示例#1
0
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
示例#2
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
示例#5
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)
示例#6
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
示例#7
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