node.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # -*- coding: utf-8 -*-
  2. id = 0
  3. class Node:
  4. def __init__(self, attributes: list, node_list: list, max_gen_level: list, level_nodes: dict):
  5. """
  6. :param attributes: List containing the generalization levels of the QI
  7. :param node_list: Global node list containing a reference to every node
  8. :param max_gen_level: Global list cointaining the maximum generalization levels of the QI
  9. :param level_nodes: Dictionary grouping the Nodes by height in the generalization lattice
  10. """
  11. self.ismarked = False
  12. self.ismarkedK = False
  13. self.attributes = attributes
  14. self.level = sum(attributes)
  15. self.iskanon = None
  16. self.childNodes = []
  17. self.parentNodes = []
  18. global id
  19. self.id = id
  20. self.eqclasses = 0
  21. self.DM_penalty = 0
  22. self.DMs_penalty = 0
  23. self.mem = []
  24. self.level_nodes = level_nodes
  25. attribute_count = len(self.attributes)
  26. # If this is the first node set defaults
  27. if len(node_list) == 0:
  28. id = 0
  29. self.id = id
  30. node_list.append(self)
  31. self.iskanon = False
  32. # Calculate precision of the Node
  33. self.prec = 0
  34. for a in range(attribute_count):
  35. self.prec += (self.attributes[a] / (max_gen_level[a]))
  36. self.prec /= attribute_count
  37. # Loop every QI level to create child nodes (generalizations of the QI)
  38. for x in range(attribute_count):
  39. # Check if QI can't be further generalized
  40. if not self.attributes[x] == max_gen_level[x]:
  41. # Create QI level values for new node
  42. next_attributes = self.attributes.copy()
  43. next_attributes[x] += 1
  44. next_level = self.level+1
  45. node = None
  46. # Check if height in generalzation lattice was already reached
  47. if next_level in level_nodes:
  48. # Check if new node exists already
  49. # if not:node=None; if yes:node=that node
  50. node = next((n for n in level_nodes[next_level] if n.attributes == next_attributes), None)
  51. if node is None:
  52. # Increase global ID counter
  53. id += 1
  54. # Create new Node
  55. node = Node(next_attributes, node_list, max_gen_level, level_nodes)
  56. # Put new node into the dictionary
  57. try:
  58. level_nodes[next_level].append(node)
  59. except KeyError:
  60. level_nodes.update({next_level: [node]})
  61. # Add node to the global node list
  62. node_list.append(node)
  63. # Add new node to the child nodes of this node
  64. self.childNodes.append(node)
  65. # Add this node to the parent nodes of the new node
  66. node.parentNodes.append(self)
  67. def set_children_kanon(self):
  68. # Only continue if the node wasn't already marked
  69. if self.ismarkedK is False:
  70. self.iskanon = True
  71. self.ismarkedK = True
  72. global id
  73. id -= 1
  74. if id < 0:
  75. return False
  76. for node in self.childNodes:
  77. if node.ismarkedK is True:
  78. continue
  79. if node.set_children_kanon() is False:
  80. return False
  81. return True
  82. def set_parents_notkanon(self):
  83. # Only continue if the node wasn't already marked
  84. if self.ismarked is False:
  85. self.iskanon = False
  86. self.ismarked = True
  87. global id
  88. id -= 1
  89. if id < 0:
  90. return False
  91. for node in self.parentNodes:
  92. if node.ismarked is True:
  93. continue
  94. if node.set_parents_notkanon() is False:
  95. return False
  96. return True