def test_returned_gap_with_aux(self): """Verify that stitch is only allowing gaps that satisfy min_classical_gap to be returned. In this case, by allowing an auxiliary variable, the min_classical_gap should be achieved and stitch should allow a bqm to be returned. """ csp = dwavebinarycsp.ConstraintSatisfactionProblem("SPIN") csp.add_constraint(operator.eq, ['a', 'b']) min_classical_gap = 3 # No aux case: max_graph_size=2 # Note: Should not be possible to satisfy min_classical_gap with self.assertRaises(dwavebinarycsp.exceptions.ImpossibleBQM): dwavebinarycsp.stitch(csp, min_classical_gap=min_classical_gap, max_graph_size=2) # One aux case: max_graph_size=3 # Note: min_classical_gap should be satisfied when we have three nodes bqm = dwavebinarycsp.stitch(csp, min_classical_gap=min_classical_gap, max_graph_size=3) # Verify one aux case sampleset = dimod.ExactSolver().sample(bqm) energy_array = sampleset.record['energy'] gap = max(energy_array) - min(energy_array) self.assertGreaterEqual(gap, min_classical_gap)
def test_eight_variable_constraint_smoketest(self): csp = dwavebinarycsp.ConstraintSatisfactionProblem( dwavebinarycsp.BINARY) variables = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] # this is reducible but for our purposes here that's fine def f(a, b, c, d, e, f, g, h): if a and b: return False if c and d: return False if e and f: return False return not (g and h) csp.add_constraint(f, variables) bqm = dwavebinarycsp.stitch(csp) resp = dimod.ExactSolver().sample(bqm) ground_energy = min(resp.record['energy']) for sample, energy in resp.data(['sample', 'energy']): if energy == ground_energy: self.assertTrue(csp.check(sample)) else: if abs(energy - ground_energy) < 2: # if classical gap is less than 2 self.assertTrue(csp.check(sample))
def solve(self, checkDeadloack=True): csp = dwavebinarycsp.ConstraintSatisfactionProblem( dwavebinarycsp.BINARY) for i in range(self.N): c = self.chopsticks[i] next_c = self.chopsticks[(i + 1) % self.N] vars = [c + '_R', c + '_L'] if checkDeadloack: csp.add_constraint(exactly1, vars) else: csp.add_constraint(atMost1, vars) phils = [c + '_R', next_c + '_L'] if checkDeadloack: csp.add_constraint(exactly1, phils) bqm = dwavebinarycsp.stitch(csp) sampler = self.getSampler() try: start = time.time() response = sampler.sample(bqm, num_reads=50) end = time.time() t = end - start sample = next(response.samples()) if not csp.check(sample): print("Failed to detect deadlock") t = 0 else: if self.draw: self.drawConfig(sample) except: t = -1 return t
def constructBQM(P): pBit = len(bin(P)) - 2 abBit = ceil(pBit / 2) print('pBit : {}, abBit : {}'.format(pBit, abBit)) csp = dbc.factories.multiplication_circuit(abBit) bqm = dbc.stitch(csp, min_classical_gap=.1) # return bqm,bqm p_vars = [] for i in range(pBit): p_vars.append('p' + str(i)) # else: # break fixed_variables = dict(zip(reversed(p_vars), "{:b}".format(P))) fixed_variables = {var: int(x) for (var, x) in fixed_variables.items()} print(fixed_variables) for var, value in fixed_variables.items(): bqm.fix_variable(var, value) bqm_ising = bqm.to_ising() h = bqm_ising[0] J = bqm_ising[1] return h, J # , abBit
def cluster_points(scattered_points, filename): # Set up problem # Note: max_distance gets used in division later on. Hence, the max(.., 1) # is used to prevent a division by zero coordinates = [Coordinate(x, y) for x, y in scattered_points] max_distance = max(get_max_distance(coordinates), 1) # Build constraints csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) # Apply constraint: coordinate can only be in one colour group choose_one_group = {(0, 0, 1), (0, 1, 0), (1, 0, 0)} for coord in coordinates: csp.add_constraint(choose_one_group, (coord.r, coord.g, coord.b)) # Build initial BQM bqm = dwavebinarycsp.stitch(csp) # Edit BQM to bias for close together points to share the same color for i, coord0 in enumerate(coordinates[:-1]): for coord1 in coordinates[i + 1:]: # Set up weight d = get_distance(coord0, coord1) / max_distance # rescale distance weight = -math.cos(d * math.pi) # Apply weights to BQM bqm.add_interaction(coord0.r, coord1.r, weight) bqm.add_interaction(coord0.g, coord1.g, weight) bqm.add_interaction(coord0.b, coord1.b, weight) # Edit BQM to bias for far away points to have different colors for i, coord0 in enumerate(coordinates[:-1]): for coord1 in coordinates[i + 1:]: # Set up weight # Note: rescaled and applied square root so that far off distances # are all weighted approximately the same d = math.sqrt(get_distance(coord0, coord1) / max_distance) weight = -math.tanh(d) * 0.1 # Apply weights to BQM bqm.add_interaction(coord0.r, coord1.b, weight) bqm.add_interaction(coord0.r, coord1.g, weight) bqm.add_interaction(coord0.b, coord1.r, weight) bqm.add_interaction(coord0.b, coord1.g, weight) bqm.add_interaction(coord0.g, coord1.r, weight) bqm.add_interaction(coord0.g, coord1.b, weight) # Submit problem to D-Wave sampler sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True})) #sampler = neal.SimulatedAnnealingSampler() sampleset = sampler.sample(bqm, chain_strength=4, num_reads=1000) best_sample = sampleset.first.sample # Visualize graph problem dwave.inspector.show(bqm, sampleset) # Visualize solution groupings = get_groupings(best_sample) visualize_groupings(groupings, filename) return groupings
def generate_dwavecsp(self): ''' returns: a weighted constraint matrix generated by dwave's algorithm ''' csp = dwavebinarycsp.ConstraintSatisfactionProblem('BINARY') def Aix_1(*args): return sum(list(args)) == 1 for i in range(1, self.n + 1): args = [] for k in range(1, self.k + 1): var_index = idx.index_1_q_to_l_1(i, k, self.k) - 1 args.append(var_index) csp.add_constraint(Aix_1, args) def Aix_le_s(*args): return sum(list(args)) <= self.bunch_size for k in range(1, self.k + 1): args = [] for i in range(1, self.n + 1): var_index = idx.index_1_q_to_l_1(i, k, self.k) - 1 args.append(var_index) print("adding %d inequality" % k) csp.add_constraint(Aix_le_s, args) print("stitching...") bqm = dwavebinarycsp.stitch(csp, max_graph_size=24) mtx = bqm.to_numpy_matrix() print(mtx) return 0
def run_circuit(P, gap, graph, circuit_size): output = { "Results": [], # { # "a": Number, # "b": Number, # "Valid": Boolean, # "Occurrences": Number, # "Percentage of results": Number # } "Timing": { "Actual": { "QPU processing time": None # microseconds } }, "Number of reads": None } csp = circuit(circuit_size) bqm = dbc.stitch(csp, max_graph_size=graph, min_classical_gap=gap) a_vars = make_array(circuit_size, 'a') b_vars = make_array(circuit_size, 'b') p_vars = make_array(circuit_size * 2, 'p') binary = "{:0" + str(circuit_size * 2) + "b}" # Convert P from decimal to binary fixed_variables = dict(zip(reversed(p_vars), binary.format(P))) fixed_variables = {var: int(x) for (var, x) in fixed_variables.items()} # Fix product qubits # for var, value in fixed_variables.items(): # bqm.fix_variable(var, value) for constraint in csp.constraints: print(constraint)
def test_sample_instantiation(self): # Check that values have not been instantiated sampler = LazyEmbeddingComposite(MockSampler()) self.assertIsNone(sampler.embedding) self.assertIsNone(sampler.nodelist) self.assertIsNone(sampler.edgelist) self.assertIsNone(sampler.adjacency) self.assertIsNone(sampler.parameters) self.assertIsNone(sampler.properties) # Set up BQM and sample csp = dbc.ConstraintSatisfactionProblem(dbc.BINARY) csp.add_constraint(and_gate(['a', 'b', 'c'])) bqm = dbc.stitch(csp) sampler.sample(bqm) # Check that values have been populated self.assertIsNotNone(sampler.embedding) self.assertEqual(sampler.nodelist, ['a', 'b', 'c']) self.assertEqual(sampler.edgelist, [('a', 'b'), ('a', 'c'), ('b', 'c')]) self.assertEqual(sampler.adjacency, { 'a': {'b', 'c'}, 'b': {'a', 'c'}, 'c': {'a', 'b'} }) self.assertIsNotNone(sampler.parameters) self.assertIsNotNone(sampler.properties)
def get_bqm(self, penalty_per_tile=0.5): """Applies the constraints necessary to form a maze and returns a BQM that would correspond to a valid path through said maze. Note: If penalty_per_tile is too large, the path will be too heavily penalized and the optimal solution might no path at all. Args: penalty_per_tile: A number. Penalty for each tile that is included in the path; encourages shorter paths. Returns: A dimod.BinaryQuadraticModel """ # Apply constraints onto self.csp self._apply_valid_move_constraint() self._set_start_and_end() self._set_borders() self._set_inner_walls() # Grab bqm constrained for valid solutions bqm = dwavebinarycsp.stitch(self.csp) # Edit bqm to favour optimal solutions for v in bqm.variables: # Ignore auxiliary variables if isinstance(v, str) and re.match(r'^aux\d+$', v): continue # Add a penalty to every tile of the path bqm.add_variable(v, penalty_per_tile) return bqm
def test_stitch_max_graph_size_is_1(self): csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(operator.eq, ['a', 'b']) csp.add_constraint(operator.ne, ['b', 'c']) with self.assertRaises(dwavebinarycsp.exceptions.ImpossibleBQM): bqm = dwavebinarycsp.stitch(csp, max_graph_size=1)
def to_bqm(self=None): """Stitch a given Constraint Solving Problem into a BQM. Args: self(dwavebinarycsp.ConstraintSatisfactionProblem): The Constraint Solving Problem to stitch into a BQM. (default None) Returns: dimod.binary_quadratic_model.BinaryQuadraticModel: BQM stitched together from the given Constraint Solving Problem. """ # Return the BQM. return __dbc__.stitch(self)
def test_stitch_constraint_too_large(self): csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) def f(*args): return all(args) csp.add_constraint(f, list('abcdefghijk')) # 11 variables with self.assertRaises(dwavebinarycsp.exceptions.ImpossibleBQM): bqm = dwavebinarycsp.stitch(csp, max_graph_size=8)
def getQUBOfromDIMACS(path, return_dict): with open(path, 'r') as fp: try: csp = dwavebinarycsp.cnf.load_cnf(fp) except ValueError: return_dict[0] = None return bqm = dwavebinarycsp.stitch(csp) return_dict[0] = bqm.to_qubo()
def test_csp_one_xor_impossible(self): csp = dwavebinarycsp.ConstraintSatisfactionProblem( dwavebinarycsp.BINARY) variables = ['a', 'b', 'c'] xor = dwavebinarycsp.factories.constraint.gates.xor_gate(variables) csp.add_constraint(xor) with self.assertRaises(pm.ImpossiblePenaltyModel): bqm = dwavebinarycsp.stitch(csp, max_graph_size=3)
def test_dwavebinarycsp(self): import dimod import dwavebinarycsp csp = dwavebinarycsp.factories.random_2in4sat(8, 4) # 8 variables, 4 clauses bqm = dwavebinarycsp.stitch(csp) resp = dimod.ExactSolver().sample(bqm) for sample, energy in resp.data(['sample', 'energy']): csp.check(sample)
def test_stitch_multiplication_circuit(self): circuit = dwavebinarycsp.factories.multiplication_circuit( 3) # 3x3=6 bit # the circuit csp is too large for dimod's exact solver to solve quickly, so let's go ahead # and fix the inputs and outputs to ones that satisfy the csp and solve for the aux variables # 15 = 3 * 5 fixed_variables = dict([ ('p0', 1), ('p1', 1), ('p2', 1), ('p3', 1), ('p4', 0), ('p5', 0), # 15 ('a0', 1), ('a1', 1), ('a2', 0), # 3 ('b0', 1), ('b1', 0), ('b2', 1) ]) # 5 for v, val in fixed_variables.items(): circuit.fix_variable(v, val) # original circuit original_circuit = dwavebinarycsp.factories.multiplication_circuit(3) # we are using an exact solver, so we only need a positive classical gap bqm = dwavebinarycsp.stitch(circuit, min_classical_gap=.1) resp = dimod.ExactSolver().sample(bqm) ground_energy = min(resp.record['energy']) for sample, energy in resp.data(['sample', 'energy']): if energy == ground_energy: self.assertTrue(circuit.check(sample)) else: self.assertFalse(circuit.check(sample)) # check against the original circuit fixed = fixed_variables.copy() fixed.update(sample) if energy == ground_energy: self.assertTrue(original_circuit.check(fixed)) else: self.assertFalse(original_circuit.check(fixed))
def test_returned_gap(self): """Verify that stitch is only allowing gaps that satisfy min_classical_gap to be returned. """ # Set up CSP csp = dwavebinarycsp.ConstraintSatisfactionProblem("SPIN") csp.add_constraint(operator.ne, ['a', 'b']) # Show that CSP has a valid BQM small_gap = 2 bqm = dwavebinarycsp.stitch(csp, min_classical_gap=small_gap, max_graph_size=2) # Verify the gap based on returned bqm sampleset = dimod.ExactSolver().sample(bqm) energy_array = sampleset.record['energy'] gap = max(energy_array) - min(energy_array) self.assertGreaterEqual(gap, small_gap) # Same CSP with a larger min_classical_gap # Note: Even though there is a BQM for this CSP (shown above), stitch should throw an # exception because the BQM does not satisfy the following min_classical_gap requirement. with self.assertRaises(dwavebinarycsp.exceptions.ImpossibleBQM): dwavebinarycsp.stitch(csp, min_classical_gap=4, max_graph_size=2)
def factor(P): bP = "{:06b}".format(P) csp = dbc.factories.multiplication_circuit(3) bqm = dbc.stitch(csp, min_classical_gap=.1) p_vars = ['p0', 'p1', 'p2', 'p3', 'p4', 'p5'] fixed_variables = dict(zip(reversed(p_vars), bP)) fixed_variables = {var: int(x) for (var, x) in fixed_variables.items()} for var, value in fixed_variables.items(): bqm.fix_variable(var, value) sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True})) sampleset = sampler.sample(bqm, num_reads=1000) a, b = to_base_ten(sampleset.first.sample) print("Given integer P={0}, found factors a={1} and b={2}".format(P, a, b)) return a, b
def scheduling(time, location, length, mandatory): if time: # Business hours return (location and mandatory) # In office and mandatory participation else: # Outside business hours return ((not location) and length) # Teleconference for a short duration import dwavebinarycsp csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) csp.add_constraint(scheduling, ['time', 'location', 'length', 'mandatory']) bqm = dwavebinarycsp.stitch(csp) bqm.linear {'length': -2.0, 'location': 2.0, 'mandatory': 0.0, 'time': 2.0} bqm.quadratic {('location', 'length'): 2.0, ('mandatory', 'length'): 0.0, ('mandatory', 'location'): -2.0, ('time', 'length'): 0.0, ('time', 'location'): -4.0, ('time', 'mandatory'): 0.0} from dimod.reference.samplers import ExactSolver sampler = ExactSolver() solution = sampler.sample(bqm) min_energy = next(solution.data(['energy']))[0] print(min_energy) -2.0 for sample, energy in solution.data(['sample', 'energy']): if energy == min_energy: time = 'business hours' if sample['time'] else 'evenings' location = 'office' if sample['location'] else 'home' length = 'short' if sample['length'] else 'long' mandatory = 'mandatory' if sample['mandatory'] else 'optional' print("During {} at {}, you can schedule a {} meeting that is {}".format(time, location, length, mandatory)) if energy == min_energy: time = 'business hours' if sample['time'] else 'evenings' location = 'office' if sample['location'] else 'home' length = 'short' if sample['length'] else 'long' mandatory = 'mandatory' if sample['mandatory'] else 'optional' print("During {} at {}, you can schedule a {} meeting that is {}".format(time, location, length, mandatory))
def test_same_embedding(self): sampler = LazyEmbeddingComposite(MockSampler()) # Set up Ising and sample h = {'a': 1, 'b': 1, 'c': 1} J = {('a', 'b'): 3, ('b', 'c'): -2, ('a', 'c'): 1} sampler.sample_ising(h, J) # Store embedding prev_embedding = sampler.embedding # Check that the same embedding is used csp2 = dbc.ConstraintSatisfactionProblem(dbc.BINARY) csp2.add_constraint(or_gate(['a', 'b', 'c'])) bqm2 = dbc.stitch(csp2) sampler.sample(bqm2) self.assertEqual(sampler.embedding, prev_embedding)
def test_attempt_on_difficult_problem(self): # Set up xor-gate # Note: penaltymodel-lp would need an auxiliary variable in order to handle this; # however, no auxiliaries are provided, hence, it should pass the problem to another # penalty model. nodes = ['a', 'b', 'c'] xor_gate_values = {(-1, -1, -1), (-1, 1, 1), (1, -1, 1), (1, 1, -1)} # penaltymodel-lp should not be able to handle an xor-gate with self.assertRaises(ValueError): lp.generate_bqm(nx.complete_graph(nodes), xor_gate_values, nodes) # Check that penaltymodel-lp is able to pass the problem to another penaltymodel csp = dbc.ConstraintSatisfactionProblem(dbc.SPIN) csp.add_constraint(xor_gate_values, ('a', 'b', 'c')) bqm = dbc.stitch( csp) # BQM created by a penaltymodel that is not penaltymodel-lp self.assertGreaterEqual(len(bqm.linear) + len(bqm.quadratic), 1) # Check BQM exists
def get_bqm(self, stitch_kwargs=None): """Returns a BQM to the Job Shop Scheduling problem. Args: stitch_kwargs: A dict. Kwargs to be passed to dwavebinarycsp.stitch. """ if stitch_kwargs is None: stitch_kwargs = {} # Apply constraints to self.csp self._add_one_start_constraint() self._add_precedence_constraint() self._add_share_machine_constraint() self._remove_absurd_times() # Get BQM bqm = dwavebinarycsp.stitch(self.csp, **stitch_kwargs) # Edit BQM to encourage an optimal schedule self._edit_bqm_for_shortest_schedule(bqm) return bqm
def test_csp_one_xor(self): csp = dwavebinarycsp.ConstraintSatisfactionProblem( dwavebinarycsp.BINARY) variables = ['a', 'b', 'c'] xor = dwavebinarycsp.factories.constraint.gates.xor_gate(variables) csp.add_constraint(xor) bqm = dwavebinarycsp.stitch(csp) resp = dimod.ExactSolver().sample(bqm) ground_energy = min(resp.record['energy']) for sample, energy in resp.data(['sample', 'energy']): if energy == ground_energy: self.assertTrue(csp.check(sample)) else: if abs(energy - ground_energy) < 2: # if classical gap is less than 2 self.assertTrue(csp.check(sample))
csp = full_adder(csp, "a1", "b1", "cin", "0") csp = full_adder(csp, "a2", "b2", "0_cout", "1") csp = full_adder(csp, "a3", "b3", "1_cout", "2") csp = full_adder(csp, "a4", "b4", "2_cout", "3") csp = full_adder(csp, "a5", "b5", "3_cout", "4") csp = full_adder(csp, "a6", "b6", "4_cout", "5") csp = full_adder(csp, "a7", "b7", "5_cout", "6") csp = full_adder(csp, "a8", "b8", "6_cout", "7") csp = full_adder(csp, "a9", "b9", "7_cout", "8") csp = full_adder(csp, "a10", "b10", "8_cout", "9") for i in range(0, 9): csp.fix_variable("sum" + str(i), 1) csp.fix_variable("9_cout", 1) bqm = dbc.stitch(csp) sampler = EmbeddingComposite(DWaveSampler(solver={"qpu": True})) sampleset = sampler.sample(bqm, num_reads=10000) print(sampleset) for sample, energy in sampleset.data(["sample", "energy"]): string = "" for i in range(1, 10): string += "a" + str(i) + ": " + str(sample["a" + str(i)]) + ", " string += "b" + str(i) + ": " + str(sample["b" + str(i)]) + ", " string += "cin: " + str(sample["cin"]) + " energy: " + str(energy) print(string) dwave.inspector.show(sampleset)
E = 3 * x3 + x1 * x2 - 2 * x1 * x3 - 2 * x2 * x3 configurations.append((E, x1, x2, x3)) # Sort from lowest to highest value of the BQM configurations.sort() # Print BQM value under "E" and all configurations under "x1, x2, x3" print("E, x1, x2, x3") print(configurations) # [(0, 0, 0, 0), (0, 0, 1, 0), (0, 1, 0, 0), (0, 1, 1, 1), (1, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0), (3, 0, 0, 1)] # Now let's use Ocean's [dwavebinarycsp](https://docs.ocean.dwavesys.com/projects/binarycsp/en/latest/) to convert our binary CSP to a BQM for us. The code cell below does so and prints out the BQM's coefficients, the inputs used to program the D-Wave system. As noted, More than one BQM can represent our AND gate, so the BQM generated here does not have to match the one we wrote ourselves. # In[ ]: # Convert the CSP into BQM and_bqm and_bqm = dbc.stitch(and_csp) and_bqm.remove_offset() # Print the linear and quadratic coefficients. These are the programable inputs to a D-Wave system print(and_bqm.linear) # {'x1': 0.0, 'x2': 0.0, 'x3': 6.0} print(and_bqm.quadratic) # {('x2', 'x1'): 2.0, ('x3', 'x1'): -4.0, ('x3', 'x2'): -4.0} # ## Step 3: Solve By Minimization # Lastly, we solve the problem by finding variable values that produce the BQM's lowest values. For real-world problems, with large numbers of variables and constraints, minimizing a BQM is hard: this is where a quantum computer comes in handy. # The next section, which solves a factoring problem, uses the D-Wave system. For this trivial example, instead of using the D-Wave system as the *sampler* (the component used to minimize a BQM), we'll use one of Ocean software's test samplers. Ocean's [dimod](https://docs.ocean.dwavesys.com/projects/dimod/en/latest/) provides one that simply returns the BQM's value for every possible assignment of variable values. # In[ ]: # Use a dimod test sampler that gives the BQM value for all values of its variables
''' csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) # At least one qubit must be set csp.add_constraint(or4, ['x1', 'x2', 'x3', 'x4']) # No more than one qubit can be set csp.add_constraint(nand, ['x1', 'x2']) csp.add_constraint(nand, ['x1', 'x3']) csp.add_constraint(nand, ['x1', 'x4']) csp.add_constraint(nand, ['x2', 'x3']) csp.add_constraint(nand, ['x2', 'x4']) csp.add_constraint(nand, ['x3', 'x4']) bqm = dwavebinarycsp.stitch(csp) response = sampler.sample(bqm, num_reads=samples) # aggregate the results answers = {} valid, invalid = 0, 0 for datum in response.data(): sample, energy, num = datum if (csp.check(sample)): valid = valid + num result = '' for i in range(1, 5): result += str(sample['x' + str(i)]) try: answers[result] += num except:
def cluster_points(scattered_points, filename, architecture): # Set up problem # Note: max_distance gets used in division later on. Hence, the max(.., 1) # is used to prevent a division by zero coordinates = [Coordinate(x, y) for x, y in scattered_points] max_distance = max(get_max_distance(coordinates), 1) # Build constraints csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) # Apply constraint: coordinate can only be in one colour group choose_one_group = {(0, 0, 1), (0, 1, 0), (1, 0, 0)} for coord in coordinates: csp.add_constraint(choose_one_group, (coord.r, coord.g, coord.b)) # Build initial BQM bqm = dwavebinarycsp.stitch(csp) # Edit BQM to bias for close together points to share the same color for i, coord0 in enumerate(coordinates[:-1]): for coord1 in coordinates[i + 1:]: # Set up weight d = get_distance(coord0, coord1) / max_distance # rescale distance weight = -math.cos(d * math.pi) # Apply weights to BQM bqm.add_interaction(coord0.r, coord1.r, weight) bqm.add_interaction(coord0.g, coord1.g, weight) bqm.add_interaction(coord0.b, coord1.b, weight) # Edit BQM to bias for far away points to have different colors for i, coord0 in enumerate(coordinates[:-1]): for coord1 in coordinates[i + 1:]: # Set up weight # Note: rescaled and applied square root so that far off distances # are all weighted approximately the same d = math.sqrt(get_distance(coord0, coord1) / max_distance) weight = -math.tanh(d) * 0.1 # Apply weights to BQM bqm.add_interaction(coord0.r, coord1.b, weight) bqm.add_interaction(coord0.r, coord1.g, weight) bqm.add_interaction(coord0.b, coord1.r, weight) bqm.add_interaction(coord0.b, coord1.g, weight) bqm.add_interaction(coord0.g, coord1.r, weight) bqm.add_interaction(coord0.g, coord1.b, weight) # Submit problem to D-Wave sampler if architecture == 'pegasus': solver = DWaveSampler(solver={ 'topology__type': 'pegasus', 'qpu': True }) print(solver.solver) sampler = EmbeddingComposite(solver) else: solver = DWaveSampler(solver={ 'topology__type': 'chimera', 'qpu': True }) print(solver.solver) sampler = EmbeddingComposite(solver) sampleset = sampler.sample(bqm, chain_strength=4, num_reads=1000, return_embedding=True) best_sample = sampleset.first.sample # Inspect the embedding embedding = sampleset.info['embedding_context']['embedding'] num_qubits = 0 for k in embedding.values(): num_qubits += len(k) print("Number of qubits used in embedding = " + str(num_qubits)) # Visualize graph problem dwave.inspector.show(bqm, sampleset) # Visualize solution groupings = get_groupings(best_sample) visualize_groupings(groupings, filename) # Print solution onto terminal # Note: This is simply a more compact version of 'best_sample' print(groupings)
def cluster_points(scattered_points, filename): # Set up problem coordinates = [Coordinate(x, y) for x, y in scattered_points] max_distance = get_max_distance(coordinates) # Build constraints csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY) # Apply constraint: coordinate can only be in one colour group choose_one_group = allowed_States(k) for coord in coordinates: mylist = list(vars(coord).values()) mylist.remove(coord.x) mylist.remove(coord.y) csp.add_constraint(choose_one_group, mylist) # Build initial BQM bqm = dwavebinarycsp.stitch(csp) # Edit BQM to bias for close together points to share the same color for i, coord0 in enumerate(coordinates[:-1]): for coord1 in coordinates[i + 1:]: # Set up weight d = get_distance(coord0, coord1) / max_distance # rescale distance weight = -math.cos(d * math.pi) # Apply weights to BQM for i in range(k): bqm.add_interaction(getattr(coord0, "x" + str(i)), getattr(coord1, "x" + str(i)), weight) # Edit BQM to bias for far away points to have different colors for i, coord0 in enumerate(coordinates[:-1]): for coord1 in coordinates[i + 1:]: # Set up weight # Note: rescaled and applied square root so that far off distances # are all weighted approximately the same d = math.sqrt(get_distance(coord0, coord1) / max_distance) weight = -math.tanh(d) * 0.1 # Apply weights to BQM for p in range(k): for m in range(k): if p != m: bqm.add_interaction(getattr(coord0, "x" + str(p)), getattr(coord1, "x" + str(m)), weight) # Submit problem to D-Wave sampler sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True})) sampleset = sampler.sample(bqm, chain_strength=4, num_reads=1000) best_sample = sampleset.first.sample # Visualize graph problem dwave.inspector.show(bqm, sampleset) # Visualize solution groupings = get_groupings(best_sample) visualize_groupings(groupings, filename) # Print solution onto terminal # Note: This is simply a more compact version of 'best_sample' print(groupings)
import dwavebinarycsp import dimod import minorminer from dwave.system.composites import FixedEmbeddingComposite, TilingComposite from dwave.system.samplers import DWaveSampler def not_all_equal(q1, q2, q3): return not ((q1 == q2) and (q2 == q3)) csp = dwavebinarycsp.ConstraintSatisfactionProblem(vartype=dimod.Vartype.SPIN) csp.add_constraint(not_all_equal, ['a', 'b', 'c']) csp.add_constraint(not_all_equal, ['c', 'd', 'e']) bqm = dwavebinarycsp.stitch(csp) chimera_cell = [(i, j + 4) for j in range(4) for i in range(4)] embeddings = [ minorminer.find_embedding(bqm.to_qubo()[0].keys(), chimera_cell) for i in range(100) ] min_emb = min(embeddings, key=lambda x: len(sum(x.values(), []))) print("Minimum embedding configuration:", min_emb) print("Minimum embedding length:", len(sum(min_emb.values(), []))) # Verification of the found embedding print("Verification of the found embedding") sampler = FixedEmbeddingComposite(DWaveSampler(), min_emb) response = sampler.sample(bqm, num_reads=5000)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # https://support.dwavesys.com/hc/en-us/community/posts/360016737274-Save-time-Reuse-your-embedding-when-possible import dwavebinarycsp as dbc import dwavebinarycsp.factories.constraint.gates as gates from dwave.system.composites import FixedEmbeddingComposite, EmbeddingComposite from dwave.system.samplers import DWaveSampler # Making two different BQMs (think: energy functions or optimization functions) csp1 = dbc.ConstraintSatisfactionProblem(dbc.BINARY) csp1.add_constraint(gates.and_gate(['a', 'b', 'c'])) bqm1 = dbc.stitch(csp1) csp2 = dbc.ConstraintSatisfactionProblem(dbc.BINARY) csp2.add_constraint(gates.or_gate(['a', 'b', 'c'])) bqm2 = dbc.stitch(csp2) # Using Embedding Composite sampler = EmbeddingComposite(DWaveSampler()) sampler.sample(bqm1) # Gets a new embedding for bqm1 sampler.sample(bqm2) # Gets a new embedding for bqm2 # Using Fixed Embedding Composite # Note: bqm1 and bqm2 can both be represented by the same graph - triangle graph. embedding = { 'a': [0, 4], 'b': [1], 'c': [5] } # Embedding the triangle graph using QPU indices