Advertisement
Guest User

Untitled

a guest
Dec 10th, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.59 KB | None | 0 0
  1. from random import shuffle, randrange, choice
  2. from collections import deque
  3. import turtle
  4.  
  5. class Graph:
  6.    
  7.     def __init__(self, C: int, R: int):
  8.         # right mówi gdzie są krawędzie w prawo, a up gdzie są krawędzie w górę
  9.         # C-1, bo ostatnia kolumna nie może mieć krawędzie w prawo, R-1, bo ostatni (na samej górze) wiersz nie może miec krawędzi w górę
  10.         self._right = [[False] * R for _ in range(C-1)]  #najpierw która kolumna, a później który wiersz, np. [1][2] - 1 kolumna, 2 wiersz
  11.         self._up = [[False] * (R-1) for _ in range(C)]
  12.        
  13.     def cols(self):
  14.         return len(self._up)
  15.    
  16.     def rows(self):
  17.         return len(self._right[0])
  18.        
  19.     def has_right(self, c: int, r: int):
  20.         return self._right[c][r]
  21.    
  22.     def set_right(self, c: int, r: int, v = True):
  23.         self._right[c][r] = v
  24.    
  25.     def has_left(self, c: int, r: int):
  26.         return self.has_right(c-1, r)
  27.    
  28.     def has_up(self, c: int, r: int):
  29.         return self._up[c][r]
  30.    
  31.     def set_up(self, c: int, r: int, v = True):
  32.         self._up[c][r] = True
  33.    
  34.     def has_down(self, c: int, r: int):
  35.         return self.has_up(c, r-1)
  36.  
  37.     @staticmethod
  38.     def _min_max(n1, n2):
  39.         return min(n1, n2), max(n1, n2)
  40.    
  41.     def has_edge(self, v1, v2) -> bool:
  42.         if v1[0] == v2[0]: # sprawdzamy czy są w tej samej kolumnie
  43.             l, u = Graph._min_max(v1[1], v2[1])
  44.             if l != u-1 or l < 0 or u >= self.rows():
  45.                 return False
  46.             return self._up[v1[0]][l]
  47.         elif v1[1] == v2[1]: # sprawdzamy czy są w tym samym wierszu
  48.             l, u = Graph._min_max(v1[0], v2[0])
  49.             if l != u-1 or l < 0 or u >= self.cols():
  50.                 return False
  51.             return self._right[l][v1[1]]
  52.         else:
  53.             return False
  54.        
  55.     def set_edge(self, v1, v2, v = True):
  56.         if v1[0] == v2[0]:
  57.             l, u = Graph._min_max(v1[1], v2[1])
  58.             if l != u-1 or l < 0 or u >= self.rows():
  59.                 raise ValueError()
  60.             self._up[v1[0]][l] = v
  61.         elif v1[1] == v2[1]:
  62.             l, u = Graph._min_max(v1[0], v2[0])
  63.             if l != u-1 or l < 0 or u >= self.cols():
  64.                 raise ValueError()
  65.             self._right[l][v1[1]] = v
  66.         else:
  67.             raise ValueError()
  68.    
  69.     def neighbours(self, vertex, visited = None):
  70.         result = []
  71.         c, r = vertex
  72.         if 0 < c: result.append((c-1, r))
  73.         if c+1 < self.cols(): result.append((c+1, r))
  74.         if 0 < r: result.append((c, r-1))
  75.         if r+1 < self.rows(): result.append((c, r+1))
  76.         if visited is not None:
  77.             result = [n for n in result if n not in visited]
  78.         return result
  79.        
  80.  
  81. def draw_line(v1, v2):
  82.     turtle.penup()
  83.     turtle.goto(v1[0]*50-500, v1[1]*50-300)
  84.     turtle.pendown()
  85.     turtle.goto(v2[0]*50-500, v2[1]*50-300)
  86.    
  87. def draw_graph(g: Graph):
  88.     turtle.speed(5000)
  89.     turtle.begin_poly()
  90.     draw_line((0, 0), (g.cols(), 0))
  91.     draw_line((0, g.rows()), (g.cols(), g.rows()))
  92.     draw_line((0, 1), (0, g.rows()))
  93.     draw_line((g.cols(), 0), (g.cols(), g.rows()-1))
  94.     for r in range(g.rows()-1):
  95.         for c in range(g.cols()):
  96.             if not g.has_up(c, r):
  97.                 draw_line((c, r+1), (c+1, r+1))
  98.     for c in range(g.cols()-1):
  99.         for r in range(g.rows()):
  100.             if not g.has_right(c, r):
  101.                 draw_line((c+1, r), (c+1, r+1))
  102.     turtle.end_poly()
  103.  
  104. def DFS(g: Graph, vertex, visited: set):
  105.     visited.add(vertex)
  106.     ns = g.neighbours(vertex)
  107.     shuffle(ns)
  108.     for n in ns:
  109.         if n not in visited:
  110.             g.set_edge(vertex, n)
  111.             DFS(g, n, visited)
  112.            
  113. def BFS(g: Graph, vertex):
  114.     q = deque()
  115.     visited = set()
  116.     q.append(vertex)
  117.     visited.add(vertex)
  118.     while q:
  119.         v = q.popleft()
  120.         ns = g.neighbours(v, visited)
  121.         shuffle(ns)
  122.         for n in ns:
  123.             g.set_edge(v, n)
  124.             visited.add(n)
  125.             q.append(n)
  126.  
  127. def randS(g: Graph, vertex):
  128.     q = []
  129.     visited = set()
  130.     q.append(vertex)
  131.     visited.add(vertex)
  132.     while q:
  133.         q_index = randrange(len(q))
  134.         v = q[q_index]
  135.         ns = g.neighbours(v, visited)
  136.         shuffle(ns)
  137.         if len(ns) <= 1:
  138.             q[q_index] = q[-1]
  139.             q.pop()
  140.         if ns:
  141.             n = choice(ns)
  142.             g.set_edge(v, n)
  143.             visited.add(n)
  144.             q.append(n)
  145.  
  146. g = Graph(20, 15)
  147. DFS(g, (0,0), set())
  148. # BFS(g, (10,7))
  149. # randS(g, (19,0))
  150. draw_graph(g)
  151. turtle.done()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement