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.

459 lines
14 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. #!/usr/bin/env python3
  2. from util.kSAT import kSAT
  3. import util.randomSAT as rand_sat
  4. import util.SAT2QUBO as SAT2QUBO
  5. import util.script as script
  6. import util.queries as queries
  7. import util.graph as graph
  8. from dwave.system.composites import FixedEmbeddingComposite
  9. import dimod
  10. from neal import SimulatedAnnealingSampler
  11. import minorminer
  12. import networkx as nx
  13. import dwave_networkx as dnx
  14. import dwave.embedding
  15. from dwave.cloud import Client
  16. from dwave.cloud import Future
  17. from dwave.system.samplers import DWaveSampler
  18. from dwave_qbsolv import QBSolv
  19. import numpy as np
  20. import random
  21. import re
  22. from tqdm import tqdm
  23. def main():
  24. #__wmis()
  25. __pqubo_3()
  26. #__pqubo()
  27. #__wmis3()
  28. def __qubo_to_nx_graph(qubo):
  29. graph = nx.Graph()
  30. for coupler, energy in qubo.items():
  31. if coupler[0] != coupler[1]:
  32. graph.add_edge(coupler[0], coupler[1], weight=energy)
  33. return graph
  34. def __wmis2():
  35. db = script.connect_to_instance_pool("dbc")
  36. target_graph = dnx.chimera_graph(16, 16, 4)
  37. target_graph_id = queries.get_id_of_solver_graph(db["solver_graphs"],
  38. nx.node_link_data(target_graph))
  39. instance_id = "5c9ccb998c6fe61926458351"
  40. qubo, wmis_id = queries.load_WMIS_qubo_of_instance(db["wmis_qubos"], instance_id)
  41. emb = queries.load_embedding(db["embeddings"], wmis_id, target_graph_id)
  42. chimera_sampler = dimod.StructureComposite(SimulatedAnnealingSampler(),
  43. target_graph.nodes(),
  44. target_graph.edges())
  45. sampler = FixedEmbeddingComposite(chimera_sampler, emb)
  46. res = sampler.sample_qubo(__negate_qubo(qubo))
  47. print(res.first)
  48. def __wmis3():
  49. db = script.connect_to_instance_pool()
  50. target_graph = dnx.chimera_graph(16, 16, 4)
  51. target_graph_id = queries.get_id_of_solver_graph(db["solver_graphs"],
  52. nx.node_link_data(target_graph))
  53. solver_input_query = queries.WMIS_solver_input_scope_query(db)
  54. solver_input_query.query("c42_vLogistic_6", target_graph_id)
  55. base_sampler = SimulatedAnnealingSampler()
  56. #base_sampler = QBSolv()
  57. chimera_sampler = dimod.StructureComposite(base_sampler,
  58. target_graph.nodes(),
  59. target_graph.edges())
  60. for solver_input in tqdm(solver_input_query):
  61. sampler = FixedEmbeddingComposite(chimera_sampler, solver_input["embeddings"][0])
  62. #res = sampler.sample_qubo(solver_input["qubo"], solver_limit=2048)
  63. res = sampler.sample_qubo(solver_input["qubo"])
  64. script.save_result(db["wmis_siman_results"],
  65. res,
  66. solver_input,
  67. 0,
  68. 1)
  69. def __wmis_qpu():
  70. db = script.connect_to_instance_pool()
  71. base_solver = DWaveSampler()
  72. solver_graph = graph.create_qpu_solver_nxgraph(base_solver)
  73. solver_graph_id = queries.get_id_of_solver_graph(db["solver_graphs"],
  74. nx.node_link_data(solver_graph))
  75. solver_input_query = queries.WMIS_solver_input_scope_query(db)
  76. solver_input_query.query("c42_vLogistic_6", solver_graph_id)
  77. for solver_input in tqdm(solver_input_query):
  78. embedding = solver_input["embeddings"][0]
  79. qubo = solver_input["qubo"]
  80. solver = FixedEmbeddingComposite(base_solver, embedding)
  81. res = solver.sample_qubo(qubo, annealing_time=5)
  82. script.save_result(db["wmis_qpu_results"],
  83. res,
  84. solver_input,
  85. emb_list_index = 0,
  86. run = 1)
  87. def __wmis():
  88. sat_count = 0
  89. no_embedding_count = 0
  90. for i in range(200):
  91. sat = rand_sat.generateRandomKSAT(40, 14, 3)
  92. qubo = SAT2QUBO.WMISdictQUBO(sat)
  93. #qubo = SAT2QUBO.WMISdictQUBO(sat)
  94. nx_qubo = __qubo_to_nx_graph(qubo)
  95. target_graph = dnx.chimera_graph(16, 16, 4)
  96. emb = minorminer.find_embedding(nx_qubo.edges(),
  97. target_graph.edges(),
  98. return_overlap=True)
  99. if emb[1] != 1:
  100. print("no embedding found")
  101. no_embedding_count += 1
  102. continue
  103. #print(emb[0])
  104. chimera_sampler = dimod.StructureComposite(SimulatedAnnealingSampler(),
  105. target_graph.nodes(),
  106. target_graph.edges())
  107. sampler = FixedEmbeddingComposite(chimera_sampler, emb[0])
  108. res = sampler.sample_qubo(qubo, chain_strength=2)
  109. #res = SimulatedAnnealingSampler().sample_qubo(qubo)
  110. #dwave.embedding.chain_breaks.majority_vote(res, emb[0])
  111. first = res.first
  112. print("chain_break_fraction={}".format(first.chain_break_fraction))
  113. #for lit, spin in first.sample.items():
  114. #print(lit, spin)
  115. print("true count: {}".format(np.count_nonzero(list(first.sample.values()))))
  116. assignments = {}
  117. for coupler, energy in first.sample.items():
  118. var = abs(coupler[1])
  119. if var not in assignments:
  120. assignments[var] = {"all": []}
  121. if energy == 1:
  122. assignments[var]["all"].append(1 if coupler[1] > 0 else 0)
  123. __majority_vote(assignments)
  124. #for var, a in assignments.items():
  125. ##print(var, np.sort(a["all"]), __majority_percentage(a["all"]))
  126. #print(var, a)
  127. final = __extract_assignment(assignments)
  128. print(final)
  129. print("satisfies sat: {}".format(sat.checkAssignment(final)))
  130. if sat.checkAssignment(final):
  131. sat_count += 1
  132. print("sat ratio: {}".format(sat_count / (200 - no_embedding_count)))
  133. def __optimize_assignment(sat, assignment, consistencies):
  134. rnd = random.Random()
  135. max_steps = 4000
  136. steps = 0
  137. while not sat.checkAssignment(assignment) and steps < max_steps:
  138. steps += 1
  139. for i in range(len(assignment)):
  140. if 0.9 * rnd.random() > consistencies[i]:
  141. assignment[i] = (1 + assignment[i]) % 2
  142. consistencies[i] = 1 - consistencies[i]
  143. print("steps: {}".format(steps))
  144. return assignment
  145. def __random_assignment(number_of_variables):
  146. rnd = random.Random()
  147. assignment = [rnd.choice([0, 1]) for i in range(number_of_variables)]
  148. consistencies = [0.5 for i in range(number_of_variables)]
  149. return assignment, consistencies
  150. def __extract_assignment(assignments):
  151. assignment = [0 for i in range(len(assignments))]
  152. for var, a in assignments.items():
  153. assignment[var - 1] = a["major"]
  154. return assignment
  155. def __extract_consistencies(assignments) :
  156. consistencies = [0.0 for i in range(len(assignments))]
  157. for var, a in assignments.items():
  158. consistencies[var - 1] = a["consistency"]
  159. return consistencies
  160. def __majority_vote(assignments):
  161. for var, a in assignments.items():
  162. assignments[var]["major"] = 1 if __true_percentage(a["all"]) >= 0.5 else 0
  163. assignments[var]["consistency"] = __majority_percentage(a["all"])
  164. def __true_percentage(a):
  165. if len(a) == 0:
  166. return 0
  167. return np.count_nonzero(a) / len(a)
  168. def __majority_percentage(a):
  169. true_perc = __true_percentage(a)
  170. return true_perc if true_perc >= 0.5 else 1 - true_perc
  171. def __pqubo():
  172. sat = rand_sat.generateRandomKSAT(42, 7, 3)
  173. ising = SAT2QUBO.primitiveQUBO(sat)
  174. nx_qubo = __qubo_to_nx_graph(ising)
  175. target_graph = dnx.chimera_graph(16, 16, 4)
  176. emb = minorminer.find_embedding(nx_qubo.edges(),
  177. target_graph.edges(),
  178. return_overlap=True)
  179. if emb[1] != 1:
  180. print("no embedding found")
  181. return
  182. chimera_sampler = dimod.StructureComposite(SimulatedAnnealingSampler(),
  183. target_graph.nodes(),
  184. target_graph.edges())
  185. sampler = FixedEmbeddingComposite(chimera_sampler, emb[0])
  186. h, J = __split_ising(ising)
  187. res = sampler.sample_ising(h, J)
  188. #res = sampler.sample_ising(h, J, find_max=False)
  189. print(res.truncate(10))
  190. sample = res.first.sample
  191. extracted = {}
  192. r = re.compile("c\d+_l-?\d*")
  193. for label, assignment in sample.items():
  194. if r.fullmatch(label):
  195. extracted[tuple(re.split(r"\_l", label[1:]))] = assignment
  196. model = [True for i in range(len(extracted))]
  197. assignments = {}
  198. for label, assignment in extracted.items():
  199. clause = int(label[0])
  200. lit = int(label[1])
  201. var = abs(lit)
  202. if lit < 0:
  203. assignment *= -1
  204. if var in assignments:
  205. assignments[var].append(assignment)
  206. else:
  207. assignments[var] = [assignment]
  208. conflicts = False
  209. for var, a in assignments.items():
  210. if abs(np.sum(a)) != len(a):
  211. conflicts = True
  212. print("conflicts - no solution found")
  213. print(var, np.sort(a))
  214. if conflicts:
  215. print(assignments)
  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 __pqubo_3():
  222. sat_count = 0
  223. no_embedding_count = 0
  224. for i in range(200):
  225. sat = rand_sat.generateRandomKSAT(40, 14, 3)
  226. #ising = SAT2QUBO.primitiveQUBO_8(sat)
  227. ising = SAT2QUBO.WMISdictQUBO_2(sat)
  228. nx_qubo = __qubo_to_nx_graph(ising)
  229. target_graph = dnx.chimera_graph(16, 16, 4)
  230. emb = minorminer.find_embedding(nx_qubo.edges(),
  231. target_graph.edges(),
  232. return_overlap=True)
  233. if emb[1] != 1:
  234. print("no embedding found")
  235. no_embedding_count += 1
  236. continue
  237. chimera_sampler = dimod.StructureComposite(SimulatedAnnealingSampler(),
  238. target_graph.nodes(),
  239. target_graph.edges())
  240. sampler = FixedEmbeddingComposite(chimera_sampler, emb[0])
  241. h, J = __split_ising(ising)
  242. res = sampler.sample_qubo(ising)
  243. #res = sampler.sample_ising(h, J, find_max=False)
  244. print(res.truncate(10))
  245. print("chain_break_fraction", res.first.chain_break_fraction)
  246. sample = res.first.sample
  247. assignments = {}
  248. vars = set()
  249. for node, energy in sample.items():
  250. if node[0] == "x":
  251. lit = int(node[1:])
  252. vars.add(abs(lit))
  253. assignments[lit] = energy
  254. print(assignments)
  255. conflicts = set()
  256. for var in vars:
  257. if var in assignments and -var in assignments:
  258. if assignments[var] == assignments[-var]:
  259. print("conflict at var: {}".format(var))
  260. conflicts.add(var)
  261. #if conflicts:
  262. # return
  263. model = [True for i in range(len(vars))]
  264. for var in vars:
  265. if var in assignments:
  266. model[var - 1] = True if assignments[var] == 1 else False
  267. elif -var in assignments:
  268. model[var - 1] = True if assignments[-var] == 0 else False
  269. var_list = list(conflicts)
  270. print(sat.checkAssignment(model))
  271. if len(var_list) > 0:
  272. for i in range(1000):
  273. if sat.checkAssignment(model):
  274. print(i)
  275. break
  276. rand_var = random.choice(var_list)
  277. model[rand_var - 1] = not model[rand_var - 1]
  278. print()
  279. print(model)
  280. print()
  281. print(sat.checkAssignment(model))
  282. if sat.checkAssignment(model):
  283. sat_count += 1
  284. print()
  285. degrees = sat.getDegreesOfVariables()
  286. for var in conflicts:
  287. node_var = "x{}".format(var)
  288. node_nvar = "x{}".format(-var)
  289. print("var {}: deg={}, coupler={}, e={}, ne={}"
  290. .format(var,
  291. degrees[var],
  292. ising[(node_var, node_nvar)],
  293. assignments[var],
  294. assignments[-var]))
  295. print("sat ratio: {}".format(sat_count / (200 - no_embedding_count)))
  296. def __split_ising(ising):
  297. h = {}
  298. J = {}
  299. for coupler, energy in ising.items():
  300. if coupler[0] == coupler[1]:
  301. h[coupler[0]] = energy
  302. else:
  303. J[coupler] = energy
  304. return h, J
  305. def __negate_qubo(qubo):
  306. negative_qubo = {}
  307. for coupler, energy in qubo.items():
  308. negative_qubo[coupler] = -1 * energy
  309. return negative_qubo
  310. if __name__ == "__main__":
  311. main()