not working yet
This commit is contained in:
commit
34b7a83d1a
17
Readme.md
Normal file
17
Readme.md
Normal 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
150
main.py
Normal 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
6
test_graph.txt
Normal file
@ -0,0 +1,6 @@
|
||||
6 5
|
||||
1 4
|
||||
4 3
|
||||
3 2
|
||||
2 5
|
||||
5 6
|
||||
Loading…
x
Reference in New Issue
Block a user