algorithm.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # -*- coding: utf-8 -*-
  2. import math
  3. # Initializes the algorithm
  4. def calculate(nodes, ac):
  5. min_k_nodes = [nodes[-1]]
  6. topnode = [nodes[-1]]
  7. evaluate(nodes, ac, topnode, min_k_nodes)
  8. return min_k_nodes
  9. def sort(nodes):
  10. sorted_array = []
  11. part_array = {}
  12. for n in reversed(nodes):
  13. h = n.level
  14. try:
  15. part_array[h].append(n)
  16. except KeyError:
  17. part_array.update({h: [n]})
  18. for n in sorted(part_array):
  19. sorted_array.extend(part_array[n])
  20. return sorted_array
  21. def evaluate(nodes, ac, topnode, min_k_nodes):
  22. for n in nodes:
  23. if n.level == math.floor((nodes[-1].level + nodes[0].level) / 2):
  24. if check_kanon(n, ac):
  25. test = createsubarray(n, topnode[-1], True, True)
  26. isOk = True
  27. for mkn in reversed(min_k_nodes):
  28. if mkn in test:
  29. min_k_nodes.remove(mkn)
  30. continue
  31. mkn_subarray = createsubarray(mkn, topnode[-1], True, True)
  32. if n in mkn_subarray:
  33. isOk = False
  34. if isOk:
  35. min_k_nodes.append(n)
  36. if n.iskanon:
  37. # Returns False if every node was checked and thus stops the algorithm
  38. if n.set_children_kanon() is False:
  39. return False
  40. if (nodes[-1].level - nodes[0].level) + 1 < 4:
  41. for node in nodes:
  42. if node.iskanon is None:
  43. if evaluate([node], ac, topnode, min_k_nodes) is False:
  44. return False
  45. continue
  46. newnodes = createsubarray(nodes[0], n, False)
  47. if newnodes is None:
  48. continue
  49. sorted = sort(newnodes)
  50. if evaluate(sorted, ac, topnode, min_k_nodes) is False:
  51. return False
  52. else:
  53. # Returns False if every node was checked and thus stops the algorithm
  54. if n.set_parents_notkanon() is False:
  55. return False
  56. if (nodes[-1].level - nodes[0].level) + 1 < 4:
  57. for node in nodes:
  58. if node.iskanon is None:
  59. if evaluate([node], ac, topnode, min_k_nodes) is False:
  60. return False
  61. continue
  62. newnodes = createsubarray(n, nodes[-1], True)
  63. if newnodes is None:
  64. continue
  65. sorted = sort(newnodes)
  66. if evaluate(sorted, ac, topnode, min_k_nodes) is False:
  67. return False
  68. return True
  69. def check_kanon(node, ac):
  70. if node.iskanon is not None:
  71. return False
  72. else:
  73. # Calculation if Node is k-anon
  74. if ac.calculate_kanon(node):
  75. node.iskanon = True
  76. return True
  77. else:
  78. node.iskanon = False
  79. return False
  80. def createsubarray(bot, top, direction, only_create_subarray=False):
  81. """Creates a subpart of the generalization lattice
  82. :param bot: bot/start node from where the subpart starts
  83. :param top: top/end node where the subpart stops
  84. :param direction: Calculate from bot to top (True) or top to bot (False)
  85. :param only_create_subarray: Specifies if the function is used as utility or for the algorithm
  86. :return: list of nodes that are in the subpart of the generalization lattice
  87. """
  88. # Checks how to use this function
  89. if not only_create_subarray:
  90. # Check if subarry was already created before
  91. if top.id in bot.mem:
  92. return None
  93. # Mark that this subarray was already created
  94. bot.mem.append(top.id)
  95. # Initialize array with bot and top node
  96. subarray = [bot, top]
  97. # Create rest of the subarray
  98. iterate(subarray, bot, top, direction)
  99. return subarray
  100. def iterate(list, bot, top, direction):
  101. if direction is True:
  102. attr_range = range(len(bot.attributes))
  103. for n in bot.childNodes:
  104. is_valid = True
  105. if n not in list:
  106. if n.level == top.level:
  107. return True
  108. for num in attr_range:
  109. if n.attributes[num] > top.attributes[num]:
  110. is_valid = False
  111. break
  112. if is_valid:
  113. list.append(n)
  114. iterate(list, n, top, direction)
  115. return True
  116. else:
  117. attr_range = range(len(top.attributes))
  118. for n in top.parentNodes:
  119. is_valid = True
  120. if n not in list:
  121. if n.level == bot.level:
  122. return True
  123. for num in attr_range:
  124. if n.attributes[num] < bot.attributes[num]:
  125. is_valid = False
  126. break
  127. if is_valid:
  128. list.append(n)
  129. iterate(list, bot, n, direction)
  130. return True