def tabu_sampler(self): print("\nTabu Sampler....") from tabu import TabuSampler qpu = TabuSampler() self.title = "Tabu Sampler" selected_features = np.zeros((len(self.features), len(self.features))) for k in range(1, len(self.features) + 1): flag = False print("Submitting for k={}".format(k)) kbqm = dimod.generators.combinations(self.features, k, strength=25) kbqm.update(self.bqm) kbqm.normalize() while not flag: result = qpu.sample(kbqm, num_reads=10) # result = qpu.sample_ising(kbqm.to_ising()[0], kbqm.to_ising()[1], num_reads=10) best = result.first.sample if list(result.first.sample.values()).count(1) == k: flag = True for fi, f in enumerate(self.features): selected_features[k - 1, fi] = best[f] if self.is_notebook: from helpers.draw import plot_feature_selection from helpers.plots import plot_solutions plot_feature_selection(self.features, selected_features, self.title)
def __init__(self, num_reads=None, tenure=None, timeout=100, initial_states_generator='random', **runopts): super(TabuProblemSampler, self).__init__(**runopts) self.num_reads = num_reads self.tenure = tenure self.timeout = timeout self.initial_states_generator = initial_states_generator self.sampler = TabuSampler()
def __init__(self, objective_function=None, dwave_sampler=None, dwave_sampler_kwargs=None, experiment_type=None, population_size=1, num_reads=1, num_iters=None): super().__init__(objective_function=objective_function) self.n_obj = self.objective_function.n self.n_qubo = self.n_obj - 1 self.dwave_solver = None self.sampler_kwargs = None self.qpu = False self.population_size = population_size self.num_reads = num_reads # Initialize dwave sampler: if dwave_sampler == 'QPU': self.dwave_solver = EmbeddingComposite(DWaveSampler()) self.qpu = True if dwave_sampler_kwargs: self.sampler_kwargs = dwave_sampler_kwargs else: self.sampler_kwargs = dict() elif dwave_sampler == 'SA': self.dwave_solver = SimulatedAnnealingSampler() if num_reads: self.sampler_kwargs = {'num_reads': num_reads} else: self.sampler_kwargs = {'num_reads': 25} elif dwave_sampler == 'Tabu': self.dwave_solver = TabuSampler() if num_reads: self.sampler_kwargs = {'num_reads': num_reads} else: self.sampler_kwargs = {'num_reads': 250} self.stopwatch = 0 if experiment_type == 'time_lim': self.n_iters = 1000 self.time_limit = 30 if experiment_type == 'iter_lim' and num_iters: self.n_iters = num_iters self.time_limit = False else: self.n_iters = 50 self.time_limit = False self.form_qubo = NewLQUBO(objective_function=self.objective_function) self.solution = self.objective_function.min_v
def test_validation(self): with self.assertRaises(TypeError): HybridRunnable(1, 'ab') with self.assertRaises(ValueError): HybridRunnable(TabuSampler(), None) with self.assertRaises(ValueError): HybridRunnable(TabuSampler(), ('a')) self.assertIsInstance(HybridRunnable(TabuSampler(), 'ab'), HybridRunnable) self.assertIsInstance(HybridRunnable(TabuSampler(), ('a', 'b')), HybridRunnable) self.assertIsInstance(HybridRunnable(TabuSampler(), ['a', 'b']), HybridRunnable)
def test_runnable_composition(self): runnable = IdentityDecomposer() | HybridSubproblemRunnable( TabuSampler()) | IdentityComposer() response = runnable.run(self.init_state) self.assertIsInstance(response, concurrent.futures.Future) self.assertEqual(response.result().samples.record[0].energy, -3.0)
def test_subproblem_sampler_runnable(self): runnable = HybridSubproblemRunnable(TabuSampler()) state = self.init_state.updated(subproblem=self.bqm) response = runnable.run(state) self.assertIsInstance(response, concurrent.futures.Future) self.assertEqual(response.result().subsamples.record[0].energy, -3.0)
def solve(self): if (self.useQPU): sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True})) sampleset = sampler.sample_qubo(self.Q, num_reads=self.n_reads, chain_strength=self.chain) elif (self.useNeal): bqm = BinaryQuadraticModel.from_qubo(self.Q, offset=self.offset) sampler = neal.SimulatedAnnealingSampler() sampleset = sampler.sample(bqm, num_reads=self.n_reads, chain_strength=self.chain) elif (self.useHyb): bqm = BinaryQuadraticModel.from_qubo(self.Q, offset=self.offset) sampler = LeapHybridSampler() sampleset = sampler.sample(bqm, num_reads=self.n_reads) else: bqm = BinaryQuadraticModel.from_qubo(self.Q, offset=self.offset) sampler = TabuSampler() sampleset = sampler.sample(bqm, num_reads=self.n_reads, chain_strength=self.chain) self.sampleset = sampleset
class TabuProblemSampler(Runnable, traits.ProblemSampler): """A tabu sampler for a binary quadratic problem. Args: num_reads (int, optional, default=1): Number of states (output solutions) to read from the sampler. tenure (int, optional): Tabu tenure, which is the length of the tabu list, or number of recently explored solutions kept in memory. Default is a quarter of the number of problem variables up to a maximum value of 20. timeout (int, optional, default=20): Total running time in milliseconds. Examples: See examples on https://docs.ocean.dwavesys.com/projects/hybrid/en/latest/reference/samplers.html#examples. """ def __init__(self, num_reads=1, tenure=None, timeout=20): super(TabuProblemSampler, self).__init__() self.num_reads = num_reads self.tenure = tenure self.timeout = timeout self.sampler = TabuSampler() def __repr__(self): return ("{self}(num_reads={self.num_reads!r}, " "tenure={self.tenure!r}, " "timeout={self.timeout!r})").format(self=self) def next(self, state): sampleset = self.sampler.sample(state.problem, init_solution=state.samples, tenure=self.tenure, timeout=self.timeout, num_reads=self.num_reads) return state.updated(samples=sampleset)
def _get_sampler(self, profile, solver): "Return a dimod.Sampler object." # Handle built-in software samplers as special cases. info = {} if solver != None: info["solver_name"] = solver if solver == "exact": return ExactSolver(), info elif solver == "neal": return SimulatedAnnealingSampler(), info elif solver == "tabu": return TabuSampler(), info # In the common case, read the configuration file, either the # default or the one named by the DWAVE_CONFIG_FILE environment # variable. if profile != None: info["profile"] = profile try: with Client.from_config(profile=profile) as client: if solver == None: solver = client.default_solver else: solver = {"name": solver} sampler = DWaveSampler(profile=profile, solver=solver) info = { "solver_name": sampler.solver.name, "endpoint": client.endpoint } return sampler, info except Exception as err: self.qmasm.abend("Failed to construct a sampler (%s)" % str(err))
def binary_clustering(feature_vecs, feature_index, **kwargs): h = {} J = {} cluster1 = [] #stores the indices for the first cluster cluster2 = [] #stores the indices for the second cluster #will recognize tabu or hybrid if 'sampler' in kwargs: sampler_type = kwargs['sampler'] else: sampler_type = "tabu" if 'time_limit' in kwargs: time_limit = kwargs['time_limit'] else: time_limit = 20 sampler = TabuSampler() sampler1 = LeapHybridSampler() for i in feature_index: for j in feature_index: if i < j: J[(i, j)] = np.linalg.norm(feature_vecs[i] - feature_vecs[j]) #Now use a sampler to solve it if sampler_type == "tabu": print("Choosing TABU sampler") sampler = TabuSampler() sampleset = sampler.sample_ising(h, J, num_reads=1, timeout=time_limit * 1000) bin_cluster = sampleset.first[0] else: print("Choosing the hybrid sampler") sampler1 = LeapHybridSampler() sampleset = sampler1.sample_ising(h, J, time_limit=time_limit) bin_cluster = sampleset.first[0] # Run the problem on the sampler and print the results for key in bin_cluster: #put in cluster 1 if -1, else 2 if bin_cluster[key] == -1: cluster1.append(key) elif bin_cluster[key] == 1: cluster2.append(key) return cluster1, cluster2
def sample_bqm(self, sapi_problem_id, time_limit): #Workaround until TabuSampler supports C BQMs bqm = dimod.BQM(sapi_problem_id.linear, sapi_problem_id.quadratic, sapi_problem_id.offset, sapi_problem_id.vartype) result = TabuSampler().sample(bqm, timeout=1000 * int(time_limit)) future = dwave.cloud.computation.Future('fake_solver', None) future._result = {'sampleset': result, 'problem_type': 'bqm'} return future
def test_dense_schedule(self): # jobs = {'small1': [(1, 1), (0, 2)], # 'small2': [(2, 2), (0, 1)], # 'longJob': [(0, 1), (1, 1), (2, 1)]} # max_time = 4 jobs = { "j0": [(1, 2), (2, 2), (3, 2)], "j1": [(3, 4), (2, 1), (1, 1)], "j2": [(2, 2), (1, 3), (2, 1)] } max_time = 7 # Get JSS BQM scheduler = JobShopScheduler(jobs, max_time) bqm = scheduler.get_bqm() # Expected solution expected = { "j0_0,0": 1, "j0_1,2": 1, "j0_2,4": 1, "j1_0,0": 1, "j1_1,4": 1, "j1_2,5": 1, "j2_0,0": 1, "j2_1,2": 1, "j2_2,5": 1 } fill_with_zeros(expected, jobs, max_time) expected_energy = get_energy(expected, bqm) # Sampled solution # response = EmbeddingComposite(DWaveSampler()).sample(bqm, num_reads=10000) # response_sample, sample_energy, _, _ = next(response.data()) # response = SimulatedAnnealingSampler().sample(bqm, num_reads=2000, beta_range=[0.01, 10]) response = TabuSampler().sample(bqm, num_reads=2000) response_sample, sample_energy, _ = next(response.data()) # Check response sample self.assertTrue(scheduler.csp.check(response_sample)) self.assertEqual(expected_energy, sample_energy) self.compare(response_sample, expected)
class TabuProblemSampler(traits.ProblemSampler, traits.SISO, Runnable): """A tabu sampler for a binary quadratic problem. Args: num_reads (int, optional, default=len(state.samples) or 1): Number of states (output solutions) to read from the sampler. tenure (int, optional): Tabu tenure, which is the length of the tabu list, or number of recently explored solutions kept in memory. Default is a quarter of the number of problem variables up to a maximum value of 20. timeout (int, optional, default=100): Total running time in milliseconds. initial_states_generator (str, 'none'/'tile'/'random', optional, default='random'): Defines the expansion of input state samples into `initial_states` for the Tabu search, if fewer than `num_reads` samples are present. See :meth:`~tabu.TabuSampler.sample`. See :ref:`samplers-examples`. """ def __init__(self, num_reads=None, tenure=None, timeout=100, initial_states_generator='random', **runopts): super(TabuProblemSampler, self).__init__(**runopts) self.num_reads = num_reads self.tenure = tenure self.timeout = timeout self.initial_states_generator = initial_states_generator self.sampler = TabuSampler() def __repr__(self): return ("{self}(num_reads={self.num_reads!r}, " "tenure={self.tenure!r}, " "timeout={self.timeout!r}, " "initial_states_generator={self.initial_states_generator!r})" ).format(self=self) def next(self, state, **runopts): sampleset = self.sampler.sample( state.problem, initial_states=state.samples, initial_states_generator=self.initial_states_generator, tenure=self.tenure, timeout=self.timeout, num_reads=self.num_reads) return state.updated(samples=sampleset)
def get_sampler(self, profile, solver): "Return a dimod.Sampler object and associated solver information." # Handle built-in software samplers as special cases. info = {} if solver != None: info["solver_name"] = solver if solver == "exact": return ExactSolver(), info, {} elif solver == "neal": return SimulatedAnnealingSampler(), info, {} elif solver == "tabu": return TabuSampler(), info, {} elif solver == "kerberos" or (solver != None and solver[:9] == "kerberos,"): base_sampler = KerberosSampler() try: sub_sampler_name = solver.split(",")[1] except IndexError: sub_sampler_name = None sub_sampler, sub_info, params = self.get_sampler_from_config( profile, sub_sampler_name, "qpu") info.update(self._recursive_properties(sub_sampler)) info["solver_name"] = "kerberos + %s" % sub_info["solver_name"] params["qpu_sampler"] = sub_sampler return base_sampler, info, params elif solver == "qbsolv" or (solver != None and solver[:7] == "qbsolv,"): base_sampler = QBSolv() try: sub_sampler_name = solver.split(",")[1] except IndexError: sub_sampler_name = None sub_sampler, sub_info, params = self.get_sampler( profile, sub_sampler_name) if getattr(sub_sampler, "structure", None) != None: sub_sampler = EmbeddingComposite(sub_sampler) info.update(self._recursive_properties(sub_sampler)) info["solver_name"] = "QBSolv + %s" % sub_info["solver_name"] params["solver"] = sub_sampler return base_sampler, info, params # In the common case, read the configuration file, either the # default or the one named by the DWAVE_CONFIG_FILE environment # variable. return self.get_sampler_from_config(profile, solver)
def solve(self, useQPU=False, useNeal=False, useHyb=True, time_limit = 10, num_reads = 100, chain_strength = 10000): Q = self.Q BQM_offset = 0 # TODO: Use the accumulated quadratic constants from the constraints bqm = BinaryQuadraticModel.from_qubo(Q, offset=BQM_offset) self.sampleset = None # Call the requested solver if ( useQPU ): print("Solving using the DWaveSampler on the QPU...") sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True})) sampleset = sampler.sample_qubo(Q, num_reads=num_reads,chain_strength = chain_strength) elif ( useHyb ): print("Solving using the LeapHybridSolver...") sampler = LeapHybridSampler() sampleset = sampler.sample(bqm, time_limit = time_limit) elif ( useNeal ): print("Solving using the SimulatedAnnealing...") sampler = neal.SimulatedAnnealingSampler() sampleset = sampler.sample(bqm, num_reads = num_reads) else: print("Solving using the TabuSampler...") sampler = TabuSampler() sampleset = sampler.sample(bqm, num_reads = num_reads) self.sampleset = sampleset count = 0 for res in self.sampleset.data(): count += 1 return (count)
#make sure D-wave API and config works from dwave.system import EmbeddingComposite, DWaveSampler from tabu import TabuSampler # Define the problem as two Python dictionaries: # h for linear terms, J for quadratic terms h = {} J = {(0, 1): 1, (1, 2): 2, (0, 2): 2.5} # Define the sampler that will be used to run the problem #sampler = EmbeddingComposite(DWaveSampler()) sampler = TabuSampler() # Run the problem on the sampler and print the results sampleset = sampler.sample_ising(h, J, num_reads=10) print(sampleset) tree.create_node("Harry", "harry") # root node tree.create_node("Jane", "jane", parent="harry") tree.create_node("Bill", "bill", parent="harry") tree.create_node("Diane", "diane", parent="jane") tree.create_node("Mary", "mary", parent="diane") tree.create_node("Mark", "mark", parent="jane") tree.show()
) # == INPUT CONFIG # whether or not to add missing doublets to the input add_missing = True # == RUN CONFIG model_class = QallseD0 # model class to use extra_config = dict() # configuration arguments overriding the defaults #: FIXME experimental pegasus setup P6 = dnx.pegasus_graph(-100, nice_coordinates=True) classical_sampler = neal.SimulatedAnnealingSampler() tabu_sampler = TabuSampler() #sampler = dimod.StructureComposite(classical_sampler, P6.nodes, P6.edges) sampler = dimod.StructureComposite(tabu_sampler, P6.nodes, P6.edges) tempdir = tempfile.TemporaryDirectory() print(f'using {tempdir.name}') metas, path = create_dataset(output_path=tempdir.name, random_seed=240834351, gen_doublets=True, **dsmaker_config) #path = '/tmp/hpt-collapse/ds10/event000001000' with open(path + '-meta.json') as f: print(f.read())
def __init__(self, num_reads=1, tenure=None, timeout=20, **runopts): super(TabuSubproblemSampler, self).__init__(**runopts) self.num_reads = num_reads self.tenure = tenure self.timeout = timeout self.sampler = TabuSampler()
def __init__(self, num_reads=None, num_trials=None): self.domain = ['4', '6', '8', '10', '12', '14', '16', '18', '20'] objective_functions = [] for size in self.domain: objective_functions.append( QAPObjectiveFunction(dat_file='had' + size + '.dat')) if num_reads: self.num_reads = num_reads else: self.num_reads = 100 sampler_kwargs = {'num_reads': self.num_reads} if num_trials: num_trials = num_trials else: num_trials = 100 dwave_solver = TabuSampler() self.data = { 'average': [], 'standard deviation': [], 'domain': self.domain, 'domain with QUBO size': [] } for objective_function in objective_functions: n_qap = objective_function.n s = SortingNetwork(n_qap) p = PermutationNetwork(n_qap) if s.depth <= p.depth: network = s else: network = p self.data['domain with QUBO size'].append('{} ({})'.format( n_qap, network.depth)) unique_bin_val = [] for trial in range(num_trials): binary_vals = [] q = np.random.randint(0, 2, size=network.depth) qubo = LQUBO(objective_function=objective_function, switch_network=network, num_activation_vectors=network.depth) formed_qubo = qubo.form_lqubo(q=q)[0] response = dwave_solver.sample_qubo(formed_qubo, **sampler_kwargs) reads = response.record for read in reads: for num_occurrence in range(read[2]): binary_vals.append(read[0]) num_unique_binary = 0 while len(binary_vals) != 0: num_unique_binary += 1 delta_q = binary_vals[0] binary_vals = remove_redundant_binaries( binary_list=binary_vals, delta_switch=delta_q) unique_bin_val.append(num_unique_binary) self.data['average'].append(stat.mean(unique_bin_val)) self.data['standard deviation'].append(stat.stdev(unique_bin_val))
f0 = {**f1, **f2} print( '# of nodes, edges, variables, fixed 1, 2 & total, energy, node with no inedge, multi inedges, no outedges, multi outedges, cycles' ) print(G.number_of_nodes(), G.number_of_edges(), bqm.num_variables, len(f1), len(f2), len(f0), end=' ') # Choose one of the solvers below. #sampler = SimulatedAnnealingSampler() sampler = TabuSampler() #sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True, 'postprocess': 'sampling'})) #sampler = LeapHybridSampler() # Conduct optimization sampleset = sampler.sample(bqm) print(sampleset.first.energy, end=' ') # Summarize the results on the graph GS = sample_graph(G, b, f0, sampleset.first.sample) # Report violations rep = report_graph(GS, G) print(' '.join(str(x) for x in rep), end=' ')
def show_if_works(sampler): qubo = {(0, 0): -1, (0, 1): 2, (1, 1): -1} embedding = {0: [0], 1: [1]} composite = StructureComposite(sampler, [0, 1], [(0, 1)]) fixed = FixedEmbeddingComposite(composite, embedding) print("\n\n") #test standard -> should deliver 100 samples print(fixed.sample_qubo(qubo, num_reads=100)) #test special case qbsolv -> should deliver 100 samples also for qbsolv print(fixed.sample_qubo(qubo, num_reads=100, num_repeats=99)) # this should just work show_if_works(SimulatedAnnealingSampler()) # here the number of samples is wrong # # The problem is the naming of the parameter # num_reads vs. num_repeats # # num_repeats in documentation: # num_repeats (int, optional) – Determines the number of times to # repeat the main loop in qbsolv after determining a better sample. # Default 50. show_if_works(QBSolv()) # this will throw an error show_if_works(TabuSampler())
def test_generic(self): runnable = HybridRunnable(TabuSampler(), fields=('problem', 'samples')) response = runnable.run(self.init_state) self.assertIsInstance(response, concurrent.futures.Future) self.assertEqual(response.result().samples.record[0].energy, -3.0)
def __init__(self, objective_function=None, dwave_sampler=None, dwave_sampler_kwargs=None, num_activation_vectors=None, activation_vec_hamming_dist=1, max_hd=None, parse_samples=True, experiment_type=None, num_reads=None, num_iters=None, network_type='minimum'): super().__init__(objective_function=objective_function) # Initialize switch network: # The default behavior here is to choose the smaller of either permutation or # sorting networks for the given input size. self.n_obj = self.objective_function.n if network_type == 'sorting': self.network = SortingNetwork(self.n_obj) elif network_type == 'permutation': self.network = PermutationNetwork(self.n_obj) elif network_type == 'minimum': s = SortingNetwork(self.n_obj) p = PermutationNetwork(self.n_obj) if s.depth <= p.depth: self.network = s else: self.network = p else: raise TypeError('Network type {} not recognized'.format(str(network_type))) self.n_qubo = self.network.depth self.dwave_solver = None self.sampler_kwargs = None self.qpu = False # Initialize dwave sampler: if dwave_sampler == 'QPU': self.dwave_solver = EmbeddingComposite(DWaveSampler()) self.qpu = True if dwave_sampler_kwargs: self.sampler_kwargs = dwave_sampler_kwargs else: self.sampler_kwargs = dict() elif dwave_sampler == 'SA': self.dwave_solver = SimulatedAnnealingSampler() if num_reads: self.sampler_kwargs = { 'num_reads': num_reads } else: self.sampler_kwargs = { 'num_reads': 25 } elif dwave_sampler == 'Tabu': self.dwave_solver = TabuSampler() if num_reads: self.sampler_kwargs = { 'num_reads': num_reads } else: self.sampler_kwargs = { 'num_reads': 250 } self.stopwatch = 0 # Initialize type of experiment # When running a timed experiment there is a high number of iterations and a 30 sec wall clock # When running a iteration experiment there is a iteration limit of 30 and no wall clock if experiment_type == 'time_lim': self.n_iters = 1000 self.time_limit = 30 if experiment_type == 'iter_lim' and num_iters: self.n_iters = num_iters self.time_limit = False else: self.n_iters = 50 self.time_limit = False if max_hd: self.max_hd = max_hd else: self.max_hd = 0 if num_activation_vectors: self.num_activation_vec = num_activation_vectors else: self.num_activation_vec = self.n_qubo self.form_qubo = LQUBO(objective_function=self.objective_function, switch_network=self.network, max_hamming_dist=self.max_hd, num_activation_vectors=self.num_activation_vec, activation_vec_hamming_dist=activation_vec_hamming_dist) self.solution = self.objective_function.min_v if parse_samples: self.selection = CheckAndSelect else: self.selection = Select
def __init__(self, num_reads=1, tenure=None, timeout=20): super(TabuProblemSampler, self).__init__() self.num_reads = num_reads self.tenure = tenure self.timeout = timeout self.sampler = TabuSampler()
class PopulationLQUBOSolver(Solver): """ The Local-QUBO Solver uses a switch/permutation network to encode the QAP permutation in a bitstring. """ def __init__(self, objective_function=None, dwave_sampler=None, dwave_sampler_kwargs=None, experiment_type=None, population_size=1, num_reads=1, num_iters=None): super().__init__(objective_function=objective_function) self.n_obj = self.objective_function.n self.n_qubo = self.n_obj - 1 self.dwave_solver = None self.sampler_kwargs = None self.qpu = False self.population_size = population_size self.num_reads = num_reads # Initialize dwave sampler: if dwave_sampler == 'QPU': self.dwave_solver = EmbeddingComposite(DWaveSampler()) self.qpu = True if dwave_sampler_kwargs: self.sampler_kwargs = dwave_sampler_kwargs else: self.sampler_kwargs = dict() elif dwave_sampler == 'SA': self.dwave_solver = SimulatedAnnealingSampler() if num_reads: self.sampler_kwargs = {'num_reads': num_reads} else: self.sampler_kwargs = {'num_reads': 25} elif dwave_sampler == 'Tabu': self.dwave_solver = TabuSampler() if num_reads: self.sampler_kwargs = {'num_reads': num_reads} else: self.sampler_kwargs = {'num_reads': 250} self.stopwatch = 0 if experiment_type == 'time_lim': self.n_iters = 1000 self.time_limit = 30 if experiment_type == 'iter_lim' and num_iters: self.n_iters = num_iters self.time_limit = False else: self.n_iters = 50 self.time_limit = False self.form_qubo = NewLQUBO(objective_function=self.objective_function) self.solution = self.objective_function.min_v def minimize_objective(self): start_code = time.time() population = initialize_population( population_size=self.population_size, n_obj=self.n_obj) evaluated_fitness = evaluate_fitness( population=population, objective_function=self.objective_function) max_fit = max_fitness(fitness_array=evaluated_fitness) min_fit = min_fitness(fitness_array=evaluated_fitness) avg_fit = avg_fitness(fitness_array=evaluated_fitness) data_dict = dict() data_dict['max_fitness'] = [max_fit] data_dict['min_fitness'] = [min_fit] data_dict['avg_fitness'] = [avg_fit] data_dict['population'] = [population] form_lqubo_timing = [] solve_lqubo_timing = [] # Initialize bitstring begin_loop = time.time() self.stopwatch = begin_loop - start_code for iteration in range(self.n_iters): # If there is a timing limit and the stopwatch is greater than the timing limit then break if self.time_limit and self.time_limit <= self.stopwatch: break start_iteration = time.time() total_lqubo_population = [] for perm in population: start_form_lqubo = time.time() lqubo = self.form_qubo.form_lqubo(p=perm) end_form_lqubo = time.time() form_lqubo_timing.append(end_form_lqubo - start_form_lqubo) # Solve the LQUBO for new permutations if self.qpu: self.sampler_kwargs.update({ 'chain_strength': 1.5 * abs(max(lqubo.values(), key=abs)), 'num_reads': 1000 }) start_solve_lqubo = time.time() response = self.dwave_solver.sample_qubo( lqubo, **self.sampler_kwargs) end_solve_lqubo = time.time() solve_lqubo_timing.append(end_solve_lqubo - start_solve_lqubo) lqubo_population = CollectLQUBOPopulation( objective_function=self.objective_function, response_record=response.record, current_perm=perm).collect_population() total_lqubo_population += lqubo_population tournament_selection = BestFitPopulation( final_population_size=self.population_size, lqubo_population=total_lqubo_population, previous_population=population, objective_function=self.objective_function) # Compile new population from tournament selection population = tournament_selection.return_population() evaluated_fitness = evaluate_fitness( population=population, objective_function=self.objective_function) max_fit = max_fitness(fitness_array=evaluated_fitness) min_fit = min_fitness(fitness_array=evaluated_fitness) avg_fit = avg_fitness(fitness_array=evaluated_fitness) data_dict['max_fitness'].append(max_fit) data_dict['min_fitness'].append(min_fit) data_dict['avg_fitness'].append(avg_fit) data_dict['population'].append(population) end_iteration = time.time() self.stopwatch += end_iteration - start_iteration end_code = time.time() timing_code = end_code - start_code average_form_lqubo = np.average(form_lqubo_timing) average_solve_lqubo = np.average(solve_lqubo_timing) lqubo_ans = min(data_dict['max_fitness']) num_iters = len(data_dict['max_fitness']) - 1 if lqubo_ans == self.solution: obtain_optimal = 1 percent_error = 0 else: percent_error = abs(self.solution - lqubo_ans) / self.solution * 100 obtain_optimal = 0 return lqubo_ans, percent_error, obtain_optimal, timing_code, num_iters, data_dict, data_dict['max_fitness'], \ average_form_lqubo, average_solve_lqubo, data_dict, data_dict['avg_fitness'], data_dict['min_fitness']
class LocalQUBOIterativeSolver(Solver): """ The Local-QUBO Solver uses a switch/permutation network to encode the QAP permutation in a bitstring. """ def __init__(self, objective_function=None, dwave_sampler=None, dwave_sampler_kwargs=None, num_activation_vectors=None, activation_vec_hamming_dist=1, max_hd=None, parse_samples=True, experiment_type=None, num_reads=None, num_iters=None, network_type='minimum'): super().__init__(objective_function=objective_function) # Initialize switch network: # The default behavior here is to choose the smaller of either permutation or # sorting networks for the given input size. self.n_obj = self.objective_function.n if network_type == 'sorting': self.network = SortingNetwork(self.n_obj) elif network_type == 'permutation': self.network = PermutationNetwork(self.n_obj) elif network_type == 'minimum': s = SortingNetwork(self.n_obj) p = PermutationNetwork(self.n_obj) if s.depth <= p.depth: self.network = s else: self.network = p else: raise TypeError('Network type {} not recognized'.format(str(network_type))) self.n_qubo = self.network.depth self.dwave_solver = None self.sampler_kwargs = None self.qpu = False # Initialize dwave sampler: if dwave_sampler == 'QPU': self.dwave_solver = EmbeddingComposite(DWaveSampler()) self.qpu = True if dwave_sampler_kwargs: self.sampler_kwargs = dwave_sampler_kwargs else: self.sampler_kwargs = dict() elif dwave_sampler == 'SA': self.dwave_solver = SimulatedAnnealingSampler() if num_reads: self.sampler_kwargs = { 'num_reads': num_reads } else: self.sampler_kwargs = { 'num_reads': 25 } elif dwave_sampler == 'Tabu': self.dwave_solver = TabuSampler() if num_reads: self.sampler_kwargs = { 'num_reads': num_reads } else: self.sampler_kwargs = { 'num_reads': 250 } self.stopwatch = 0 # Initialize type of experiment # When running a timed experiment there is a high number of iterations and a 30 sec wall clock # When running a iteration experiment there is a iteration limit of 30 and no wall clock if experiment_type == 'time_lim': self.n_iters = 1000 self.time_limit = 30 if experiment_type == 'iter_lim' and num_iters: self.n_iters = num_iters self.time_limit = False else: self.n_iters = 50 self.time_limit = False if max_hd: self.max_hd = max_hd else: self.max_hd = 0 if num_activation_vectors: self.num_activation_vec = num_activation_vectors else: self.num_activation_vec = self.n_qubo self.form_qubo = LQUBO(objective_function=self.objective_function, switch_network=self.network, max_hamming_dist=self.max_hd, num_activation_vectors=self.num_activation_vec, activation_vec_hamming_dist=activation_vec_hamming_dist) self.solution = self.objective_function.min_v if parse_samples: self.selection = CheckAndSelect else: self.selection = Select def minimize_objective(self): start_code = time.time() q = np.random.randint(0, 2, size=self.n_qubo) p = self.network.permute(q) v = self.objective_function(p) delta_q = None data_dict = dict() data_dict['q_vec'] = [q] data_dict['p_vec'] = [p] data_dict['v_vec'] = [v] data_dict['delta_q_vec'] = [['random switch setting']] # Initialize bitstring begin_loop = time.time() self.stopwatch = begin_loop - start_code for iteration in range(self.n_iters): # If there is a timing limit and the stopwatch is greater than the timing limit then break if self.time_limit and self.time_limit <= self.stopwatch: break start_iteration = time.time() # Build the Local QUBO by creating all delta_q's that are hamming distance 2 # from the current q. For each of those, the new q gives a permutation (via # the network encoding) and hence a new objective function value. The deltas # in the objective function values are what populate the qubo. qubo = self.form_qubo.form_lqubo(q=q)[0] delta_q_basis = self.form_qubo.form_lqubo(q=q)[1] # Solve the QUBO for delta_q if self.qpu: self.sampler_kwargs.update({ 'chain_strength': 1.5*abs(max(qubo.values(), key=abs)), 'num_reads': 1000 }) retries = 10 while retries > 0: try: response = self.dwave_solver.sample_qubo(qubo, **self.sampler_kwargs) select_response = self.selection(objective_function=self.objective_function, switch_network=self.network, response_record=response.record, delta_q_basis=delta_q_basis, data_dict_qvecs=data_dict['q_vec'], current_q=q).select() q = select_response[0] p = select_response[1] v = select_response[2] delta_q = select_response[3] break except ValueError: print('retrying QUBO...') retries -= 1 if retries == 0: q = np.random.randint(0, 2, size=self.n_qubo) p = self.network.permute(q) v = self.objective_function(p) delta_q = None data_dict['q_vec'] = [q] data_dict['p_vec'] = [p] data_dict['v_vec'] = [v] data_dict['delta_q_vec'] = [['random switch setting']] data_dict['q_vec'].append(q) data_dict['p_vec'].append(p) data_dict['v_vec'].append(v) data_dict['delta_q_vec'].append(delta_q) end_iteration = time.time() self.stopwatch += end_iteration - start_iteration end_code = time.time() timing_code = end_code - start_code lqubo_ans = min(data_dict['v_vec']) num_iters = len(data_dict['v_vec']) - 1 if lqubo_ans == self.solution: obtain_optimal = 1 percent_error = 0 else: percent_error = abs(self.solution - lqubo_ans) / self.solution * 100 obtain_optimal = 0 return lqubo_ans, percent_error, obtain_optimal, timing_code, num_iters, data_dict, data_dict['v_vec']
def solve(self, R, qubo, samples, exact, verbose, useQPU, useHyb, useNeal, useTabu): use_QUBO = qubo # We obtain the calculations performed at load time c_coeffs = self.get_qubo_coeffs(R) c_a = c_coeffs['c_a'] c_b = c_coeffs['c_b'] c_c = c_coeffs['c_c'] a1 = c_coeffs['a1'] a2 = c_coeffs['a2'] a3 = c_coeffs['a3'] g_values = self.get_g_values(R) g0 = g_values['g0'] g1 = g_values['g1'] g2 = g_values['g2'] g3 = g_values['g3'] g4 = g_values['g4'] e = g_values['e'] g3_addition = g_values['g3add'] # Solve the equation. First solution is lowest energy if use_QUBO: #Using QUBO Q = defaultdict(float) Q[0, 0] = c_a Q[0, 1] = c_b Q[1, 0] = c_b Q[1, 1] = c_a #Q = [(2 * a2 - 2 * a3, 2 * a3),(2 * a3,2 * a2 - 2 * a3 )] offset = 0 if (useQPU): chain_strength = 4 if (verbose == True): print("Solving using the DWaveSampler on the QPU...") sampler = EmbeddingComposite( DWaveSampler(solver={'qpu': True})) sampleset = sampler.sample_qubo(Q, num_reads=samples, chain_strength=chain_strength) elif (useHyb): if (verbose == True): print("Solving using the LeapHybridSolver...") time_limit = 3 bqm = BinaryQuadraticModel.from_qubo(Q, offset=offset) sampler = LeapHybridSampler() sampleset = sampler.sample(bqm, time_limit=time_limit) elif (useNeal): if (verbose == True): print("Solving using the Leap SimulatedAnnealing...") bqm = BinaryQuadraticModel.from_qubo(Q, offset=offset) sampler = neal.SimulatedAnnealingSampler() sampleset = sampler.sample(bqm, num_reads=samples) else: if (verbose == True): print("Solving using the TabuSampler...") sampler = TabuSampler() bqm = BinaryQuadraticModel.from_qubo(Q, offset=offset) sampleset = sampler.sample(bqm, num_reads=samples) if (verbose == True): print(sampleset.first.sample) if (verbose == True): print(sampleset) # Step 3: Get x0 and x1 for first energy result for set in sampleset.data(): x0 = set.sample[0] x1 = set.sample[1] energy = set.energy if (verbose == True): print("x0,x1,ener : ", x0, x1, energy) break H_b = self.get_energy_from_binary_spins(R, x0, x1) Y = 4 * x0 * x1 + (2 * a2 - 2 * a3) * x0 + ( 2 * a2 - 2 * a3) * x1 + a3 - 2 * a2 + a1 # convert x0,x1 to ising spins sz0 = (2 * x0) - 1 sz1 = (2 * x1) - 1 else: # Using SPIN (ising): H = h_1 * s_1 + h_2 * s_2 + J_{1,2} * s_1 *s_2 sampler = TabuSampler() response = sampler.sample_ising({ 'a': c_a, 'b': c_a }, {('a', 'b'): c_b}, num_reads=samples) if (verbose == True): print(response) for set in response.data(): sz0 = set.sample['a'] sz1 = set.sample['b'] energy = set.energy if (verbose == True): print("sz0,sz1,ener : ", sz0, sz1, energy) break H_b = self.get_energy_from_ising_spins(R, sz0, sz1) # Step 4: Calculate Y = ( a1 + a2( sz0 + sz1 ) + a3 (sz0*sz1)) Y = (a1 + a2 * (sz0 + sz1) + a3 * (sz0 * sz1)) # Convert to get x0,x1 x0 = (sz0 + 1) / 2 x1 = (sz1 + 1) / 2 # Get hx1 and hx2 in : # hx**2 + 2*g3*hx = Y # a = 1, b = 2g3, c = -Y a = 1 b = 2 * g3 c = -Y #print("a,b,c,b**2-4*a*c : ", a,b,c,b**2-4*a*c) # Solve H1 for x (minimum of the two possibilities) hx1 = (-b + np.sqrt(b**2 - 4 * a * c)) / (2 * a) hx2 = (-b - np.sqrt(b**2 - 4 * a * c)) / (2 * a) if (hx2 < hx1): swp = hx2 hx2 = hx1 hx1 = swp # Add g3_addition to hx1 hx1 += g3_addition H0_ver = (g1 * sz0) + (g2 * sz1) + (g3 * sz0 * sz1) H0 = hx1 H = H0 + g0 assert (H_b == H) return (H)