class SteepestDescentProblemSampler(traits.ProblemSampler, traits.SISO, Runnable): """A steepest descent solver for a complete problem. Args: num_reads (int, optional, default=len(state.samples) or 1): Number of states (output solutions) to read from the sampler. initial_states_generator (str, 'none'/'tile'/'random', optional, default='random'): Defines the expansion of input state samples into `initial_states` for the steepest descent, if fewer than `num_reads` samples are present. See :meth:`greedy.sampler.SteepestDescentSolver.sample`. """ def __init__(self, num_reads=None, initial_states_generator='random', **runopts): super(SteepestDescentProblemSampler, self).__init__(**runopts) self.num_reads = num_reads self.initial_states_generator = initial_states_generator self.sampler = SimulatedAnnealingSampler() def __repr__(self): return ("{self}(num_reads={self.num_reads!r}, " "initial_states_generator={self.initial_states_generator!r})" ).format(self=self) def next(self, state, **runopts): samples = self.sampler.sample( state.problem, num_reads=self.num_reads, initial_states=state.samples, initial_states_generator=self.initial_states_generator) return state.updated(samples=samples)
class SimulatedAnnealingSubproblemSampler(Runnable, traits.SubproblemSampler): """A simulated annealing sampler for a subproblem. Args: num_reads (int, optional, default=1): Number of states (output solutions) to read from the sampler. sweeps (int, optional, default=1000): Number of sweeps or steps. Examples: See examples on https://docs.ocean.dwavesys.com/projects/hybrid/en/latest/reference/samplers.html#examples. """ def __init__(self, num_reads=1, sweeps=1000): super(SimulatedAnnealingSubproblemSampler, self).__init__() self.num_reads = num_reads self.sweeps = sweeps self.sampler = SimulatedAnnealingSampler() self._stop_event = threading.Event() def __repr__(self): return ("{self}(num_reads={self.num_reads!r}, " "sweeps={self.sweeps!r})").format(self=self) def next(self, state): subbqm = state.subproblem response = self.sampler.sample( subbqm, num_reads=self.num_reads, sweeps=self.sweeps, interrupt_function=lambda: self._stop_event.is_set()) return state.updated(subsamples=response) def stop(self): self._stop_event.set()
def test_maze_heuristic_response(self): """Small and simple maze to verify that it is possible get a solution. """ # Create maze n_rows = 3 n_cols = 3 start = '0,0n' end = '3,2n' walls = ['1,0n', '2,1n', '2,2n'] maze = Maze(n_rows, n_cols, start, end, walls) bqm = maze.get_bqm() # Sample and test that a response is given sampler = SimulatedAnnealingSampler() response = sampler.sample(bqm, num_reads=1000) response_sample = next(response.samples()) self.assertGreaterEqual(len(response), 1) # Test heuristic response expected_solution = { '0,1w': 1, '1,1n': 1, '1,1w': 1, '2,0n': 1, '2,1w': 1, '2,2w': 1 } fill_with_zeros(expected_solution, n_rows, n_cols, [start, end]) self.compare(response_sample, expected_solution)
class SimulatedAnnealingProblemSampler(Runnable, traits.ProblemSampler): """A simulated annealing sampler for a complete problem. Args: num_reads (int, optional, default=1): Number of states (output solutions) to read from the sampler. sweeps (int, optional, default=1000): Number of sweeps or steps. """ def __init__(self, num_reads=1, sweeps=1000, **runopts): super(SimulatedAnnealingProblemSampler, self).__init__(**runopts) self.num_reads = num_reads self.sweeps = sweeps self.sampler = SimulatedAnnealingSampler() self._stop_event = threading.Event() def __repr__(self): return ("{self}(num_reads={self.num_reads!r}, " "sweeps={self.sweeps!r})").format(self=self) def next(self, state, **runopts): bqm = state.problem response = self.sampler.sample( bqm, num_reads=self.num_reads, sweeps=self.sweeps, interrupt_function=lambda: self._stop_event.is_set()) return state.updated(samples=response) def halt(self): self._stop_event.set()
class SimulatedAnnealingSubproblemSampler(traits.SubproblemSampler, traits.SISO, Runnable): """A simulated annealing sampler for a subproblem. Args: num_reads (int, optional, default=len(state.subsamples) or 1): Number of states (output solutions) to read from the sampler. num_sweeps (int, optional, default=1000): Number of sweeps or steps. beta_range (tuple, optional): A 2-tuple defining the beginning and end of the beta schedule, where beta is the inverse temperature. The schedule is applied linearly in beta. Default range is set based on the total bias associated with each node. beta_schedule_type (string, optional, default='geometric'): Beta schedule type, or how the beta values are interpolated between the given 'beta_range'. Supported values are: linear and geometric. initial_states_generator (str, 'none'/'tile'/'random', optional, default='random'): Defines the expansion of input state subsamples into `initial_states` for the simulated annealing, if fewer than `num_reads` subsamples are present. See :meth:`~neal.SimulatedAnnealingSampler.sample`. See :ref:`samplers-examples`. """ def __init__(self, num_reads=None, num_sweeps=1000, beta_range=None, beta_schedule_type='geometric', initial_states_generator='random', **runopts): super(SimulatedAnnealingSubproblemSampler, self).__init__(**runopts) self.num_reads = num_reads self.num_sweeps = num_sweeps self.beta_range = beta_range self.beta_schedule_type = beta_schedule_type self.initial_states_generator = initial_states_generator self.sampler = SimulatedAnnealingSampler() self._stop_event = threading.Event() def __repr__(self): return ("{self}(num_reads={self.num_reads!r}, " "num_sweeps={self.num_sweeps!r}, " "initial_states_generator={self.initial_states_generator!r})").format(self=self) def next(self, state, **runopts): subsamples = self.sampler.sample( state.subproblem, num_reads=self.num_reads, num_sweeps=self.num_sweeps, beta_range=self.beta_range, beta_schedule_type=self.beta_schedule_type, initial_states=state.subsamples, initial_states_generator=self.initial_states_generator, interrupt_function=lambda: self._stop_event.is_set()) return state.updated(subsamples=subsamples) def halt(self): self._stop_event.set()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from dimod import BinaryQuadraticModel from neal import SimulatedAnnealingSampler sampler = SimulatedAnnealingSampler() x0, x1, y = ('x0', 'x1', 'y') a, b, c = 1, 1, 3 Q = {(y, y): c, (x0, y): -2*b, (x1, y): -2*b, (x0, x1): a, (x0, x0): 0} bqm = BinaryQuadraticModel.from_qubo(Q) response = sampler.sample(bqm, num_reads=5000) results = {} for datum in response.data(['sample', 'energy', 'num_occurrences']): key = (tuple(dict(datum.sample).items()), float(datum.energy)) if key in results: results[key] = (datum.sample, results[key][1] + datum.num_occurrences) else: results[key] = (datum.sample, datum.num_occurrences) num_runs = sum([results[key][1] for key in results]) for key in results: try: print(results[key][0], "Energy: ", key[1], f"Occurrences: {results[key][1]/num_runs*100:.2f}%") except KeyError: pass
class QBM: def __init__(self, hidlen, vislen, sampler="Test"): self.sep = 0 if sampler == "LeapHybridSampler": self.sampler = LeapHybridSampler() #accessing dwave self.sep = 1 if sampler == "DWaveSampler": self.sampler = AutoEmbeddingComposite(DWaveSampler()) if sampler == "Test": self.sampler = SimulatedAnnealingSampler() self.t_step = 1000 self.stepsize = 0.1 self.path = "" self.mute = True self.hidlen = hidlen #handling indexes self.vislen = vislen self.outlen = 10 self.hind = ['h' + str(i) for i in range(self.hidlen)] self.vind = ['v' + str(i) for i in range(self.vislen)] self.ind = self.hind + self.vind self.cmap = [] self.coef = np.zeros( (self.vislen + self.hidlen, self.vislen + self.hidlen), dtype=np.float_) #self.Q = {(i, j): self.coef[i][j] for i in self.ind for j in self.ind} self.bqm = dimod.BinaryQuadraticModel(self.coef, 'SPIN') self.response = 0 #response and data from it self.answerlen = 0 self.answer = [] self.index = [] for i in range(self.hidlen + self.vislen): self.index += [i] self.answer_occ = [] self.answern = 0 self.prob = [] self.top = [0] * 3 self.expected = 0 self.images = [] #images from dataset self.label = 0 self.labels = [] self.chosen_images = [] self.prob = [] self.chosen_prob = [] self.single_unfixed = [] self.double_unfixed = [] self.single_fixed = [] self.double_fixed = [] self.delta = [] self.mean_single = [] def randomize_coef(self): #for premature testing self.read_cmap() for pair in self.cmap: self.coef[pair[0]][pair[1]] = random.randrange(200) / 100 - 1 def read_data(self, train=True): prop = idx2numpy.convert_from_file(self.path + "Data/prop") self.hidlen = prop[0] self.vislen = prop[1] self.outlen = prop[2] self.coef = np.zeros( (self.vislen + self.hidlen, self.vislen + self.hidlen), dtype=np.float_) self.make_bqm() self.read_cmap() if train: self.mean_single = idx2numpy.convert_from_file(self.path + 'Data/single') self.images = idx2numpy.convert_from_file(self.path + 'Data/train') self.data_prob = idx2numpy.convert_from_file(self.path + 'Data/prob') else: self.images = idx2numpy.convert_from_file(self.path + 'Data/test') for i in range(self.hidlen + self.vislen): self.index += [i] '''def read_tests(self): self.mean_single = idx2numpy.convert_from_file("../Data/tests/single") self.images = idx2numpy.convert_from_file("../Data/tests/data") self.chosen_images = self.images''' def read_coef(self, filename="last"): filename = self.path + "Coef/" + filename + ".coef" self.coef = idx2numpy.convert_from_file(filename) def save_coef(self, filename="last"): filename = self.path + "Coef/" + filename + ".coef" idx2numpy.convert_to_file(filename, self.coef) def read_cmap(self): self.cmap = idx2numpy.convert_from_file(self.path + "Data/cmap") #def make_q(self): #question from coefs #self.Q = {(i, j): self.coef[i][j] for i in self.ind for j in self.ind} def make_bqm(self): #bqm from coefs #self.make_q() self.bqm = dimod.BinaryQuadraticModel(self.coef, 'SPIN') def run(self, n=1): #run on dwave self.answern += n self.make_bqm() self.response = self.sampler.sample(self.bqm, num_reads=n) def run_test(self, n=1): self.answern += n self.response = self.sampler.sample(self.bqm, num_reads=n) '''def sim_run(self, n = 100): #run locally (simulation) self.make_bqm() self.answern += n self.response = dimod.SimulatedAnnealingSampler().sample(self.bqm, num_reads = self.answern)''' def fix_h(self, i, val): #fix hidden layer qubit self.bqm.fix_variable(self.hind[i], val) def fix_v(self, i, val): #fix visible layer qubit self.bqm.fix_variable(self.vind[i], val) def fix_image(self, v, out=True): #fix image into bqm if out: ch = self.vislen else: ch = self.viseln - self.outlen for i in range(ch): self.bqm.fix_variable(i + self.hidlen, v[i]) self.index = [] for i in range(self.hidlen): self.index += [i] if not out: for i in range(self.outlen): self.index += [self.hidlen + self.vislen - self.outlen + i] '''def fix_output(self, n): #fix output (0-9) for i in range(self.outlen): if i == n: self.bqm.fix_variable(self.vind[-(self.outlen - i)], 1) else: self.bqm.fix_variable(self.vind[-(self.outlen - i)], 0)''' def fetch_answer(self): #reading response self.answerlen = 0 for datum in self.response.data( fields=['sample', 'energy', 'num_occurrences'], sorted_by='energy'): self.answerlen += 1 self.answer = np.zeros((self.answerlen, self.hidlen + self.vislen), dtype="int8") self.answer_occ = np.zeros(self.answerlen, dtype=np.int32) i = 0 for datum in self.response.data( fields=['sample', 'energy', 'num_occurrences'], sorted_by='energy'): self.answer_occ[i] = datum.num_occurrences for j in self.index: self.answer[i][j] = datum.sample[j] i += 1 def add_answer(self): for datum in self.response.data( fields=['sample', 'energy', 'num_occurrences'], sorted_by='energy'): self.answerlen += 1 for datum in self.response.data( fields=['sample', 'energy', 'num_occurrences'], sorted_by='energy'): self.answer_occ = np.append(self.answer_occ, datum.num_occurrences) ent = np.zeros((1, self.hidlen + self.vislen), dtype=np.int32) for i in self.index: ent[0][i] = datum.sample[i] self.answer = np.concatenate((self.answer, ent), axis=0) def save_answer(self, number="test"): #save data as idx filename1 = self.path + "Resp/" + number + ".samples" filename2 = self.path + "Resp/" + number + ".occs" filename3 = self.path + "Resp/" + number + ".lens" lens = np.zeros((2), dtype="int16") lens[0] = self.hidlen lens[1] = self.vislen idx2numpy.convert_to_file(filename1, self.answer) idx2numpy.convert_to_file(filename2, self.answer_occ) idx2numpy.convert_to_file(filename3, lens) def read_answer(self, number="test"): filename1 = self.path + "Resp/" + number + ".samples" filename2 = self.path + "Resp/" + number + ".occs" '''filename3 = self.path + "Resp/" + number + ".lens" lens = np.zeros((2), dtype = "int16") lens[0] = self.hidlen lens[1] = self.vislen''' self.answer = idx2numpy.convert_from_file(filename1) self.answer_occ = idx2numpy.convert_from_file(filename2) def prepare_answer(self): self.prob = np.zeros((self.answerlen), dtype=np.float_) for ans in range(self.answerlen): for pair in self.cmap: if pair[0] != pair[1]: self.prob[ans] += self.coef[pair[0]][ pair[1]] * self.answer[ans][ pair[0]] * self.answer[ans][pair[1]] else: self.prob[ans] += self.coef[pair[0]][ pair[0]] * self.answer[ans][pair[0]] self.prob = e**(-self.prob) self.prob = self.prob / np.sum(self.prob) '''def calc_single_unfixed(self): if not self.mute: print("Response processing has begun:") self.single_unfixed = np.zeros(self.hidlen + self.vislen, dtype = np.float_) responses = self.answer.transpose() self.single_unfixed = responses.dot(self.prob) if not self.mute: print("Response processing has finished")''' def calc_double_unfixed(self): #self.calc_single_unfixed() self.double_unfixed = np.zeros( (self.hidlen + self.vislen, self.hidlen + self.vislen), dtype=np.float_) for pair in self.cmap: for k in range(self.answerlen): if pair[0] != pair[1]: self.double_unfixed[pair[0]][pair[1]] += self.prob[ k] * self.answer[k][pair[0]] * self.answer[k][pair[1]] else: self.double_unfixed[pair[0]][ pair[0]] += self.prob[k] * self.answer[k][pair[0]] def choose_images(self, n="who gives a f**k"): self.chosen_images = [] self.chosen_prob = self.data_prob n = len(self.images) numbers = random.sample(range(len(self.images)), n) for i in numbers: self.chosen_images += [self.images[i]] def calc_sigma_v(self, v, th=True): state = np.ones((self.vislen + self.hidlen), dtype=np.float_) for i in range(self.vislen): state[self.hidlen + i] = v[i] b_eff = np.zeros(self.vislen + self.hidlen, dtype=np.float_) b_eff = self.coef.dot(state) if th: b_eff = np.tanh(b_eff) return b_eff def calc_single_fixed(self): self.single_fixed = np.zeros(self.vislen + self.hidlen, dtype=np.float_) for n in range(len(self.chosen_images)): self.single_fixed += self.calc_sigma_v( self.chosen_images[n]) * self.chosen_prob[n] def calc_double_fixed(self): if not self.mute: print("Dataset processing has begun:") self.double_fixed = np.zeros( (self.hidlen + self.vislen, self.hidlen + self.vislen), dtype=np.float_) temp = np.zeros((self.hidlen + self.vislen, self.hidlen + self.vislen), dtype=np.float_) image_number = 0 for v in self.chosen_images: vp = np.ones(self.vislen, dtype=np.float_) * -1 for i in range(self.vislen): vp[i] = v[i] if image_number % 4000 == 0: if not self.mute: print("Image: ", image_number, " out of ", len(self.chosen_images), " processed") sigma_v = self.calc_sigma_v(v) for i in range(self.hidlen): for j in range(self.vislen): temp[i][self.hidlen + j] += sigma_v[i] * vp[ j] * self.chosen_prob[image_number] image_number += 1 self.calc_single_fixed() for i in range(self.hidlen): temp[i][i] = self.single_fixed[i] for i in range(self.vislen): temp[self.hidlen + i][self.hidlen + i] = self.mean_single[i] for pair in self.cmap: self.double_fixed[pair[0]][pair[1]] = temp[pair[0]][pair[1]] if not self.mute: print("Dataset processing has finished") def change_coef(self): self.delta = (self.double_fixed - self.double_unfixed) * self.stepsize self.coef = self.coef - self.delta '''max_coef = 0 for pair in self.cmap: if abs(self.coef[pair[0]][pair[1]]) > max_coef: max_coef = abs(self.coef[pair[0]][pair[1]]) self.coef = self.coef / max_coef''' def make_step(self, step): print("Step " + str(step) + " began!") self.read_coef(str(step)) self.make_bqm() if not self.sep: self.run(self.t_step) self.fetch_answer() if not self.mute: print("Got full respose, n = ", self.t_step) else: self.run(1) self.fetch_answer() for i in range(self.t_step - 1): self.run(1) self.add_answer() if (i + 2) % 10 == 0: if not self.mute: print("Got respose ", i + 2, " out of", self.t_step) self.save_answer(str(step)) self.prepare_answer() self.calc_double_unfixed() self.choose_images(len(self.images)) self.calc_double_fixed() self.change_coef() self.save_coef(str(int(step) + 1)) '''div = self.calc_div() print("Calculated ", step, "th divergence:", div)''' print("Step " + str(step) + " complete!") def make_steps(self, n): starting_step = idx2numpy.convert_from_file(self.path + "current_step") new_step = np.zeros((1), dtype=np.int32) for i in range(n): step = starting_step[0] + i self.make_step(step) new_step[0] = step + 1 idx2numpy.convert_to_file(self.path + "current_step", new_step) def calc_pv(self, v, beff=True): b_eff = self.calc_sigma_v(v, False) Energy = 0 for i in range(self.vislen): Energy += v[i] * self.coef[self.hidlen + i][self.hidlen + i] pv = e**(-Energy) if beff: for i in range(self.hidlen): pv = pv * cosh(b_eff[i]) return pv def calc_div(self, beff=True): pvs = [0] * len(self.images) pvsum = 0 pds = self.data_prob i = 0 for image in self.images: pvs[i] = self.calc_pv(image) pvsum += self.calc_pv(image, beff) i += 1 if not self.mute: if i % 2000 == 0: print(i, "th picture") pvs = pvs / pvsum div = 0 i = 0 for image in self.images: div += pds[i] * log(pds[i] / pvs[i]) i += 1 return div def save_div(self, steps): div = np.zeros((steps), dtype=np.float_) for i in range(steps): self.read_coef(str(i)) div[i] = self.calc_div() print("Calculated ", i, "th divergence:", div[i]) idx2numpy.convert_to_file(self.path + "Results/div", div) def find_answer(self, n): mostan = np.zeros((n, self.outlen), dtype=np.float_) if n > len(self.images): n = len(self.images) for im in range(n): for qu in range(self.outlen): out = np.ones((self.outlen), dtype=np.int32) * -1 string = copy.deepcopy(self.images[im]) for i in range(self.outlen): if i != qu: string[self.vislen - self.outlen + i] = -1 else: string[self.vislen - self.outlen + i] = 1 self.make_bqm() self.fix_image(string) self.run_test(self.t_step) top = 1 for datum in self.response.data( fields=['sample', 'energy', 'num_occurrences'], sorted_by='energy'): if top: energy = datum.energy top = 0 mostan[im][qu] = e**(-energy) mostan[im] = mostan[im] / np.sum(mostan[im]) print(mostan[im]) return mostan
print(f"Our set S is {arr}") H = 0 for i in range(len(arr)): H += Spin(f'x_{i}') * arr[i] H *= H model = H.compile() bqm = model.to_bqm() # we need pyqubo>=1.0.0 if not USE_SIMULATOR: sampler = DWaveSampler() embedded = EmbeddingComposite(sampler) print("embedding and sampling...") sampleset = embedded.sample(bqm, num_reads=100) backup("num partitioning arr", "Chimera", arr) backup("num partitioning", "Chimera", sampleset) else: simulator = SimulatedAnnealingSampler() sampleset = simulator.sample(bqm) decoded_samples = model.decode_sampleset(sampleset) decoded_samples = model.decode_sampleset(sampleset) best = min(decoded_samples, key=lambda x: x.energy) # decision version of the partitioning problemm: does there exist a partition? print(best.energy == 0) # how "far away" are we? print(best.energy)