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.

403 lines
12 KiB

6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
  1. #!/usr/bin/env python3
  2. from util import SAT2QUBO as s2q
  3. from util import randomSAT as rs
  4. import networkx as nx
  5. import dwave_networkx as dnx
  6. import minorminer
  7. from dwave_qbsolv import QBSolv
  8. import matplotlib.pyplot as plt
  9. import seaborn as sns
  10. import numpy as np
  11. import re
  12. def frange(start, stop, steps):
  13. while start < stop:
  14. yield start
  15. start += steps
  16. def test_kv_range():
  17. k = 75
  18. data = {
  19. "p_node_counts" : [],
  20. "wmis_node_counts" : [],
  21. "p_conn_counts" : [],
  22. "wmis_conn_counts" : [],
  23. "a_arr" : [],
  24. "k_arr" : []
  25. }
  26. target = dnx.chimera_graph(25, 25, 4)
  27. print(target.number_of_nodes())
  28. for r in range(2):
  29. #for k in range(50, 5001, 50):
  30. for a in frange(3.5, 5.5, 0.1):
  31. #v = int(k/4)
  32. #a = k/v
  33. v = int(k/a)
  34. print("k={} v={} k/v={}".format(k, v, k/v))
  35. ksatInstance = rs.generateRandomKSAT(k, v, 3)
  36. p_qubo = s2q.primitiveQUBO(ksatInstance)
  37. wmis_qubo = s2q.WMISdictQUBO(ksatInstance)
  38. qg = nx.Graph()
  39. for coupler, energy in wmis_qubo.items():
  40. if coupler[0] != coupler[1]:
  41. qg.add_edge(coupler[0], coupler[1], weight=energy)
  42. ig = nx.Graph()
  43. for coupler, energy in p_qubo.items():
  44. if coupler[0] != coupler[1]:
  45. ig.add_edge(coupler[0], coupler[1], weight=energy)
  46. qemb = minorminer.find_embedding(qg.edges(), target.edges(), return_overlap=True, threads=8)
  47. print("wmis emb. found: {}".format(qemb[1]))
  48. iemb = minorminer.find_embedding(ig.edges(), target.edges(), return_overlap=True, threads=8)
  49. print("primitive emb. found: {}".format(iemb[1]))
  50. if qemb[1] == 0 or iemb[1] == 0:
  51. print()
  52. continue
  53. p_node_count = 0;
  54. p_conn_count = 0;
  55. used_nodes = []
  56. for var, chain in iemb[0].items():
  57. used_nodes.extend(chain)
  58. p_node_count = len(np.unique(used_nodes))
  59. wmis_node_count = 0;
  60. wmis_conn_count = 0;
  61. used_nodes = []
  62. for var, chain in qemb[0].items():
  63. used_nodes.extend(chain)
  64. wmis_node_count = len(np.unique(used_nodes))
  65. #print("p_qubo: nodes={} connections={}".format(p_node_count, p_conn_count))
  66. #print("wmis_qubo: nodes={} connections={}".format(wmis_node_count, wmis_conn_count))
  67. print("p_qubo nodes= {}".format(p_node_count));
  68. print("wwmis qubo nodes= {}".format(wmis_node_count));
  69. print("nodes= {}".format(p_node_count / wmis_node_count));
  70. #print("conns= {}".format(p_conn_count / wmis_conn_count));
  71. data["p_node_counts"].append(p_node_count)
  72. data["wmis_node_counts"].append(wmis_node_count)
  73. data["p_conn_counts"].append(p_conn_count)
  74. data["wmis_conn_counts"].append(wmis_conn_count)
  75. data["a_arr"].append(k/v)
  76. data["k_arr"].append(k)
  77. print()
  78. sns.set()
  79. ax = sns.scatterplot(x="a_arr", y="p_node_counts", data=data, label="p_qubo")
  80. ax.set(xlabel='k/v', ylabel='used verticies after embedding')
  81. ax = sns.scatterplot(x="a_arr", y="wmis_node_counts", data=data, ax=ax, label="wmis_qubo")
  82. plt.show()
  83. def test_k_range():
  84. k = 75
  85. data = {
  86. "p_node_counts" : [],
  87. "wmis_node_counts" : [],
  88. "p_conn_counts" : [],
  89. "wmis_conn_counts" : [],
  90. "a_arr" : [],
  91. "k_arr" : []
  92. }
  93. target = dnx.chimera_graph(25, 25, 4)
  94. print(target.number_of_nodes())
  95. for r in range(2):
  96. for k in range(15, 76, 1):
  97. v = int(k/4)
  98. print("k={} v={} k/v={}".format(k, v, k/v))
  99. ksatInstance = rs.generateRandomKSAT(k, v, 3)
  100. p_qubo = s2q.primitiveQUBO(ksatInstance)
  101. wmis_qubo = s2q.WMISdictQUBO(ksatInstance)
  102. qg = nx.Graph()
  103. for coupler, energy in wmis_qubo.items():
  104. if coupler[0] != coupler[1]:
  105. qg.add_edge(coupler[0], coupler[1], weight=energy)
  106. ig = nx.Graph()
  107. for coupler, energy in p_qubo.items():
  108. if coupler[0] != coupler[1]:
  109. ig.add_edge(coupler[0], coupler[1], weight=energy)
  110. qemb = minorminer.find_embedding(qg.edges(), target.edges(), return_overlap=True, threads=8)
  111. print("wmis emb. found: {}".format(qemb[1]))
  112. iemb = minorminer.find_embedding(ig.edges(), target.edges(), return_overlap=True, threads=8)
  113. print("primitive emb. found: {}".format(iemb[1]))
  114. if qemb[1] == 0 or iemb[1] == 0:
  115. print()
  116. continue
  117. p_node_count = 0;
  118. p_conn_count = 0;
  119. used_nodes = []
  120. for var, chain in iemb[0].items():
  121. used_nodes.extend(chain)
  122. p_node_count = len(np.unique(used_nodes))
  123. wmis_node_count = 0;
  124. wmis_conn_count = 0;
  125. used_nodes = []
  126. for var, chain in qemb[0].items():
  127. used_nodes.extend(chain)
  128. wmis_node_count = len(np.unique(used_nodes))
  129. #print("p_qubo: nodes={} connections={}".format(p_node_count, p_conn_count))
  130. #print("wmis_qubo: nodes={} connections={}".format(wmis_node_count, wmis_conn_count))
  131. print("p_qubo nodes= {}".format(p_node_count));
  132. print("wwmis qubo nodes= {}".format(wmis_node_count));
  133. print("nodes= {}".format(p_node_count / wmis_node_count));
  134. #print("conns= {}".format(p_conn_count / wmis_conn_count));
  135. data["p_node_counts"].append(p_node_count)
  136. data["wmis_node_counts"].append(wmis_node_count)
  137. data["p_conn_counts"].append(p_conn_count)
  138. data["wmis_conn_counts"].append(wmis_conn_count)
  139. data["a_arr"].append(k/v)
  140. data["k_arr"].append(k)
  141. print()
  142. sns.set()
  143. ax = sns.scatterplot(x="k_arr", y="p_node_counts", data=data, label="p_qubo")
  144. ax.set(xlabel='k',
  145. ylabel='used verticies after embedding')
  146. ax = sns.scatterplot(x="k_arr", y="wmis_node_counts", data=data, ax=ax, label="wmis_qubo")
  147. plt.show()
  148. def medianChainLength(emb):
  149. chl = []
  150. for chain in emb.values():
  151. chl.append(len(chain))
  152. return np.median(chl)
  153. def test2():
  154. sat = rs.generateRandomKSAT(15, 4, 3)
  155. print(sat.toString())
  156. qubo = s2q.WMISdictQUBO(sat)
  157. ising = s2q.primitiveQUBO(sat)
  158. qg = nx.Graph()
  159. for coupler, energy in qubo.items():
  160. if coupler[0] != coupler[1]:
  161. qg.add_edge(coupler[0], coupler[1], weight=energy)
  162. ig = nx.Graph()
  163. for coupler, energy in ising.items():
  164. if coupler[0] != coupler[1]:
  165. ig.add_edge(coupler[0], coupler[1], weight=energy)
  166. #plt.ion()
  167. print(qg.number_of_nodes(), qg.number_of_edges())
  168. print(ig.number_of_nodes(), ig.number_of_edges())
  169. target = dnx.chimera_graph(9, 9, 4)
  170. #nx.draw_shell(qg, with_labels=True, node_size=50)
  171. #nx.draw_shell(ig, with_labels=True, node_size=50)
  172. eg = ig
  173. emb = minorminer.find_embedding(eg.edges(), target.edges(), return_overlap=True,
  174. threads=8)
  175. print("median chain length = {}".format(medianChainLength(emb[0])))
  176. print(emb[1])
  177. dnx.draw_chimera_embedding(G=target, emb=emb[0], embedded_graph=eg, show_labels=True)
  178. plt.show()
  179. def test3():
  180. sat = rs.generateRandomKSAT(15, 4, 3)
  181. print(sat.toString())
  182. ising = s2q.primitiveQUBO(sat)
  183. h = {}
  184. J = {}
  185. for coupler, energy in ising.items():
  186. if coupler[0] == coupler[1]:
  187. h[coupler[0]] = energy
  188. else:
  189. J[coupler] = energy
  190. res = QBSolv().sample_ising(h, J, find_max=False)
  191. sample = list(res.samples())[0]
  192. extracted = {}
  193. r = re.compile("c\d+_l-?\d*")
  194. for label, assignment in sample.items():
  195. if r.fullmatch(label):
  196. extracted[tuple(re.split(r"\_l", label[1:]))] = assignment
  197. model = [True for i in range(len(extracted))]
  198. assignments = {}
  199. for label, assignment in extracted.items():
  200. clause = int(label[0])
  201. lit = int(label[1])
  202. var = abs(lit)
  203. if lit < 0:
  204. assignment *= -1
  205. if var in assignments:
  206. assignments[var].append(assignment)
  207. else:
  208. assignments[var] = [assignment]
  209. conflicts = False
  210. for var, a in assignments.items():
  211. if abs(np.sum(a)) != len(a):
  212. conflicts = True
  213. print("conflicts - no solution found")
  214. print(var, np.sort(a))
  215. if conflicts:
  216. return
  217. model = [True for i in range(sat.getNumberOfVariables())]
  218. for var, assignment in assignments.items():
  219. model[var - 1] = True if assignment[0] > 0 else False
  220. print(model, sat.checkAssignment(model))
  221. def test4():
  222. sat = rs.generateRandomKSAT(50, 13, 3)
  223. print(sat.toString())
  224. qubo = s2q.WMISdictQUBO(sat)
  225. ising = s2q.primitiveQUBO(sat)
  226. qg = nx.Graph()
  227. for coupler, energy in qubo.items():
  228. if coupler[0] != coupler[1]:
  229. qg.add_edge(coupler[0], coupler[1], weight=energy)
  230. ig = nx.Graph()
  231. for coupler, energy in ising.items():
  232. if coupler[0] != coupler[1]:
  233. ig.add_edge(coupler[0], coupler[1], weight=energy)
  234. #plt.ion()
  235. print(qg.number_of_nodes(), qg.number_of_edges())
  236. print(ig.number_of_nodes(), ig.number_of_edges())
  237. target = dnx.chimera_graph(12, 12, 4)
  238. #nx.draw_shell(qg, with_labels=True, node_size=50)
  239. #nx.draw_shell(ig, with_labels=True, node_size=50)
  240. print()
  241. print("wmis:")
  242. qemb = minorminer.find_embedding(qg.edges(), target.edges(), return_overlap=True)
  243. print(qemb[1])
  244. print("median chain length = {}".format(medianChainLength(qemb[0])))
  245. used_nodes = []
  246. for var, chain in qemb[0].items():
  247. used_nodes.extend(chain)
  248. used_nodes = np.unique(used_nodes)
  249. print("used nodes (embedding) = {}".format(len(used_nodes)))
  250. print()
  251. print("primitves:")
  252. iemb = minorminer.find_embedding(ig.edges(), target.edges(), return_overlap=True)
  253. print(iemb[1])
  254. print("median chain length = {}".format(medianChainLength(iemb[0])))
  255. used_nodes = []
  256. for var, chain in iemb[0].items():
  257. used_nodes.extend(chain)
  258. used_nodes = np.unique(used_nodes)
  259. print("used nodes (embedding) = {}".format(len(used_nodes)))
  260. test_k_range()