class Node: def __init__(self, sid, color): self.sid = sid self.connected = [] self.used = False self.color = color self.is_free = None # may be an other value to initialise def add_nodes(self, neighbord): not_the_same = neighbord != self.sid not_allrady_inside = neighbord not in self.connected if neighbord != self.sid and neighbord not in self.connected: self.connected.append(neighbord) # print the content of the objet to debug with print() def __repr__(self): is_free = " \t###" if self.is_free else " \t___" return is_free + str(self.connected) + "\n" #class Graph: # nodes = {} # dict of all nodes # # def __init__(selt): # pass def list_to_nodes(pl): all_nodes = {} # it will contain all nodes sid_prev = None for p in pl: sid = str([int(p[0]), int(p[1])]) is_colored = p[2] != 0 if is_colored: if sid not in all_nodes: all_nodes[sid] = Node(sid, p[2]) if sid_prev != None: all_nodes[sid].add_nodes(sid_prev) all_nodes[sid_prev].add_nodes(sid) sid_prev = sid if is_colored else None return all_nodes # recursiv function witch get all connected node for one component and tag them as used def get_one_comp(id_elem, nodes): comp = [] comp.append(id_elem) nodes[id_elem].used = True for id_near in nodes[id_elem].connected: if nodes[id_near].used == False: comp += get_one_comp(id_near, nodes) return comp def get_comps(nodes): comps = [] #all component iter_nodes = iter(nodes) nb_elem = len(nodes) for id_nodes in iter_nodes: if nodes[id_nodes].used == False: comps.append(get_one_comp(id_nodes, nodes)) return comps # if ther is a class for the component it would be a good idea to set en atribute about eulerian graph or non eulerian graph def set_free_vertices(components, nodes): for comp in components: all_even_neighbord = True for id_node in comp: if len(nodes[id_node].connected) % 2 == 0: # test if even neighbord nodes[id_node].is_free = False else: nodes[id_node].is_free = True all_even_neighbord = False if all_even_neighbord: for id_node in comp: nodes[id_node].is_free = True def optimizer(pl): all_nodes = {} # it will contain all nodes components = [] # list of connected node as a graph # construct dict of connected all_nodes all_nodes = list_to_nodes(pl) components = get_comps(all_nodes) set_free_vertices(components, all_nodes) print("\n\nall_nodes:\n", all_nodes) print("\n\nconnected_components:\n", components) return pl if __name__ == '__main__': pl = [(355, 262, 0), (355, 262, 16777215), (300, 130, 16777215), (432, 75, 16777215), (487, 207, 16777215), (355, 262, 16777215), (355, 262, 0), (0, 435, 0), (0, 480, 16777215), (0, 300, 16777215), (135, 300, 16777215), (135, 570, 16777215), (135, 570, 16777215), (135, 300, 16777215), (135, 300, 0), (135, 300, 16777215), (225, 480, 16777215), (225, 480, 0), (510, 450, 0), (510, 450, 16777215), (600, 420, 16777215), (600, 300, 16777215), (720, 300, 16777215), (720, 420, 16777215), (810, 450, 16777215), (810, 450, 0)] optimizer(pl)