示例#1
0
 def add_precedence_constraints(self, precedence_pairs):
     for job, pairs in precedence_pairs.items():
         for i, t, k, tprime in pairs:
             self.operation_order_const += \
                 pyqubo.Constraint(
                     self.bin_vars[job][i + 1][t] * self.bin_vars[job][k + 1][tprime],
                     "operation_order__{}_{}_{}__{}_{}_{}".format(job, i + 1, t, job, k + 1, tprime)
                 )
示例#2
0
 def add_machine_cap_constraints(self, machines):
     for machine_cap_pairs in machines.values():
         for i, k in machine_cap_pairs:
             self.machine_cap_const += \
                 pyqubo.Constraint(
                     self.bin_vars[i[0]][i[1]][i[2]] * self.bin_vars[k[0]][k[1]][k[2]],
                     "machine_cap__{}_{}_{}__{}_{}_{}".format(i[0], i[1], i[2], k[0], k[1], k[2])
                 )
示例#3
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
示例#5
0
 def add_start_once_constraints(self, start_times):
     for job, op_num, op_times in start_times:
         # constraint is (sum(time_vars) - 1)**2; penalizes more or less than one start time
         self.start_once_const += \
             pyqubo.Constraint(
                 (
                     pyqubo.Sum(
                         0,
                         len(op_times),
                         lambda t: self.bin_vars[job][op_num][op_times[t]]
                     ) - 1
                 ) ** 2,
                 "start_once_{}_o{}".format(job, op_num)
             )
def knapsack(W, weights, costs):
    xs = pyqubo.Array.create('x', shape=(len(weights)), vartype='BINARY')

    ## 価値の制約
    X = -sum([c * x for (x, c) in zip(xs, costs)])

    ## OneHot Encoding
    a = pyqubo.OneHotEncInteger('y', 1, W, strength=100)

    ## 重さの制約
    Y = (a - sum([w * x for (x, w) in zip(xs, weights)]))**2

    ## ハミルトニアン(コスト関数)
    H = X + pyqubo.Constraint(Y, label="one_hot")

    ## モデル作成とQUBOの生成
    model = H.compile()
    q, offset = model.to_qubo()
    # print(q)

    ## 解答
    sampleset = dimod.ExactSolver().sample_qubo(q)
    solution, broken, e = model.decode_dimod_response(sampleset, topk=1)[0]
    return solution
示例#7
0
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
示例#8
0
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