You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
8.3 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. #!/usr/bin/python
  2. #Import required libraries
  3. import sys
  4. import os
  5. from PIL import Image, ImageDraw, ImageShow, ImageFont
  6. import math
  7. import psutil
  8. import time
  9. from collections import defaultdict
  10. class Node:
  11. def __init__(self, rect, colour, index, node_size):
  12. self.rect = [rect[0], rect[1], rect[0] + node_size, rect[1] + node_size]
  13. self.pos = ((self.rect[0] + self.rect[2])/2, (self.rect[1] + self.rect[3])/2)
  14. self.colour = colour
  15. self.index = index
  16. def colour(index):
  17. array = ["red", "blue", "green"]
  18. return array[index % len(array)]
  19. def sort_edges(edges):
  20. return sorted(edges, key = lambda x: (x[0].index, x[1].index))
  21. def sort_tuples_and_edges(edges):
  22. sorted_tuples = []
  23. for e in edges:
  24. if e[0].index == num_nodes - 1 and e[1].index == 0:
  25. sorted_tuples.append(e)
  26. elif e[0].index > e[1].index:
  27. sorted_tuples.append((e[1], e[0]))
  28. else:
  29. sorted_tuples.append(e)
  30. return sort_edges(sorted_tuples)
  31. def to_indices(edge):
  32. return (edge[0].index, edge[1].index)
  33. def list_to_indices(edges):
  34. e = []
  35. for edge in edges:
  36. e.append(to_indices(edge))
  37. return e
  38. class Sxiv(ImageShow.UnixViewer):
  39. def get_command_ex(self, file, **options):
  40. return ("bspc rule -a \* -o state=floating focus=off && sxiv",) * 2
  41. node_size = 10
  42. m, n = 600, 600
  43. nodes = []
  44. num_nodes = 6
  45. assert(num_nodes % 3 == 0)
  46. ImageShow.register(Sxiv(), -1)
  47. font = ImageFont.truetype("Hack-Bold.ttf", node_size*3)
  48. im = Image.new('RGB', (m, n))
  49. draw = ImageDraw.Draw(im)
  50. draw.rectangle([0, 0, m, n], "white")
  51. x_step = math.floor(m / num_nodes) - 10
  52. y_step = math.floor(n / num_nodes) - 10
  53. centerX = math.floor(m/2)
  54. centerY = math.floor(n/2)
  55. step = -math.floor(360 / num_nodes)
  56. radius = math.floor(n/2.5)
  57. for i in range(0, num_nodes):
  58. angle = (i * step)
  59. coordinates = [centerX + radius*math.cos(math.radians(angle)), centerY + radius*math.sin(math.radians(angle))]
  60. nodes.append(Node(coordinates, colour(i), i, node_size))
  61. for i,node in enumerate(nodes):
  62. draw.rectangle(node.rect, fill=node.colour)
  63. draw.text(node.pos, str(node.index),font=font, fill="black")
  64. root = []
  65. for i in range(0, num_nodes - 1):
  66. root.append((nodes[i], nodes[i+1]))
  67. root_tuples = list_to_indices(root)
  68. def connect_tuple(d, e):
  69. connect(d, e[0], e[1])
  70. def connect(d, v, w):
  71. d.line([v.pos, w.pos], fill="black", width=math.floor(node_size/4))
  72. def draw_tree(edges):
  73. local = im.copy()
  74. d = ImageDraw.Draw(local)
  75. for e in edges:
  76. connect(d, e[0], e[1])
  77. local.show()
  78. def has_crossing(edge, edges):
  79. new = to_indices(edge)
  80. if(new[0] > new[1]):
  81. new = new[::-1]
  82. for e in edges:
  83. exis = to_indices(e)
  84. if(exis[0] > exis[1]):
  85. exis = exis[::-1]
  86. if(exis[0] < new[0] < exis[1] and new[1] > exis[1]):
  87. return True
  88. if(exis[0] < new[1] < exis[1] and new[0] < exis[0]):
  89. return True
  90. return False
  91. def dfs(parents, visited, adj, node):
  92. visited.add(node)
  93. for adj_node in adj[node]:
  94. if adj_node not in visited:
  95. parents[adj_node] = node
  96. dfs(parents, visited, adj, adj_node)
  97. elif parents[node] != adj_node:
  98. return True
  99. def has_cycle(new_edge, edges):
  100. adj = defaultdict(set)
  101. es = [to_indices(e) for e in edges]
  102. es.append(to_indices(new_edge))
  103. for x, y in es:
  104. adj[x].add(y)
  105. adj[y].add(x)
  106. visited = set()
  107. parents = [None] * len(adj)
  108. if dfs(parents, visited, adj, to_indices(new_edge)[0]):
  109. return True
  110. return False
  111. def construct_neighbourhood(edges, index):
  112. neighbourhood = []
  113. i = 0
  114. #print(list_to_indices(edges))
  115. for e in edges:
  116. if not is_from_root(to_indices(e)): continue
  117. start = e[0].index
  118. #print("Testing: " + str(to_indices(e)))
  119. for new_target in range(0, num_nodes):
  120. new_edge = (e[0], nodes[new_target])
  121. if(e == new_edge): continue
  122. cropped_edges = edges[:]
  123. cropped_edges.remove(e)
  124. #print(list_to_indices(cropped_edges))
  125. #print(to_indices(new_edge))
  126. #input()
  127. if(new_target % 3 == e[0].index % 3):
  128. #print("isn't bicolored")
  129. continue
  130. if(has_crossing(new_edge, cropped_edges)):
  131. #print("has_crossing")
  132. continue
  133. if(has_cycle(new_edge, cropped_edges)):
  134. #print("has_cycle")
  135. continue
  136. cropped_edges.append(new_edge)
  137. #print("Added: " + str(list_to_indices(cropped_edges)))
  138. neighbourhood.append(sort_edges(cropped_edges))
  139. if(i == index):
  140. return neighbourhood
  141. i = i + 1
  142. return neighbourhood
  143. def degree(edges):
  144. #print("degree...")
  145. l = len(construct_neighbourhood(edges, sys.maxsize))
  146. #print("done...")
  147. return l
  148. def get_jth_neighbour(edges, index):
  149. #print("Getting index: " + str(index))
  150. return construct_neighbourhood(edges, index)[index]
  151. def is_from_root(edge):
  152. return abs(edge[0] - edge[1]) == 1
  153. def get_largest_non_root_edge(edges):
  154. edges.reverse()
  155. for e in edges:
  156. if not is_from_root(e):
  157. return e
  158. return edges
  159. def get_largest_missing_convex_edge(edges):
  160. difference = [e for e in root_tuples if e not in edges]
  161. return difference[-1]
  162. def get_missing_convex_edge(edges, tup):
  163. for i in range(tup[0], tup[1]):
  164. if (i,i+1) not in list_to_indices(edges):
  165. print("missing edge: " + str((i,i+1)))
  166. return (nodes[i], nodes[i+1])
  167. def get_e_bar(edges):
  168. for e in sort_tuples_and_edges(edges):
  169. if not is_from_root(to_indices(e)):
  170. print("e_bar: " + str(to_indices(e)))
  171. return e
  172. return edges
  173. def get_parent(edges):
  174. sorted_edges = sort_edges(edges)
  175. e = get_e_bar(sorted_edges)
  176. if type(e) is list: return list_to_indices(edges)
  177. try:
  178. sorted_edges.remove(e)
  179. except:
  180. sorted_edges.remove((e[1], e[0]))
  181. #sorted_edges.append(get_largest_missing_convex_edge(sorted_edges))
  182. sorted_edges.append(get_missing_convex_edge(sorted_edges, to_indices(e)))
  183. return sorted_edges
  184. def get_parent_in_nodes(edges):
  185. parent = list_to_indices(get_parent(edges))
  186. p = []
  187. for e in parent:
  188. p.append((nodes[e[0]], nodes[e[1]]))
  189. return sort_edges(p)
  190. #
  191. #test = []
  192. #test.append((nodes[1], nodes[2]))
  193. #test.append((nodes[2], nodes[3]))
  194. #test.append((nodes[2], nodes[4]))
  195. #test.append((nodes[4], nodes[0]))
  196. #test.append((nodes[0], nodes[5]))
  197. #test.append((nodes[5], nodes[6]))
  198. #test.append((nodes[0], nodes[7]))
  199. #test.append((nodes[8], nodes[8]))
  200. #draw_tree(test)
  201. #draw_tree(get_parent_in_nodes(test))
  202. v = root
  203. j = 0
  204. count = 1
  205. while True:
  206. deg = degree(v)
  207. #print(" degree = " + str(deg))
  208. while(j != deg):
  209. j = j + 1
  210. w = sort_tuples_and_edges(get_jth_neighbour(v, j - 1))
  211. print("\t prob(v): " + str(list_to_indices(v)))
  212. print("\t probing: " + str(list_to_indices(w)))
  213. print("\t pred(w): " + str(list_to_indices(sort_tuples_and_edges(get_parent_in_nodes(w)))))
  214. if(sort_tuples_and_edges(get_parent_in_nodes(w)) == sort_tuples_and_edges(v)):
  215. print("!!! Added: " + str(list_to_indices(w)))
  216. v = w
  217. j = 0
  218. count = count + 1
  219. #print(" Current w:" + str(list_to_indices(v)))
  220. #print(" degree = " + str(deg) + " j = " + str(j))
  221. deg = degree(v)
  222. #draw_tree(v)
  223. #input()
  224. #for proc in psutil.process_iter():
  225. # if proc.name() == "sxiv":
  226. # proc.kill()
  227. input()
  228. if(v != root):
  229. w = v
  230. v = get_parent_in_nodes(w)
  231. j = 0
  232. neighbours = construct_neighbourhood(v, sys.maxsize)
  233. n = neighbours[j]
  234. while(n != w):
  235. j = j + 1
  236. n = neighbours[j]
  237. input()
  238. if(v == root and j == degree(root)):
  239. print(list_to_indices(v))
  240. print(j)
  241. break
  242. #while True:
  243. # for tree in construct_neighbourhood(root, sys.maxsize):
  244. # im1 = im.copy()
  245. # d = ImageDraw.Draw(im1)
  246. # draw_tree(d, tree)
  247. # im1.show()
  248. #
  249. # input()
  250. # #for proc in psutil.process_iter():
  251. # # if proc.name() == "sxiv":
  252. # # proc.kill()
  253. # assert(False)