not working yet

This commit is contained in:
Andreas Fruhwirt 2024-01-10 19:48:30 +01:00
commit 34b7a83d1a
3 changed files with 173 additions and 0 deletions

17
Readme.md Normal file
View File

@ -0,0 +1,17 @@
The goal of this exercise is to provide a centralized implementation that simulates
a randomized distributed algorithm. Your implementation should take a graph
$G = (V, E)$ with maximum degree $\Delta$ as its input and simulate the following distributed
randomized $(\Delta + 1)$-coloring algorithm until all vertices are colored:
*Initially, all nodes are uncolored. Then, in synchronous iterations, each uncolored
node selects a random candidate color from its list of available colors, that is, from
the set of colors that none of its already permanently colored neighbors have. Then,
nodes exchange their candidate colors with their neighbors. A node v that has a
candidate color c that is not selected as a candidate color by any of its neighbors
gets permanently colored with c, otherwise v discards its candidate color, remains
uncolored, and proceeds with the next iteration.*
The code may be written in any programming language. Submit your code via
GIT (link the repository in your submission) including instructions on how to run it.
Additionally provide several example inputs (on at least a few hundred nodes) and a
test case that your algorithm computes a proper vertex coloring.

150
main.py Normal file
View File

@ -0,0 +1,150 @@
#!/usr/bin/python3
from random import randint, random
import networkx as nx
import sys
class Node(object):
def __init__(self, id, g):
self.graph = g
self.id = id
self.color = None
self.candidate_list = None
self.queue = "start"
self.next_tick = None
self.edges = []
self.done = False
def add_edge(self, node):
self.edges.append(node)
def print(self):
print(f"Node {self.id} = (c:{self.color}, #e:{len(self.edges)})")
def run_tick(self):
if not self.done:
# candidate list of colors
self.candidate_list = self.graph.possible_colors.copy()
if not self.next_tick == "start":
# if its not the first iteration w/o data, filter out all neighbor colors from candidate list
neighbor_candidates = self.next_tick.copy()
for colore in neighbor_candidates:
if colore in self.candidate_list:
self.candidate_list.remove(colore)
# if color is in candidate list (no neighbors has this color), finish.
# do not run this at start
if self.color in self.candidate_list and self.color is not None:
self.done = True
self.queue = "stop"
#print(f"{self.id} | is done")
return
# pick random color from candidate list
self.color = self.candidate_list[randint(0, len(self.candidate_list) - 1)]
#print(f"{self.id} | possible colors: {self.candidate_list}, current color: {self.color}")
# send data to the other neighbors
for n in self.edges:
if n.queue != "stop":
n.queue.append(self.color)
#print(f"{self.id} => sending {self.color} to N[{n.id}]")
class Graph(object):
def __init__(self):
self.V = None
self.max_degree = None
def load_graph_file(self, graph_file):
with open(graph_file, "r") as f:
V_amt, E_amt = map(int, f.readline().split(" "))
self.V = [Node(x, self) for x in range(1, V_amt+1)]
self.E = {}
self.max_degree = 0
for i in range(0, E_amt):
a, b = map(int, f.readline().split(" "))
a -= 1
b -= 1
self.V[a].add_edge(self.V[b])
self.V[b].add_edge(self.V[a])
self.max_degree = max(self.max_degree, len(self.V[a].edges), len(self.V[b].edges))
self.possible_colors = [x for x in range(1, self.max_degree + 2)]
def load_graph_networkx(self, graph):
self.V = [Node(x, self) for x in range(1, graph.number_of_nodes() + 1)]
self.E = {}
self.max_degree = 0
for a, b in graph.edges:
self.V[a].add_edge(self.V[b])
self.V[b].add_edge(self.V[a])
self.max_degree = max(self.max_degree, len(self.V[a].edges), len(self.V[b].edges))
self.possible_colors = [x for x in range(1, self.max_degree + 2)]
def run_tick(self):
print("Next Tick")
# send data
for n in self.V:
n.next_tick = n.queue
n.queue = []
# run tick for each
for n in self.V:
n.run_tick()
done = True
for n in self.V:
done &= n.done
if done:
print("Stop")
return -1
pass
def print_graph(self):
print(f"Max Degree: {self.max_degree}")
for n in self.V:
n.print()
def check_correctness(self):
for n in self.V:
color = n.color
for neighbor in n.edges:
if neighbor.color == color:
print("=====================")
n.print()
neighbor.print()
print(f"Neighbor {neighbor.id} has same color as {n.id}")
print("=====================")
return False
return True
def main():
g = Graph()
if len(sys.argv) == 2:
filename = sys.argv[1]
g.load_graph(filename)
else:
G = nx.erdos_renyi_graph(randint(100, 300), random())
g.load_graph_networkx(G)
g.print_graph()
for i in range(0, 10):
ret = g.run_tick()
if ret == -1:
# print info
print("Final colors:")
for n in g.V:
n.print()
# assert if correct
assert g.check_correctness()
exit(0)
pass
if __name__ == '__main__':
main()

6
test_graph.txt Normal file
View File

@ -0,0 +1,6 @@
6 5
1 4
4 3
3 2
2 5
5 6