123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- # -*- coding: utf-8 -*-
- import math
- # Initializes the algorithm
- def calculate(nodes, ac):
- min_k_nodes = [nodes[-1]]
- topnode = [nodes[-1]]
- evaluate(nodes, ac, topnode, min_k_nodes)
- return min_k_nodes
- def sort(nodes):
- sorted_array = []
- part_array = {}
- for n in reversed(nodes):
- h = n.level
- try:
- part_array[h].append(n)
- except KeyError:
- part_array.update({h: [n]})
- for n in sorted(part_array):
- sorted_array.extend(part_array[n])
- return sorted_array
- def evaluate(nodes, ac, topnode, min_k_nodes):
- for n in nodes:
- if n.level == math.floor((nodes[-1].level + nodes[0].level) / 2):
- if check_kanon(n, ac):
- test = createsubarray(n, topnode[-1], True, True)
- isOk = True
- for mkn in reversed(min_k_nodes):
- if mkn in test:
- min_k_nodes.remove(mkn)
- continue
- mkn_subarray = createsubarray(mkn, topnode[-1], True, True)
- if n in mkn_subarray:
- isOk = False
- if isOk:
- min_k_nodes.append(n)
- if n.iskanon:
- # Returns False if every node was checked and thus stops the algorithm
- if n.set_children_kanon() is False:
- return False
- if (nodes[-1].level - nodes[0].level) + 1 < 4:
- for node in nodes:
- if node.iskanon is None:
- if evaluate([node], ac, topnode, min_k_nodes) is False:
- return False
- continue
- newnodes = createsubarray(nodes[0], n, False)
- if newnodes is None:
- continue
- sorted = sort(newnodes)
- if evaluate(sorted, ac, topnode, min_k_nodes) is False:
- return False
- else:
- # Returns False if every node was checked and thus stops the algorithm
- if n.set_parents_notkanon() is False:
- return False
- if (nodes[-1].level - nodes[0].level) + 1 < 4:
- for node in nodes:
- if node.iskanon is None:
- if evaluate([node], ac, topnode, min_k_nodes) is False:
- return False
- continue
- newnodes = createsubarray(n, nodes[-1], True)
- if newnodes is None:
- continue
- sorted = sort(newnodes)
- if evaluate(sorted, ac, topnode, min_k_nodes) is False:
- return False
- return True
- def check_kanon(node, ac):
- if node.iskanon is not None:
- return False
- else:
- # Calculation if Node is k-anon
- if ac.calculate_kanon(node):
- node.iskanon = True
- return True
- else:
- node.iskanon = False
- return False
- def createsubarray(bot, top, direction, only_create_subarray=False):
- """Creates a subpart of the generalization lattice
- :param bot: bot/start node from where the subpart starts
- :param top: top/end node where the subpart stops
- :param direction: Calculate from bot to top (True) or top to bot (False)
- :param only_create_subarray: Specifies if the function is used as utility or for the algorithm
- :return: list of nodes that are in the subpart of the generalization lattice
- """
- # Checks how to use this function
- if not only_create_subarray:
- # Check if subarry was already created before
- if top.id in bot.mem:
- return None
- # Mark that this subarray was already created
- bot.mem.append(top.id)
- # Initialize array with bot and top node
- subarray = [bot, top]
- # Create rest of the subarray
- iterate(subarray, bot, top, direction)
- return subarray
- def iterate(list, bot, top, direction):
- if direction is True:
- attr_range = range(len(bot.attributes))
- for n in bot.childNodes:
- is_valid = True
- if n not in list:
- if n.level == top.level:
- return True
- for num in attr_range:
- if n.attributes[num] > top.attributes[num]:
- is_valid = False
- break
- if is_valid:
- list.append(n)
- iterate(list, n, top, direction)
- return True
- else:
- attr_range = range(len(top.attributes))
- for n in top.parentNodes:
- is_valid = True
- if n not in list:
- if n.level == bot.level:
- return True
- for num in attr_range:
- if n.attributes[num] < bot.attributes[num]:
- is_valid = False
- break
- if is_valid:
- list.append(n)
- iterate(list, bot, n, direction)
- return True
|