|
@@ -1,7 +1,77 @@
|
|
|
-from typing import List, Tuple
|
|
|
+import random
|
|
|
+from queue import Queue
|
|
|
+from typing import Dict, List, Optional, Tuple
|
|
|
|
|
|
from loguru import logger
|
|
|
+from pydantic import BaseModel
|
|
|
|
|
|
|
|
|
-async def get_graph_coloring(vertexes: List[str], edges: List[List[str]]) -> Tuple[List[str], List[str], List[str]]:
|
|
|
- pass
|
|
|
+class Vertex(BaseModel):
|
|
|
+ id: str
|
|
|
+ color: Optional[int]
|
|
|
+ edges: Optional[set]
|
|
|
+
|
|
|
+
|
|
|
+class ColoringProblemBFSSolution:
|
|
|
+
|
|
|
+ def __init__(self, vertexes: List[Vertex]):
|
|
|
+ self._vertexes = vertexes
|
|
|
+ self._is_solvable = False
|
|
|
+
|
|
|
+ def bfs(self, m=2):
|
|
|
+ n = len(self._vertexes)
|
|
|
+ visited = [False for _ in range(n + 1)]
|
|
|
+ max_color_count = 1
|
|
|
+
|
|
|
+ for i in range(1, n + 1):
|
|
|
+ if not visited[i]:
|
|
|
+ visited[i] = True
|
|
|
+ q = Queue()
|
|
|
+ q.put(i)
|
|
|
+
|
|
|
+ while not q.empty():
|
|
|
+ top = q.get()
|
|
|
+
|
|
|
+ for j in self._vertexes[top].edges:
|
|
|
+ if self._vertexes[top].color == self._vertexes[j].color:
|
|
|
+ self._vertexes[j].color += 1
|
|
|
+
|
|
|
+ max_color_count = max(max_color_count, max(self._vertexes[top].color, self._vertexes[j].color))
|
|
|
+ if max_color_count > m:
|
|
|
+ return False
|
|
|
+
|
|
|
+ if not visited[j]:
|
|
|
+ visited[j] = True
|
|
|
+ q.put(j)
|
|
|
+
|
|
|
+ self._is_solvable = True
|
|
|
+
|
|
|
+ return True
|
|
|
+
|
|
|
+ def get_colored(self) -> Dict[str, int]:
|
|
|
+ colored = dict()
|
|
|
+ if self._is_solvable:
|
|
|
+ for v in self._vertexes:
|
|
|
+ colored.update({v.id: v.color})
|
|
|
+ else:
|
|
|
+ for v in self._vertexes:
|
|
|
+ colored.update({v.id: random.choice([0, 1])})
|
|
|
+
|
|
|
+ return colored
|
|
|
+
|
|
|
+
|
|
|
+def reformat(graph: Dict[str, List]) -> List[Vertex]:
|
|
|
+ vertexes = []
|
|
|
+ for v, edges in graph.items():
|
|
|
+ vertexes.append(Vertex(id=v, color=0, edges=set(edges)))
|
|
|
+
|
|
|
+ return vertexes
|
|
|
+
|
|
|
+
|
|
|
+@logger.catch()
|
|
|
+async def get_graph_coloring(graph: Dict[str, List]) -> Tuple[bool, Dict[str, int]]:
|
|
|
+ vertexes = reformat(graph)
|
|
|
+ solution = ColoringProblemBFSSolution(vertexes)
|
|
|
+ is_solvable = solution.bfs()
|
|
|
+
|
|
|
+ return is_solvable, solution.get_colored()
|