Esempio n. 1
0
def by_amplify_limited(list_dependent_variables, num_registers, limitation):
    num_variables = len(list_dependent_variables)
    q = gen_symbols(BinaryPoly, num_variables, num_registers)

    # 各変数を1つのレジスタに割り当てるOne-het制約
    const_onehot = [
        equal_to(sum_poly([q[i][r] for r in range(num_registers)]), 1)
        for i in range(num_variables)
    ]

    # レジスタスピルを減らすために,依存関係のある変数同士が同一のレジスタに割り当てられない制約
    const_spill = [
        penalty(q[i][r] * q[j][r]) for i in range(num_variables)
        for j in list_dependent_variables[i] if i < j
        for r in range(num_registers)
    ]

    # ある変数が割り当てられるレジスタがわかっている時,必ずそのレジスタに割り当てられるようにする制約
    const_limit = [
        penalty(q[i][r]) for i, x in limitation.items()
        for r in range(num_registers) if r not in x
    ]

    constraints = sum(const_onehot)
    if len(const_spill) != 0:
        constraints += sum(const_spill)
    if len(const_limit) != 0:
        constraints += sum(const_limit)
    return {"qubits": q, "model": BinaryQuadraticModel(constraints)}
Esempio n. 2
0
    def room_total_satisfaction(self):
        """ルームの総満足度

        Returns:
            [amplify.BinaryPoly]: \\sum_{j=1}^{M}P(j)
        """
        return sum_poly(self.num_users,
                        lambda j: self.someone_total_satisfaction(j))
Esempio n. 3
0
    def room_variance_satisfaction(self):
        """ルームの満足度の分散

        Returns:
            [amplify.BinaryPoly]: \\sum_{j=1}^{M}(P_{avg}-P(j))^2 / M
        """
        return sum_poly(
            self.num_users, lambda j: (self.room_average_satisfaction(
            ) - self.someone_total_satisfaction(j))**2) / self.num_users
Esempio n. 4
0
    def time_constraint(self):
        """時間制約

        Returns:
            [amplify.BinaryConstraint]: (\\sum_{i=1}^{N}(t_{i}x_{i}) - T)^2
        """
        return penalty((self.time_limit - sum_poly(
            self.num_tracks, lambda i: self.q[i] *
            (self.candidates[i].duration_ms // 1000)))**2)
Esempio n. 5
0
def make_hamiltonian(d, feed_dict):
    # set the number of cities
    N = len(d)
    # set hyperparameters
    lambda_1 = feed_dict['h1']
    lambda_2 = feed_dict['h2']
    # make variables
    x = gen_symbols(BinaryPoly, N, N)
    # set One-hot constraint for time
    h1 = [equal_to(sum_poly([x[n][i] for n in range(N)]), 1) for i in range(N)]
    # set One-hot constraint for city
    h2 = [equal_to(sum_poly([x[n][i] for i in range(N)]), 1) for n in range(N)]
    # compute the total of constraints
    const = lambda_1 * sum(h1) + lambda_2 * sum(h2)
    # set objective function
    obj = sum_poly(N, lambda n: sum_poly(N, lambda i: sum_poly(N, lambda j: d[i][j]*x[n][i]*x[(n+1)%N][j]), ), )
    # compute model
    model = obj + const
    return x, model
Esempio n. 6
0
    def someone_total_satisfaction(self, j: int):
        """メンバーjの総満足度

        Args:
            j (int): メンバーインデックス

        Returns:
            [amplify.BinaryPoly]: P(j) = \\sum_{i=1}^{N}p_{i,j}x_{i}
        """
        return sum_poly(self.num_tracks,
                        lambda i: self.q[i] * self.candidates[i].p[j])
Esempio n. 7
0
def by_amplify(list_dependent_variables, num_registers):
    num_variables = len(list_dependent_variables)
    q = gen_symbols(BinaryPoly, num_variables, num_registers)

    # 各変数を1つのレジスタに割り当てるOne-het制約
    const_onehot = [
        equal_to(sum_poly([q[i][r] for r in range(num_registers)]), 1)
        for i in range(num_variables)
    ]

    # レジスタスピルを減らすために,依存関係のある変数同士が同一のレジスタに割り当てられない制約
    const_spill = [
        penalty(q[i][r] * q[j][r]) for i in range(num_variables)
        for j in list_dependent_variables[i] if i < j
        for r in range(num_registers)
    ]

    constraints = sum(const_onehot) + sum(const_spill)
    return {"qubits": q, "model": BinaryQuadraticModel(constraints)}
Esempio n. 8
0
solver = Solver(client)

# 四色の定義
colors = ["red", "green", "blue", "yellow"]
num_colors = len(colors)
num_region = len(jm.pref_names) - 1  # 都道府県数を取得

# 都道府県数 x 色数 の変数を作成
q = gen_symbols(BinaryPoly, num_region, num_colors)

# 各領域に対する制約
# 一つの領域に一色のみ(one-hot)
# sum_{c=0}^{C-1} q_{i,c} = 1 for all i
reg_constraints = [
    equal_to(sum_poly([q[i][c] for c in range(num_colors)]), 1)
    for i in range(num_region)
]

# 隣接する領域間の制約
adj_constraints = [
    # 都道府県コードと配列インデックスは1ずれてるので注意
    penalty(q[i][c] * q[j - 1][c]) for i in range(num_region)
    for j in jm.adjacent(i + 1)  # j: 隣接している都道府県コード
    if i + 1 < j for c in range(num_colors)
]

constraints = sum(reg_constraints) + sum(adj_constraints)

model = BinaryQuadraticModel(constraints)
result = solver.solve(model)
Esempio n. 9
0
def quantum_solver_approx(N, M,
                          query):  # solve with Amplify (approximate version)
    q = gen_symbols(BinaryPoly, M, N, N)  # represent the solution

    ##########   constraints   ##########

    # each layer doesn't have 2+ same values
    one_hot_constraints_layer = [
        # m -> layer
        # n -> qubit
        # v -> value of qubit
        equal_to(sum(q[m][n][v] for n in range(N)), 1) for m in range(M)
        for v in range(N)
    ]

    # each qubit doesn't have 2+ values
    one_hot_constraints_num = [
        # m -> layer
        # n -> qubit
        # v -> value of qubit
        equal_to(sum(q[m][n][v] for v in range(N)), 1) for m in range(M)
        for n in range(N)
    ]

    # every CX gate must be applied for 2 adjacent qubits
    CXgate_constraints = []
    for m in range(M):
        for g0 in range(0, len(query[m]), 2):
            v0, v1 = query[m][g0], query[m][g0 + 1]

            # v0 and v1 must be adjacent each other
            for i in range(N):
                for j in range(i + 2, N):
                    CXgate_constraints.append(
                        penalty(q[m][i][v0] * q[m][j][v1]))
                    CXgate_constraints.append(
                        penalty(q[m][i][v1] * q[m][j][v0]))

    constraints = (sum(one_hot_constraints_layer) +
                   sum(one_hot_constraints_num) + sum(CXgate_constraints))

    cost = sum_poly(
        M - 1, lambda m: sum_poly(
            N, lambda i: sum_poly(
                N, lambda j: sum_poly(N, lambda v: q[m][i][v] * q[m + 1][j][v])
                * ((N - 1) * (i + j) - 2 * i * j) / N)))

    ##########   solve   ##########

    solver = Solver(client)
    model = BinaryQuadraticModel(constraints * constraintWeight + cost)

    result = solver.solve(model)
    if len(result) == 0:
        raise RuntimeError("Any one of constraints is not satisfied.")

    values = result[0].values
    q_values = decode_solution(q, values, 1)

    # print(q_values_main)

    ##########   decode the result into string   ##########

    ans = [[-1 for n in range(N)] for m in range(M)]
    for m in range(M):
        for n in range(N):
            for v in range(N):
                if (q_values[m][n][v] > 0.5):
                    ans[m][n] = v

    cost = 0
    for m in range(M - 1):
        cost += calcCost(ans[m], ans[m + 1])

    return cost, ans
Esempio n. 10
0
from amplify import BinaryQuadraticModel, Solver, decode_solution
from amplify.client import FixstarsClient
from amplify import BinaryPoly, gen_symbols, sum_poly
from amplify.constraint import equal_to
q = gen_symbols(BinaryPoly, 3)
H = equal_to(sum_poly(q), 3)
model = BinaryQuadraticModel(H)
solver = Solver(client)
result = solver.solve(model)
values = result[0].values
print(f"q = {decode_solution(q, values)}")
Esempio n. 11
0
# 研究室学生数
nstudents = [4, 5, 4, 3, 3, 2, 4, 4, 4, 4, 5, 3, 4, 3, 3]
assert nlab == len(nstudents), "研究室数と学生数配列の長さが違う"

# グループ名
grps = ["CS1", "CS2", "CS3", "CS4"]
ngrp = len(grps)  # グループ数

##################################################################################
# QUBO変数の生成: nlab x ngrp
q = gen_symbols(BinaryPoly, nlab, ngrp)

# グループ内の教員数
T = [
    sum_poly([q[i][j] * nteachers[i] for i in range(nlab)])
    for j in range(ngrp)
]

# グループ内の学生数
S = [
    sum_poly([q[i][j] * nstudents[i] for i in range(nlab)])
    for j in range(ngrp)
]

##################################################################################
# コスト関数:各グループの学生数、教員数が等しいか?
cost = sum_poly(ngrp, lambda j: (S[j] - S[
    (j + 1) % ngrp])**2) + sum_poly(ngrp, lambda j: (T[j] - T[
        (j + 1) % ngrp])**2)
Esempio n. 12
0
print("OR")
print(f"p_OR = {p_OR}")

# 制約条件を満たす解を求める
result = solver.solve(p_OR)
for sol in result:
    energy = sol.energy
    values = sol.values

    print(f"energy = {energy}, {q} = {decode_solution(q, values)}")

###########################################################
# 等式制約:one-hot制約
# バイナリ変数:要素数3
q = gen_symbols(BinaryPoly, 3)
g = (sum_poly(q) - 1)**2  # one-hot 制約に対応したペナルティ関数

print("One-Hot")
print(f"g = {g}")

# 問題を解いて結果を表示
result = solver.solve(g)
for sol in result:
    energy = sol.energy
    values = sol.values

    print(f"energy = {energy}, {q} = {decode_solution(q, values)}")

###########################################################
# 等式制約:q0 * q1 + q2 = 1
g = equal_to(q[0] * q[1] + q[2], 1)  # 等式制約
Esempio n. 13
0
# インデックスをずらさないと、同一の変数が定義されてしまう
print(s1, s2)

# s1 の分だけインデックスをずらして変数生成
s3 = gen_symbols(BinaryPoly, len(s1), (4, ))

# 異なる変数が定義できる
print(s1, s3) 

##########################
# 例 1
# バイナリ変数を1次元配列形式に8個生成
q = gen_symbols(BinaryPoly, 8)

# 二値変数や多項式のリストを指定すると、その総和を計算
f0 = sum_poly(q)

print(f"f0 = {f0}")

##########################
# 例 2
# バイナリ変数を3個生成
q = gen_symbols(BinaryPoly, 3)

# インデックスを受け取る関数とインデックスの上限値を指定して、総和を取ることも可能
f1 = sum_poly(3, lambda i:
        sum_poly(3, lambda j: q[i] * q[j]))

print(f"f1 = {f1}")

##########################
            if j < len(pol_data[i][2]) - 1:
                angle_diff = pol_data[i][2][j + 1][2] - pol_data[i][2][j][2]
                pa_diff_each.append([pol_data[i][2][j][0], angle_diff])
            else:
                angle_diff = pol_data[i][2][0][2] - pol_data[i][2][j][2]
                pa_diff_each.append([pol_data[i][2][j][0], angle_diff])

        pa_diff_data.append([pol_data[i][0], pol_data[i][1], pa_diff_each])

    # テンプレートとして持っているデータの個数をバイナリ変数の数とする。
    # 1のとき、その角度パラメータである。0のときその角度パラメータではないとする。
    q = gen_symbols(BinaryPoly, len(pa_diff_data))

    # onehot条件: 当てはまる角度パラメータは1つだけ
    const_onehot = (sum_poly(q) - 1)**2

    # 目的関数: 各回転位相での偏光角の違いを小さくするためのもの
    obj_pa = 0.0
    coef = 1.0 / 180.0

    for j in range(len(pa_test)):
        obj_pa_j = pa_test[j][1]

        for i in range(len(pa_data)):
            obj_pa_j -= pa_data[i][2][j][1] * q[i]

        obj_pa += coef**2 * obj_pa_j**2

    # 目的関数: 各回転位相の偏光角の変化の違いを小さくするためのもの
    obj_pa_diff = 0.0
Esempio n. 15
0
    def find_feasible_solution(self):
        """find a feasible locations with makespan, found -> set self.used_edges
        """
        # create variables
        q = []
        index = 0
        for t in range(self.makespan):
            q.append([])
            for v in range(self.field["size"]):
                l = len(self.field["adj"][v])+1  # +1 -> stay at the current location
                q[-1].append(
                    amplify.gen_symbols( amplify.BinaryPoly, index, (1, l) )
                )
                index += l

        # set starts
        constraints_starts = [
            equal_to(sum_poly( q[0][v][0] ), 1)    # q[timestep][node][0]
            for v in self.instance["starts"]
        ]

        for v in range(self.field["size"]):
            if v in self.instance["starts"]:
                continue
            # other locations
            for i in range(len(q[0][v][0])):
                q[0][v][0][i] = amplify.BinaryPoly(0)

        # set goals
        constraints_goals = [
            equal_to(sum_poly([ q[-1][u][0][ self.field["adj"][u].index(v) ]
                                for u in self.field["adj"][v] ] +
                              [ q[-1][v][0][ len(self.field["adj"][v]) ] ]),
                     1)
            for v in self.instance["goals"]
        ]

        for v in range(self.field["size"]):
            # other locations
            for i in range(len(self.field["adj"][v])):
                if self.field["adj"][v][i] not in self.instance["goals"]:
                    q[-1][v][0][i] = amplify.BinaryPoly(0)
            if v not in self.instance["goals"]:
                q[-1][v][0][-1] = amplify.BinaryPoly(0)

        # upper bound, in
        constraints_in = [
            less_equal(sum_poly([ q[t][u][0][ self.field["adj"][u].index(v) ]
                                  for u in self.field["adj"][v] ] +
                                [ q[t][v][0][ len(self.field["adj"][v]) ] ]),
                       1)
            for v, t in product(range(self.field["size"]), range(0, self.makespan-1))
        ]

        # upper bound, out
        constraints_out = [
            less_equal(sum_poly( q[t][v][0] ),
                       1)
            for v, t in product(range(self.field["size"]), range(1, self.makespan))
        ]

        # continuity
        constraints_continuity = [
            equal_to(sum_poly([ q[t][u][0][ self.field["adj"][u].index(v) ]
                                for u in self.field["adj"][v] ] +
                              [ q[t][v][0][ len(self.field["adj"][v]) ] ])
                     -
                     sum_poly( q[t+1][v][0] ),
                     0)
            for v, t in product(range(self.field["size"]), range(0, self.makespan-1))
        ]

        # branching
        for v in range(self.field["size"]):
            if not self.field["body"][v]:
                continue
            # unreachable vertexes from starts
            for t in range(0, min(self.DIST_TABLE_FROM_STARTS[v], self.makespan)):
                for i in range(len(q[t][v][0])):
                    q[t][v][0][i] = amplify.BinaryPoly(0)
            # unreachable vertexes to goals
            for t in range(max(self.makespan - self.DIST_TABLE_FROM_GOALS[v] + 1, 0), self.makespan):
                for i in range(len(q[t][v][0])):
                    q[t][v][0][i] = amplify.BinaryPoly(0)

        # set occupied vertex
        for v in range(self.field["size"]):
            if self.field["body"][v]:
                continue
            for t in range(0, self.makespan):
                q[t][v][0][-1] = amplify.BinaryPoly(0)

        # create model
        model = sum(constraints_starts)
        model += sum(constraints_goals)
        if len(constraints_in) > 0:
            model += sum(constraints_in)
        if len(constraints_out) > 0:
            model += sum(constraints_out)
        if len(constraints_continuity) > 0:
            model += sum(constraints_continuity)

        # setup client
        client = FixstarsClient()
        client.token = os.environ['TOKEN']
        client.parameters.timeout = self.timeout

        # solve
        solver = amplify.Solver(client)
        result = solver.solve(model)
        if len(result) > 0:
            self.used_edges = amplify.decode_solution(q, result[0].values)
from amplify import BinaryPoly, gen_symbols, sum_poly, Solver
from amplify.constraint import greater_equal
from amplify.client import HitachiClient

from secret import get_token
import utils

import time

# 問題サイズ N=2,4,6,8,10,12,14,16 で実験
for N in range(2, 16 + 1, 2):
    # QUBO変数の2次元配列(正方格子グラフに対応)
    q = gen_symbols(BinaryPoly, N, N)

    # コスト関数(w_b で調整)
    cost_function = sum([sum_poly(q[i]) for i in range(N)])

    # 制約(w_a で調整)
    constraint_x = sum([
        greater_equal(q[i][j] + q[i + 1][j], 1) for i in range(N - 1)
        for j in range(N)
    ])
    constraint_y = sum([
        greater_equal(q[i][j] + q[i][j + 1], 1) for i in range(N)
        for j in range(N - 1)
    ])
    constraint = constraint_x + constraint_y

    # クライアント設定
    client = HitachiClient()
    client.token = get_token()
Esempio n. 17
0
def make_hamiltonian(type_matrix, weak_matrix, resist_matrix, enemies, num_party, feed_dict):
    # set the number of types
    N = len(type_matrix)
    # set the number of enemies
    M = len(enemies)
    # set hyperparameters
    lambda_1 = feed_dict['h1']
    lambda_2 = feed_dict['h2']
    lambda_3 = feed_dict['h3']
    # make variables
    x = gen_symbols(BinaryPoly, num_party, N)
    # set one-hot constraint for types
    h1 = [equal_to(sum_poly([x[i][j] for j in range(N)]), 1) for i in range(num_party)]
    # set weak constraint
    h2 = [less_equal(sum_poly(N, lambda j: sum_poly(num_party, lambda l: sum_poly(N, lambda k: enemies[i][j]*weak_matrix[j][k]*x[l][k]))), 2) for i in range(M)]
    # set resist constraint
    h3 = [greater_equal(sum_poly(N, lambda j: sum_poly(num_party, lambda l: sum_poly(N, lambda k: enemies[i][j]*resist_matrix[j][k]*x[l][k]))), 1) for i in range(M)]
    # compute the total of constraints
    const = lambda_1 * sum(h1) + lambda_2 * sum(h2) + lambda_3 * sum(h3)
    # set objective function
    obj = sum_poly(num_party, lambda i: sum_poly(N, lambda j: sum_poly(N, lambda k: sum_poly(M, lambda l: x[i][j]*type_matrix[j][k]*enemies[l][k]))))
    # compute model
    model = - obj + const
    return x, model