forked from protonphoton/LJ
94 lines
3.0 KiB
Python
94 lines
3.0 KiB
Python
|
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)
|