def test_logical_model_from_pyqubo_model_with_placeholder(qubo): x = qubo.variables("x", shape=(10, 2)) y = qubo.variables("y", shape=(10, 2)) sum_x = sum(x[i, 0] for i in range(10)) sum_y = sum(y[i, 0] for i in range(10)) hamiltonian = pyqubo.Placeholder("A") * (sum_x - sum_y)**2 + 10.0 pyqubo_model = hamiltonian.compile() qubo.from_pyqubo(pyqubo_model) # We cannot evaluate cofficient values before placeholders are resolved, # so convert it to a physical model. physical = qubo.to_physical({"A": 2.0}) for i in range(10): assert physical._raw_interactions[ constants.INTERACTION_LINEAR][f"x[{i}][0]"] == -2.0 for i in range(10): for j in range(i + 1, 10): assert physical._raw_interactions[constants.INTERACTION_QUADRATIC][ (f"x[{i}][0]", f"x[{j}][0]")] == -4.0 assert physical._raw_interactions[constants.INTERACTION_QUADRATIC][ (f"y[{i}][0]", f"y[{j}][0]")] == -4.0 assert physical._raw_interactions[constants.INTERACTION_QUADRATIC][ (f"x[{i}][0]", f"y[{j}][0]")] == 4.0 assert physical.get_offset() == 10.0
def TSPHamiltonian(citiesSize: int, pathsWeight: nptyping.Array[int]): if pathsWeightChecker(citiesSize, pathsWeight): pass else: sys.exit() timeSteps = citiesSize x = pyqubo.Array.create("x", (citiesSize - 1, citiesSize - 1), "BINARY") # goal -> start costHamiltonian = pyqubo.Sum(0, citiesSize - 1, lambda start: pathsWeight[citiesSize - 1, start] * x[start][0]) # on the way costHamiltonian += pyqubo.Sum( 0, timeSteps - 2, lambda time: pyqubo.Sum( 0, citiesSize - 2, lambda i: pyqubo.Sum(i + 1, citiesSize - 1, lambda j: pathsWeight[i, j] * x[i][time] * x[j][time + 1]), ), ) # on the way -> goal costHamiltonian += pyqubo.Sum(0, citiesSize - 1, lambda j: pathsWeight[j, citiesSize - 1] * x[j][timeSteps - 2]) ## Constrain timeConstrain = pyqubo.Constraint( pyqubo.Sum(0, timeSteps - 1, lambda time: (pyqubo.Sum(0, citiesSize - 1, lambda i: x[i][time]) - 1) ** 2), label="time", ) visitConstrain = pyqubo.Constraint( pyqubo.Sum(0, citiesSize - 1, lambda i: (pyqubo.Sum(0, timeSteps - 1, lambda time: x[i][time]) - 1) ** 2), label="city", ) hamiltonian = ( costHamiltonian + pyqubo.Placeholder("lamTime") * timeConstrain + pyqubo.Placeholder("lamVisit") * visitConstrain ) return hamiltonian
def test_logical_model_to_physical_with_placeholder_qubo(qubo): # Note: This test is needed to test a PhysicalModel whose offset is pyqubo.core.Coefficient a = qubo.variables("a", shape=(4,)) onehot = pyqubo.Constraint((pyqubo.Sum(0, 4, lambda i: a[i]) - 1) ** 2, label="one-hot") hamiltonian = onehot * pyqubo.Placeholder("A") qubo.from_pyqubo(hamiltonian) placeholder = {"A": 2.0} physical = qubo.to_physical(placeholder=placeholder) assert physical._offset == 2.0
def test_logical_model_to_physical_with_placeholder_ising(ising): x = ising.variables("x", shape=(7,)) ising.add_interaction(x[0], coefficient=pyqubo.Placeholder("a")) ising.add_interaction(x[1], coefficient=pyqubo.Placeholder("b") + 1.0) ising.add_interaction(x[2], coefficient=2.0) ising.add_interaction(x[2], name="x[2]-2", coefficient=pyqubo.Placeholder("c")) ising.add_interaction(x[3], coefficient=2 * pyqubo.Placeholder("d") + 3 * pyqubo.Placeholder("e")) ising.add_interaction(x[4], coefficient=pyqubo.Placeholder("f"), scale=3.0) ising.add_interaction(x[5], coefficient=4.0, scale=pyqubo.Placeholder("g")) ising.add_interaction(x[6], coefficient=pyqubo.Placeholder("h"), scale=pyqubo.Placeholder("i") * 5) ising._offset = pyqubo.Placeholder("j") placeholder = {"a": 1.0, "b": 2.0, "c": 3.0, "d": 4.0, "e": -5.0, "f": 6, "g": -7, "h": 8, "i": 9, "j": 10} physical = ising.to_physical(placeholder=placeholder) assert physical._raw_interactions[constants.INTERACTION_LINEAR]["x[0]"] == 1.0 assert physical._raw_interactions[constants.INTERACTION_LINEAR]["x[1]"] == 3.0 assert physical._raw_interactions[constants.INTERACTION_LINEAR]["x[2]"] == 5.0 assert physical._raw_interactions[constants.INTERACTION_LINEAR]["x[3]"] == -7.0 assert physical._raw_interactions[constants.INTERACTION_LINEAR]["x[4]"] == 18.0 assert physical._raw_interactions[constants.INTERACTION_LINEAR]["x[5]"] == -28.0 assert physical._raw_interactions[constants.INTERACTION_LINEAR]["x[6]"] == 360.0 assert physical._offset == 10.0
def __init__(self, job_dict, max_time=None, remove_impossible_times=True): # time_vars are required by bin_vars, which must exist before add_constraints super().__init__(job_dict=job_dict, max_time=max_time, remove_impossible_times=remove_impossible_times) self.bin_vars = self.create_bin_vars() self.start_once_const = 0.0 self.machine_cap_const = 0.0 self.operation_order_const = 0.0 self.add_constraints() self.penalty_strength = pyqubo.Placeholder("penalty_strength") self.hamiltonian = 0.0 \ + self.penalty_strength \ * (self.start_once_const + self.machine_cap_const + self.operation_order_const)
def tsp_mapping( prev_model: sawatabi.model.LogicalModel, prev_sampleset: dimod.SampleSet, curr_data: List[Tuple[float, Tuple[int, Dict[str, List[float]]]]], incoming: List[Tuple[float, Tuple[int, Dict[str, List[float]]]]], outgoing: List[Tuple[float, Tuple[int, Dict[str, List[float]]]]], ) -> sawatabi.model.LogicalModel: """ Mapping -- Update model based on the input data elements Parameters ---------- prev_model : sawatabi.model.LogicalModel Previous LogicalModel. prev_sampleset : dimod.SampleSet, Previous SampleSet. curr_data : List Elements in the current window (= prev data + incoming - outgoing). curr_data : [ (1.0, (1, {'Sendai': [140.87194, 38.26889]})), (2.0, (2, {'Tokyo': [139.69167, 35.689440000000005]})), (3.0, (3, {'Yokohama': [139.6425, 35.44778]})), (4.0, (4, {'Nagoya': [136.90667, 35.180279999999996]})), (5.0, (5, {'Kyoto': [135.75556, 35.021390000000004]})) ] incoming : List Elements just coming into the current window. incoming: [ (5.0, (5, {'Kyoto': [135.75556, 35.021390000000004]})) ] outgoing : List Elements just going from the current window. outgoing: [ (0.0, (0, {'Sapporo': [141.34694, 43.064170000000004]})) ] Returns ------- model : sawatabi.model.LogicalModel LogicalModel of TSP created from data in the current window. """ import pyqubo from geopy.distance import geodesic model: sawatabi.model.LogicalModel = prev_model.empty() # print(f"incoming: {incoming}", type(incoming)) # print(f"curr_data: {curr_data}", type(curr_data)) # print(f"outgoing: {outgoing}", type(outgoing)) # prepare binary vector with bit(i, j) n_city = len(curr_data) if n_city > 0: binary_vector = model.append("city", shape=(n_city, n_city)) # Update variables else: return model # Constraint not to visit more than one citie at the same time. time_const = 0.0 for i in range(n_city): time_const += pyqubo.Constraint( (pyqubo.Sum(0, n_city, lambda j: binary_vector[i, j]) - 1)**2, label="time{}".format(i)) # Constraint not to visit the same city more than once. city_const = 0.0 for j in range(n_city): city_const += pyqubo.Constraint( (pyqubo.Sum(0, n_city, lambda i: binary_vector[i, j]) - 1)**2, label="city{}".format(j)) # Objective term n_cities = [list(c[1][1].values())[0] for c in curr_data] traveling_distance = 0.0 for i in range(n_city): # i: city to visit for j in range(n_city): # j: city to visit for k in range(n_city): # k: visit order # Scale down O(100)km -> O(1)km or convenience long_lat_dist = geodesic( (n_cities[i][1], n_cities[i][0]), (n_cities[j][1], n_cities[j][0])).km / 100 traveling_distance += long_lat_dist * binary_vector[ k, i] * binary_vector[(k + 1) % n_city, j] # Build an Hamiltonian from the constraint terms and the objective term. hamiltonian_tsp = traveling_distance + pyqubo.Placeholder( "time") * time_const + pyqubo.Placeholder("city") * city_const # Load QUBO from the PyQUBO expression into the Sawatabi model. model.from_pyqubo(hamiltonian_tsp) # print(f"model: {model}", type(model)) return model
def optimize(game_type, W, c, w, min_count): N = len(w) # x_max = {k: int(W / v) for k, v in w.items()} offset_value = {x: int(min_count[x]) * int(y) for x, y in w.items()} new_W = W - sum(offset_value.values()) x_max = {k: int((new_W) / v) for k, v in w.items()} print('min_count') print(min_count) print('offset_value') print(offset_value) print('sum_offset_value') print(sum(offset_value.values())) print('new_W') print(new_W) print('x_max') print(x_max) for k, v in x_max.items(): if v <= 0: return "paramater error" # print("x_max: ") # print(x_max) x = pyq.Array([ pyq.LogEncInteger('x_{}'.format(i), (0, x_max[i])) for i in x_max.keys() ]) y = pyq.LogEncInteger('y', (0, new_W)) A, B = pyq.Placeholder("A"), pyq.Placeholder("B") HA = pyq.Constraint(A * (new_W - sum(w[a] * x[a] for a in range(N)) - y)**2, label='HA') HB = -B * sum(c[a] * x[a] for a in range(N)) Q = HA + HB model = Q.compile() feed_dict = {'A': 1, 'B': 1} qubo, offset = model.to_qubo(feed_dict=feed_dict) #iteration回数 iteration = 1000 sampler = oj.SASampler(num_reads=iteration) response = sampler.sample_qubo(qubo) def decode_solution(sampleset): decoded = model.decode_sampleset(response, feed_dict=feed_dict) solution = decoded[0].subh x = np.zeros(N, dtype=int) y = 0 for k, v in solution.items(): if 'x' in k: index = int(k.split('_')[1]) x[index] = v elif 'y' in k: y = v return {'x': x, 'y': y} result = decode_solution(response) print(result['x']) result_x = result['x'] print('result_x') print(result_x) # gacha_count = {v: result_x[k] for k,v in game_type.items()} # print(gacha_count) gacha_result = { game_id[str(v)]: result_x[k] + min_count[k] for k, v in enumerate(game_type) } gacha_count = { str(v): result_x[k] + min_count[k] for k, v in enumerate(game_type) } print('gacha_result') print(gacha_result) print('gacha_count') print(gacha_count) for k, v in gacha_result.items(): print(k) print(v) sum_money = sum(offset_value) for k, v in gacha_count.items(): sum_money += v * int(gacha_bid[k]) print('合計金額:') print(sum_money) return gacha_result