|
|
- #!/usr/bin/env python3
-
- from util import SAT2QUBO as s2q
- from util import randomSAT as rs
- from util import queries
- from util import graph
- from util import script
-
- import networkx as nx
- import dwave_networkx as dnx
- import minorminer
- from dwave_qbsolv import QBSolv
- import dimod
- from dwave.system.composites import FixedEmbeddingComposite
- from neal import SimulatedAnnealingSampler
-
- import matplotlib.pyplot as plt
- import seaborn as sns
- import numpy as np
- import re
- from tqdm import tqdm
-
- def frange(start, stop, steps):
- while start < stop:
- yield start
- start += steps
-
- def test_kv_range():
-
- k = 75
- v = 40
-
- data = {
- "p_node_counts" : [],
- "wmis_node_counts" : [],
-
- "p_conn_counts" : [],
- "wmis_conn_counts" : [],
-
- "p_avrg_connectivity" : [],
- "wmis_avrg_connectivity" : [],
-
- "a_arr" : [],
-
- "k_arr" : []
- }
-
- target = dnx.chimera_graph(25, 25, 4)
-
- print(target.number_of_nodes())
-
- for r in range(2):
- #for k in range(50, 5001, 50):
- for a in frange(0.5, 8, 0.5):
- #v = int(k/4)
- #a = k/v
-
- #v = int(k/a)
- k = int(a*v)
-
- print("k={} v={} k/v={}".format(k, v, k/v))
-
- ksatInstance = rs.generateRandomKSAT(k, v, 3)
-
- p_qubo = s2q.WMISdictQUBO_2(ksatInstance)
-
- wmis_qubo = s2q.WMISdictQUBO(ksatInstance)
-
- qg = nx.Graph()
-
- for coupler, energy in wmis_qubo.items():
- if coupler[0] != coupler[1]:
- qg.add_edge(coupler[0], coupler[1], weight=energy)
-
-
- ig = nx.Graph()
- for coupler, energy in p_qubo.items():
- if coupler[0] != coupler[1]:
- ig.add_edge(coupler[0], coupler[1], weight=energy)
-
-
- p_node_count = ig.number_of_nodes();
- p_conn_count = ig.number_of_edges();
-
-
- wmis_node_count = qg.number_of_nodes();
- wmis_conn_count = qg.number_of_edges();
-
-
-
- print("p_qubo nodes= {}".format(p_node_count));
- print("wwmis qubo nodes= {}".format(wmis_node_count));
-
- print("nodes= {}".format(p_node_count / wmis_node_count));
-
-
- data["p_node_counts"].append(p_node_count)
- data["wmis_node_counts"].append(wmis_node_count)
-
- data["p_conn_counts"].append(p_conn_count)
- data["wmis_conn_counts"].append(wmis_conn_count)
-
- print("calculating connectivity...")
- data["p_avrg_connectivity"].append(nx.edge_connectivity(ig))
- print("calculating connectivity...")
- data["wmis_avrg_connectivity"].append(nx.edge_connectivity(qg))
-
- data["a_arr"].append(k/v)
- data["k_arr"].append(k)
-
- print()
-
- sns.set()
-
- ax = sns.scatterplot(x="a_arr", y="p_node_counts", data=data, label="p_qubo")
- ax.set(xlabel='k/v', ylabel='used verticies')
- ax = sns.scatterplot(x="a_arr", y="wmis_node_counts", data=data, ax=ax, label="wmis_qubo")
- plt.show()
-
- ax = sns.scatterplot(x="a_arr", y="p_conn_counts", data=data, label="p_qubo")
- ax.set(xlabel='k/v', ylabel='used edges')
- ax = sns.scatterplot(x="a_arr", y="wmis_conn_counts", data=data, ax=ax, label="wmis_qubo")
- plt.show()
-
- ax = sns.scatterplot(x="a_arr", y="p_avrg_connectivity", data=data, label="p_qubo")
- ax.set(xlabel='k/v', ylabel='avrg connectivity')
- ax = sns.scatterplot(x="a_arr", y="wmis_avrg_connectivity", data=data, ax=ax, label="wmis_qubo")
- plt.show()
-
-
- def test_kv_range_emb():
-
- k = 75
-
- data = {
- "p_node_counts" : [],
- "wmis_node_counts" : [],
-
- "p_conn_counts" : [],
- "wmis_conn_counts" : [],
-
- "a_arr" : [],
-
- "k_arr" : []
- }
-
- target = dnx.chimera_graph(25, 25, 4)
-
- print(target.number_of_nodes())
-
- for r in range(2):
- #for k in range(50, 5001, 50):
- for a in frange(3.5, 5.5, 0.1):
- #v = int(k/4)
- #a = k/v
-
- v = int(k/a)
-
- print("k={} v={} k/v={}".format(k, v, k/v))
-
- ksatInstance = rs.generateRandomKSAT(k, v, 3)
-
- p_qubo = s2q.WMISdictQUBO_2(ksatInstance)
-
- wmis_qubo = s2q.WMISdictQUBO(ksatInstance)
-
- qg = nx.Graph()
-
- for coupler, energy in wmis_qubo.items():
- if coupler[0] != coupler[1]:
- qg.add_edge(coupler[0], coupler[1], weight=energy)
-
-
- ig = nx.Graph()
- for coupler, energy in p_qubo.items():
- if coupler[0] != coupler[1]:
- ig.add_edge(coupler[0], coupler[1], weight=energy)
-
- qemb = minorminer.find_embedding(qg.edges(), target.edges(), return_overlap=True, threads=8)
- print("wmis emb. found: {}".format(qemb[1]))
- iemb = minorminer.find_embedding(ig.edges(), target.edges(), return_overlap=True, threads=8)
- print("primitive emb. found: {}".format(iemb[1]))
-
- if qemb[1] == 0 or iemb[1] == 0:
- print()
- continue
-
- p_node_count = 0;
- p_conn_count = 0;
-
- used_nodes = []
- for var, chain in iemb[0].items():
- used_nodes.extend(chain)
-
- p_node_count = len(np.unique(used_nodes))
-
- wmis_node_count = 0;
- wmis_conn_count = 0;
-
- used_nodes = []
- for var, chain in qemb[0].items():
- used_nodes.extend(chain)
-
- wmis_node_count = len(np.unique(used_nodes))
-
-
- #print("p_qubo: nodes={} connections={}".format(p_node_count, p_conn_count))
-
- #print("wmis_qubo: nodes={} connections={}".format(wmis_node_count, wmis_conn_count))
-
- print("p_qubo nodes= {}".format(p_node_count));
- print("wwmis qubo nodes= {}".format(wmis_node_count));
-
- print("nodes= {}".format(p_node_count / wmis_node_count));
- #print("conns= {}".format(p_conn_count / wmis_conn_count));
-
-
- data["p_node_counts"].append(p_node_count)
- data["wmis_node_counts"].append(wmis_node_count)
-
- data["p_conn_counts"].append(p_conn_count)
- data["wmis_conn_counts"].append(wmis_conn_count)
-
- data["a_arr"].append(k/v)
- data["k_arr"].append(k)
-
- print()
-
- sns.set()
-
- ax = sns.scatterplot(x="a_arr", y="p_node_counts", data=data, label="p_qubo")
- ax.set(xlabel='k/v', ylabel='used verticies after embedding')
- ax = sns.scatterplot(x="a_arr", y="wmis_node_counts", data=data, ax=ax, label="wmis_qubo")
- plt.show()
-
- def test_k_range():
-
- k = 75
-
- data = {
- "p_node_counts" : [],
- "wmis_node_counts" : [],
-
- "p_conn_counts" : [],
- "wmis_conn_counts" : [],
-
- "a_arr" : [],
-
- "k_arr" : []
- }
-
- target = dnx.chimera_graph(25, 25, 4)
-
- print(target.number_of_nodes())
-
- for r in range(2):
- for k in range(15, 76, 1):
- v = int(k/4)
-
-
- print("k={} v={} k/v={}".format(k, v, k/v))
-
- ksatInstance = rs.generateRandomKSAT(k, v, 3)
-
- p_qubo = s2q.primitiveQUBO(ksatInstance)
-
- wmis_qubo = s2q.WMISdictQUBO(ksatInstance)
-
- qg = nx.Graph()
-
- for coupler, energy in wmis_qubo.items():
- if coupler[0] != coupler[1]:
- qg.add_edge(coupler[0], coupler[1], weight=energy)
-
-
- ig = nx.Graph()
- for coupler, energy in p_qubo.items():
- if coupler[0] != coupler[1]:
- ig.add_edge(coupler[0], coupler[1], weight=energy)
-
- qemb = minorminer.find_embedding(qg.edges(), target.edges(), return_overlap=True, threads=8)
- print("wmis emb. found: {}".format(qemb[1]))
- iemb = minorminer.find_embedding(ig.edges(), target.edges(), return_overlap=True, threads=8)
- print("primitive emb. found: {}".format(iemb[1]))
-
- if qemb[1] == 0 or iemb[1] == 0:
- print()
- continue
-
- p_node_count = 0;
- p_conn_count = 0;
-
- used_nodes = []
- for var, chain in iemb[0].items():
- used_nodes.extend(chain)
-
- p_node_count = len(np.unique(used_nodes))
-
- wmis_node_count = 0;
- wmis_conn_count = 0;
-
- used_nodes = []
- for var, chain in qemb[0].items():
- used_nodes.extend(chain)
-
- wmis_node_count = len(np.unique(used_nodes))
-
-
- #print("p_qubo: nodes={} connections={}".format(p_node_count, p_conn_count))
-
- #print("wmis_qubo: nodes={} connections={}".format(wmis_node_count, wmis_conn_count))
-
- print("p_qubo nodes= {}".format(p_node_count));
- print("wwmis qubo nodes= {}".format(wmis_node_count));
-
- print("nodes= {}".format(p_node_count / wmis_node_count));
- #print("conns= {}".format(p_conn_count / wmis_conn_count));
-
-
- data["p_node_counts"].append(p_node_count)
- data["wmis_node_counts"].append(wmis_node_count)
-
- data["p_conn_counts"].append(p_conn_count)
- data["wmis_conn_counts"].append(wmis_conn_count)
-
- data["a_arr"].append(k/v)
- data["k_arr"].append(k)
-
- print()
-
- sns.set()
-
- ax = sns.scatterplot(x="k_arr", y="p_node_counts", data=data, label="p_qubo")
- ax.set(xlabel='k',
- ylabel='used verticies after embedding')
- ax = sns.scatterplot(x="k_arr", y="wmis_node_counts", data=data, ax=ax, label="wmis_qubo")
- plt.show()
-
- def medianChainLength(emb):
- chl = []
-
- for chain in emb.values():
- chl.append(len(chain))
-
- sns.distplot(chl)
- plt.show()
-
- return np.mean(chl)
-
-
- def test2():
- sat = rs.generateRandomKSAT(42, 10, 3)
-
- print(sat.toString())
-
- qubo = s2q.WMISdictQUBO(sat)
- #ising = s2q.primitiveQUBO_8(sat)
- ising = s2q.WMISdictQUBO_2(sat)
-
- qg = nx.Graph()
-
- for coupler, energy in qubo.items():
- if coupler[0] != coupler[1]:
- qg.add_edge(coupler[0], coupler[1], weight=energy)
-
-
- ig = nx.Graph()
- for coupler, energy in ising.items():
- if coupler[0] != coupler[1]:
- ig.add_edge(coupler[0], coupler[1], weight=energy)
-
- #plt.ion()
-
- print(qg.number_of_nodes(), qg.number_of_edges())
- print(ig.number_of_nodes(), ig.number_of_edges())
-
- target = dnx.chimera_graph(16, 16, 4)
- #nx.draw_shell(qg, with_labels=True, node_size=50)
- #nx.draw_shell(ig, with_labels=True, node_size=50)
-
- eg = ig
-
- emb = minorminer.find_embedding(eg.edges(), target.edges(), return_overlap=True,
- threads=8)
-
- print(emb[1])
-
- for node, chain in emb[0].items():
- print(node, chain)
-
- print("avrg chain length = {}".format(medianChainLength(emb[0])))
-
- dnx.draw_chimera_embedding(G=target, emb=emb[0], embedded_graph=eg, show_labels=True)
-
- plt.show()
-
-
- def test3():
- sat = rs.generateRandomKSAT(42, 10, 3)
-
- print(sat.toString())
-
- ising = s2q.primitiveQUBO(sat)
-
- h = {}
- J = {}
-
- for coupler, energy in ising.items():
- if coupler[0] == coupler[1]:
- h[coupler[0]] = energy
- else:
- J[coupler] = energy
-
- res = QBSolv().sample_ising(h, J, find_max=False)
-
-
- sample = list(res.samples())[0]
-
- extracted = {}
-
- r = re.compile("c\d+_l-?\d*")
-
- for label, assignment in sample.items():
- if r.fullmatch(label):
-
- extracted[tuple(re.split(r"\_l", label[1:]))] = assignment
-
- model = [True for i in range(len(extracted))]
-
- assignments = {}
-
- for label, assignment in extracted.items():
- clause = int(label[0])
- lit = int(label[1])
- var = abs(lit)
-
- if lit < 0:
- assignment *= -1
-
- if var in assignments:
- assignments[var].append(assignment)
- else:
- assignments[var] = [assignment]
-
-
- conflicts = False
- for var, a in assignments.items():
- if abs(np.sum(a)) != len(a):
- conflicts = True
- print("conflicts - no solution found")
- print(var, np.sort(a))
-
- if conflicts:
- return
-
- model = [True for i in range(sat.getNumberOfVariables())]
-
- for var, assignment in assignments.items():
- model[var - 1] = True if assignment[0] > 0 else False
-
- print(model, sat.checkAssignment(model))
-
- def test3_3():
- sat = rs.generateRandomKSAT(42, 10, 3)
-
- print(sat.toString())
-
- #ising = s2q.primitiveQUBO_8(sat)
- ising = s2q.WMISdictQUBO_2(sat)
-
- #ising = {}
-
- #ising[("x1", "z1")] = +2
- #ising[("x2", "z2")] = +2
-
- #ising[("z1", "z2")] = +2
-
- #ising[("z1", "z1")] = -2
- #ising[("z2", "z2")] = -2
-
- #ising[("x1", "z3")] = -2
- #ising[("x2", "z3")] = -2
- #ising[("x3", "z3")] = +2
- #ising[("z3", "z3")] = +2
-
-
- h, J = graph.split_ising(ising)
-
- #res = QBSolv().sample_ising(h, J, find_max=False)
- res = QBSolv().sample_qubo(ising, find_max=False)
-
- #res = dimod.ExactSolver().sample_ising(h, J)
- #res = dimod.ExactSolver().sample_qubo(ising)
-
- sample = res.first.sample
-
- print(res.truncate(50))
- #print(res.truncate(10))
-
- assignments = {}
- vars = set()
-
- for node, energy in sample.items():
- if node[0] == "x":
- lit = int(node[1:])
-
- vars.add(abs(lit))
-
- assignments[lit] = energy
-
- conflicts = set()
- for var in vars:
- if var in assignments and -var in assignments:
- if assignments[var] == assignments[-var]:
- print("conflict at var: {}".format(var))
- conflicts.add(var)
-
- #if conflicts:
- # return
-
- model = [True for i in range(len(vars))]
-
- for var in vars:
- if var in assignments:
- model[var - 1] = True if assignments[var] == 1 else False
- elif -var in assignments:
- model[var - 1] = True if assignments[-var] == 0 else False
-
- print()
-
- print(model)
-
- print()
-
- print(sat.checkAssignment(model))
-
- print()
-
- degrees = sat.getDegreesOfVariables()
-
- for var in conflicts:
- node_var = "x{}".format(var)
- node_nvar = "x{}".format(-var)
- print("var {}: deg={}, coupler={}, e={}, ne={}"
- .format(var,
- degrees[var],
- ising[(node_var, node_nvar)],
- assignments[var],
- assignments[-var]))
-
- def test3_4():
- sat_count = 0
-
- steps = 200
-
- for i in tqdm(range(steps)):
- sat = rs.generateRandomKSAT(35, 10, 3)
-
- ising = s2q.WMISdictQUBO_2(sat)
-
-
-
- res = QBSolv().sample_qubo(ising, find_max=False)
-
- #res = dimod.ExactSolver().sample_qubo(ising)
-
- sample = res.first.sample
-
-
- assignments = {}
- vars = set()
-
- for node, energy in sample.items():
- if node[0] == "x":
- lit = int(node[1:])
-
- vars.add(abs(lit))
-
- assignments[lit] = energy
-
- model = [True for i in range(len(vars))]
-
- for var in vars:
- if var in assignments:
- model[var - 1] = True if assignments[var] == 1 else False
- elif -var in assignments:
- model[var - 1] = True if assignments[-var] == 0 else False
-
- if sat.checkAssignment(model):
- sat_count += 1
-
- print("sat percentage: {}".format(sat_count / steps))
-
- def test_wmis():
- sat_count = 0
-
- #steps = 100
- steps = 1
-
- for i in tqdm(range(steps)):
- sat = rs.generateRandomKSAT(35, 10, 3)
- target = dnx.chimera_graph(16, 16, 4)
-
- qubo = s2q.WMISdictQUBO(sat)
-
- qg = nx.Graph()
-
- for coupler, energy in qubo.items():
- if coupler[0] != coupler[1]:
- qg.add_edge(coupler[0], coupler[1], weight=energy)
-
- qemb = minorminer.find_embedding(qg.edges(), target.edges(), return_overlap=True)
-
- chimera_sampler = dimod.StructureComposite(SimulatedAnnealingSampler(),
- target.nodes(),
- target.edges())
-
- solver = FixedEmbeddingComposite(chimera_sampler, qemb[0])
-
- res = solver.sample_qubo(__negate_qubo(qubo))
- #res = solver.sample_qubo(qubo)
-
- #res = dimod.ExactSolver().sample_qubo(ising)
-
-
- sample = res.first.sample
-
- model = script.majority_vote_sample(sample)
-
- print("energy={}".format(res.first.energy))
-
- if sat.checkAssignment(model):
- sat_count += 1
-
- print("sat percentage: {}".format(sat_count / steps))
-
- def test4():
- sat = rs.generateRandomKSAT(50, 13, 3)
-
- print(sat.toString())
-
- qubo = s2q.WMISdictQUBO(sat)
- ising = s2q.primitiveQUBO(sat)
-
- qg = nx.Graph()
-
- for coupler, energy in qubo.items():
- if coupler[0] != coupler[1]:
- qg.add_edge(coupler[0], coupler[1], weight=energy)
-
-
- ig = nx.Graph()
- for coupler, energy in ising.items():
- if coupler[0] != coupler[1]:
- ig.add_edge(coupler[0], coupler[1], weight=energy)
-
- #plt.ion()
-
- print(qg.number_of_nodes(), qg.number_of_edges())
- print(ig.number_of_nodes(), ig.number_of_edges())
-
- target = dnx.chimera_graph(12, 12, 4)
- #nx.draw_shell(qg, with_labels=True, node_size=50)
- #nx.draw_shell(ig, with_labels=True, node_size=50)
-
- print()
- print("wmis:")
- qemb = minorminer.find_embedding(qg.edges(), target.edges(), return_overlap=True)
- print(qemb[1])
- print("median chain length = {}".format(medianChainLength(qemb[0])))
-
- used_nodes = []
- for var, chain in qemb[0].items():
- used_nodes.extend(chain)
-
- used_nodes = np.unique(used_nodes)
- print("used nodes (embedding) = {}".format(len(used_nodes)))
-
-
- print()
- print("primitves:")
- iemb = minorminer.find_embedding(ig.edges(), target.edges(), return_overlap=True)
- print(iemb[1])
- print("median chain length = {}".format(medianChainLength(iemb[0])))
-
- used_nodes = []
- for var, chain in iemb[0].items():
- used_nodes.extend(chain)
-
- used_nodes = np.unique(used_nodes)
- print("used nodes (embedding) = {}".format(len(used_nodes)))
-
- def __negate_qubo(qubo):
- negative_qubo = {}
-
- for coupler, energy in qubo.items():
- negative_qubo[coupler] = -1 * energy
-
- return negative_qubo
-
- #test3_4()
- #test2()
- #test_kv_range
- test_wmis()
-
-
|