示例#1
0
    def optimize_leap(self):
        from pyqubo import Array,Constraint,Placeholder,UnaryEncInteger,Sum #LogEncInteger
        from dwave.system import LeapHybridSampler

        x = Array.create("x",shape=(self.num),vartype="BINARY")
        #y = LogEncInteger("y",lower=0,upper=5)
        y = UnaryEncInteger("y",lower=0,upper=5)

        #価値が最大になるように(符号を反転させる)
        H1 = -Sum(0,self.num,lambda i :x[i]*self.p[i].get_value() )
        #H1 = -sum([x[i]*self.p[i].get_value() for i in range(self.num)])

        #重さが目的の重量になるように
        H2 = Constraint((self.limit_weight -sum([x[i]*p_i.get_weight() for i,p_i in enumerate(self.p)]) - y*10)**2,"Const Weight")

        H = H1 + H2*Placeholder("balancer")
        model = H.compile()
        balance_dict = {"balancer":1.0}
        bqm = model.to_dimod_bqm(feed_dict=balance_dict)
        sampler = LeapHybridSampler()
        responses = sampler.sample(bqm,time_limit=3)

        solutions = model.decode_dimod_response(responses,feed_dict=balance_dict)

        if len(solutions[0][1]) == 0:
            print(f" y= { sum(2**i*y_i for i,y_i in enumerate(solutions[0][0]['y']))}")
            print("## LeapHybridSolver Optimized Result")
            self.print([int(solutions[0][0]['x'][i]) for i in range(self.num)])
        else:
            print("## LeapHybridSolver Optimizing Failed")
示例#2
0
def n_queens(n, sampler=None):
    """Returns a potential solution to the n-queens problem in a list of sets,
    each containing constraint IDs representing a queen's location.

    Args:
        n: Number of queens to place.

        sampler: A binary quadratic model sampler. Defaults to dwave-system's LeapHybridSampler.
    """
    num_row_col_constraints = 2 * n
    row_col_constraint_ids = set(range(num_row_col_constraints))

    num_diag_constraints = 4 * n - 6  # includes anti-diag constraints
    diag_constraint_ids = set(
        range(num_row_col_constraints,
              num_row_col_constraints + num_diag_constraints))

    # Build subsets of constraint IDs. Each subset will become a variable in our BQM.
    subsets = build_subsets(n)

    # Build BQM with only row/col constraints
    bqm = exact_cover_bqm(row_col_constraint_ids, subsets)

    # Add diag/anti-diag constraints - duplicates are penalized.
    bqm = handle_diag_constraints(bqm, subsets, diag_constraint_ids)

    if sampler is None:
        sampler = LeapHybridSampler()

    sampleset = sampler.sample(bqm)
    sample = sampleset.first.sample

    return [subsets[i] for i in sample if sample[i]]
示例#3
0
def solve_knapsack(incidencias,
                   controles,
                   online,
                   sampler=None,
                   samplerSpin=None):
    timeBqmS = datetime.now()
    bqm, J = createBQM(
        incidencias,
        controles)  #Se crea la matriz con las energías entre cada incidencia.
    timeBqmF = datetime.now()
    timeBQM = timeBqmF - timeBqmS
    print('Se han tardado ' + str(timeBQM) + ' segundos en crear el BQM.')

    timeSamplerS = datetime.now()
    if online:
        sampler = LeapHybridSampler(
        )  #Se inicializa el sampler. El LeapHybridSampler se utiliza para conectarse a
    else:  #los ordenadores de D-Wave, y el ExactSolver para hacer una simulación en la
        sampler = ExactSolver()  #computadora.
        #Probar SimulatedAnnealingSampler

    timeSamplerF = datetime.now()
    timeSampler = timeSamplerF - timeSamplerS
    print('Se han tardado ' + str(timeSampler) +
          ' segundos en crear el sampler.')

    timeSolverS = datetime.now()
    sampleset = sampler.sample(
        bqm
    )  #Se pasa el BQM que hemos creado anteriormente al sampler y busca las soluciones.
    timeSolverF = datetime.now()
    timeSolver = timeSolverF - timeSolverS
    print('Se han tardado ' + str(timeSolver) +
          ' segundos en resolver el problema.')

    sample = sampleset.first.sample  #Se guarda qué incidencias han sido gestionadas y cuáles no.
    energy = sampleset.first.energy  #Se guarda la energía que tiene la solución.

    #selected_item_ids = []
    #for varname, value in sample.items():
    # For each "x" variable, check whether its value is set, which
    # indicates that the corresponding item is included in the
    # knapsack
    # The index into the weight array is retrieved from the
    # variable name
    #if(sample[varname] == 1):
    #selected_item_ids.append(int(varname))

    selected_item_ids = []
    for varname, value in sample.items():
        # For each "x" variable, check whether its value is set, which
        # indicates that the corresponding item is included in the
        # knapsack
        if value and varname.startswith('x'):
            # The index into the weight array is retrieved from the
            # variable name
            selected_item_ids.append(int(varname[1:]))

    return sorted(selected_item_ids), energy, timeSolver, sampleset, J
示例#4
0
def _minimize_squared_loss_binary(H, y, lam):
    """Minimize squared loss using binary weight variables."""
    bqm = _build_bqm(H, y, lam)

    sampler = LeapHybridSampler()
    results = sampler.sample(bqm, label='Example - QBoost')
    weights = np.array(list(results.first.sample.values()))
    energy = results.first.energy

    return weights, energy
示例#5
0
def sample_dwave(bqm: dimod.BinaryQuadraticModel,
                 sample_label: str) -> dict[int, int]:
    """Ask the DWave sampler to return the best sample for the supplied binary quadratic model

    Args:
        bqm (dimod.BinaryQuadraticModel):
            Binary qudratic model representing the problem
        sample_label (str):
            Label to use for the sample - appears in the DWave dashboard

        Returns:
            A dictionary mapping the location of each element in the input "vector" to the
            corresponding 0/1 value returned by the sampler
    """
    sampler = LeapHybridSampler()
    sample_set = sampler.sample(bqm, label=sample_label)
    return sample_set.first.sample
示例#6
0
    def test_small(self):

        demand, nfreq, reuse_distances = load_problem('small')

        bqm = frequency.construct_bqm(demand, nfreq, reuse_distances)

        sampler = LeapHybridSampler()
        results = sampler.sample(bqm)

        violation_dict = frequency.check_results(demand,
                                                 nfreq,
                                                 reuse_distances,
                                                 results.first,
                                                 verbose=False)

        self.assertEqual(violation_dict['demand-count'], 0)
        self.assertEqual(violation_dict['self-count'], 0)
        self.assertEqual(violation_dict['cross-count'], 0)
示例#7
0
def solve_knapsack(costs, weights, weight_capacity, sampler=None):
    """Construct BQM and solve the knapsack problem
    
    Args:
        costs (array-like):
            Array of costs associated with the items
        weights (array-like):
            Array of weights associated with the items
        weight_capacity (int):
            Maximum allowable weight
        sampler (BQM sampler instance or None):
            A BQM sampler instance or None, in which case
            LeapHybridSampler is used by default
    
    Returns:
        Tuple:
            List of indices of selected items
            Solution energy
    """
    bqm = build_knapsack_bqm(costs, weights, weight_capacity)

    if sampler is None:
        sampler = LeapHybridSampler()

    sampleset = sampler.sample(bqm)
    sample = sampleset.first.sample
    energy = sampleset.first.energy

    # Build solution from returned binary variables:
    selected_item_indices = []
    for varname, value in sample.items():
        # For each "x" variable, check whether its value is set, which
        # indicates that the corresponding item is included in the
        # knapsack
        if value and varname.startswith('x'):
            # The index into the weight array is retrieved from the
            # variable name
            selected_item_indices.append(int(varname[1:]))

    return sorted(selected_item_indices), energy
# Off-diagonal terms in soft nurse constraint
# Include only the same nurse, across days
for nurse in range(n_nurses):
    for day1 in range(n_days):
        for day2 in range(day1 + 1, n_days):

            ind1 = get_index(nurse, day1)
            ind2 = get_index(nurse, day2)
            Q[ind1, ind2] += 2 * lagrange_soft_nurse * preference ** 2

# Solve the problem, and use the offset to scale the energy
e_offset = (lagrange_hard_shift * n_days * workforce ** 2) + (lagrange_soft_nurse * n_nurses * min_duty_days ** 2)
bqm = BinaryQuadraticModel.from_qubo(Q, offset=e_offset)
sampler = LeapHybridSampler()
results = sampler.sample(bqm)

# Get the results
smpl = results.first.sample
energy = results.first.energy
print("Size ", size)
print("Energy ", energy)


# Check the results by doing the sums directly
# J sum
sum_j = 0
for i in range(size):
    for j in range(size):
        sum_j += J[i, j] * smpl[i] * smpl[j]
print("Checking Hard nurse constraint ", sum_j)
示例#9
0
import dimod
from dimod import BinaryQuadraticModel
import numpy as np
from dwave.system import LeapHybridSampler
import sys

N = int(sys.argv[1])

# Ising model x_i x_j
h = {}
J = {(i, j): 1 for i in range(N) for j in range(i + 1, N)}

bqm = dimod.BinaryQuadraticModel.from_ising(h, J)

sampler = LeapHybridSampler()
sampleset = sampler.sample(bqm, time_limit=15)
print(sampleset.info)
print("Found solution at energy {}.".format(sampleset.first.energy))
print(len(sampleset.record[0][0]))
G = read_bigraph(in_file, idx_data)

Q = hamilton_qubo(G)

bqm = dimod.BinaryQuadraticModel(Q, 'BINARY')

# Choose one from below. The top two samplers are software algorithms,
# while the bottoms are hardware / hybrid algorithms.
#sampler = SimulatedAnnealingSampler()
#sampler = TabuSampler()
#sampler = EmbeddingComposite(DWaveSampler(solver={'qpu': True, 'postprocess': 'sampling'}))
sampler = LeapHybridSampler()

# Conduct optimization
sampleset = sampler.sample(bqm)

#print(sampleset.first)

edges = list(G.edges)
GS = nx.DiGraph()
for (u, v), d in sampleset.first.sample.items():
    if d == 1:
        if (u, v) in edges:
            GS.add_edge(u, v)
        else:
            print(u, v, ": not in G")

report_graph(GS)

#pos = nx.spring_layout(G)
示例#11
0
def main(token=None, n_nurses=3, n_days=11, nurses_per_day=1):
    """
    Takes a number of nurses, a number of days, and a wanted capacity
    of nurses per day.
    Also takes in a Dwave Authentication Token.
    Returns its best try at assigning nurses properly to the schedule required.
    One can think of the output as being a grid of size row x col,
    with a desired number of Xs in any column, while avoiding neighbouring
    Xs in any row.

    This runs on the Dwave Hybrid Sampler.
    The solution will be fast and good, but relatively expensive on Dwave
    allowed minutes.

    This code includes an implementation of the algorithm described in Ikeda,
    K., Nakamura, Y. & Humble, T.S. Application of Quantum Annealing to Nurse
    Scheduling Problem. Sci Rep 9, 12837 (2019).
    `DOI: 10.1038/s41598-019-49172-3 <https://doi.org/10.1038/s41598-019-49172-3>`_,
    © The Author(s) 2019, use of
    which is licensed under a Creative Commons Attribution 4.0 International
    License

    :param n_nurses: The number of nurses as an integer (number of rows in solution)

    :param n_days: The number of days as an integer (number of columns in solution)

    :param nurses_per_day: The number of desired nurses per day, an integer
        (desired number of Xs in any given column)

    :param token: The Dwave token to be used.
        This should be a string, in the format used on the dwave leap website.

    :return: Returns a dictionary. Keys supported:

        * "Size" a string describing the problem size
        * "Energy" a string describing the energy of the solution
        * "HardNurseConstraint" a string describing the hard nurse constraint energy
        * "HardShiftConstraint" a string describing the hard shift constraint energy
        * "n_days" an integer - the number of days (columns) of the solution
        * "n_nurses" an integer - the number of nurses (rows) of the solution
        * "schedule" - A 2-dimensional array of integers. Lists the exact days each nurse works (The marked columns for each row).
    
    """
    # Overall model variables: problem size
    # binary variable q_nd is the assignment of nurse n to day d
    n_nurses = n_nurses  # count nurses n = 1 ... n_nurses
    n_days = n_days  # count scheduling days as d = 1 ... n_days
    size = n_days * n_nurses

    print("solving with " + str(n_nurses) + " and " + str(n_days) +
          " nurses and days")

    # Parameters for hard nurse constraint
    # a is a positive correlation coefficient for implementing the hard nurse
    # constraint - value provided by Ikeda, Nakamura, Humble
    a = 3.5

    # Parameters for hard shift constraint
    # Hard shift constraint: at least one nurse working every day
    # Lagrange parameter, for hard shift constraint, on workforce and effort
    lagrange_hard_shift = 1.3
    # workforce = 1     # Workforce function W(d) - set to a constant for now
    workforce = nurses_per_day  # Workforce function W(d)
    effort = 1  # Effort function E(n) - set to a constant for now

    # Parameters for soft nurse constraint
    # Soft nurse constraint: all nurses should have approximately even work
    #                        schedules
    # Lagrange parameter, for shift constraints, on work days is called gamma
    # in the paper
    # Minimum duty days 'min_duty_days' - the number of work days that each
    # nurse wants
    # to be scheduled. At present, each will do the minimum on average.
    # The parameter gamma's value suggested by Ikeda, Nakamura, Humble
    lagrange_soft_nurse = 0.3  # Lagrange parameter for soft nurse, gamma
    preference = 1  # preference function - constant for now
    # min_duty_days = int(n_days/n_nurses)
    min_duty_days = int(n_days * workforce / n_nurses)

    # Find composite index into 1D list for (nurse_index, day_index)
    def get_index(nurse_index, day_index):
        return nurse_index * n_days + day_index

    # Inverse of get_index - given a composite index in a 1D list, return the
    # nurse_index and day_index
    def get_nurse_and_day(index):
        nurse_index, day_index = divmod(index, n_days)
        return nurse_index, day_index

    # Hard nurse constraint: no nurse works two consecutive days
    # It does not have Lagrange parameter - instead, J matrix
    # symmetric, real-valued interaction matrix J, whereas all terms are
    # a or zero.
    # composite indices i(n, d) and j(n, d) as functions of n and d
    # J_i(n,d)j(n,d+1) = a and 0 otherwise.
    J = defaultdict(int)
    for nurse in range(n_nurses):
        for day in range(n_days - 1):
            nurse_day_1 = get_index(nurse, day)
            nurse_day_2 = get_index(nurse, day + 1)
            J[nurse_day_1, nurse_day_2] = a

    # Q matrix assign the cost term, the J matrix
    Q = deepcopy(J)

    # Hard shift constraint: at least one nurse working every day
    # The sum is over each day.
    # This constraint tries to make (effort * sum(q_i)) equal to workforce,
    # which is set to a constant in this implementation, so that one nurse
    # is working each day.
    # Overall hard shift constraint:
    # lagrange_hard_shift * sum_d ((sum_n(effort * q_i(n,d)) - workforce) ** 2)
    #
    # with constant effort and constant workforce:
    # = lagrange_hard_shift * sum_d ( effort * sum_n q_i(n,d) - workforce ) ** 2
    # = lagrange_hard_shift * sum_d [ effort ** 2 * (sum_n q_i(n,d) ** 2)
    #                              - 2 effort * workforce * sum_n q_i(n,d)
    #                              + workforce ** 2 ]
    # The constant term is moved to the offset, below, right before we solve
    # the QUBO
    #
    # Expanding and merging the terms ( m is another sum over n ):
    # lagrange_hard_shift * (effort ** 2 - 2 effort * workforce) *
    # sum_d sum_n q_i(n,d)
    # + lagrange_hard_shift * effort ** 2 * sum_d sum_m sum_n q_i(n,d) q_j(m, d) #

    # Diagonal terms in hard shift constraint, without the workforce**2 term
    for nurse in range(n_nurses):
        for day in range(n_days):
            ind = get_index(nurse, day)
            Q[ind, ind] += lagrange_hard_shift * (effort**2 -
                                                  (2 * workforce * effort))

    # Off-diagonal terms in hard shift constraint
    # Include only the same day, across nurses
    for day in range(n_days):
        for nurse1 in range(n_nurses):
            for nurse2 in range(nurse1 + 1, n_nurses):

                ind1 = get_index(nurse1, day)
                ind2 = get_index(nurse2, day)
                Q[ind1, ind2] += 2 * lagrange_hard_shift * effort**2

    # Soft nurse constraint: all nurses should have approximately even work
    #                        schedules
    # This constraint tries to make preference * sum(q_i) equal to min_duty_days,
    # so that the nurses have the same number of days. The sum of the q_i,
    # over the number of days, is each nurse's number of days worked in the
    # schedule.
    # Overall soft nurse constraint:
    # lagrange_soft_nurse * sum_n ((sum_d(preference * q_i(n,d)) - min_duty_days) ** 2)
    # with constant preference and constant min_duty_days:
    # = lagrange_soft_nurse * sum_n ( preference * sum_d q_i(n,d) - min_duty_days ) ** 2
    # = lagrange_soft_nurse * sum_n [ preference ** 2 * (sum_d q_i(n,d) ** 2)
    #                              - 2 preference * min_duty_days * sum_d q_i(n,d)
    #                              + min_duty_days ** 2 ]
    # The constant term is moved to the offset, below, right before we solve
    # the QUBO
    #
    # The square of the the sum_d term becomes:
    # Expanding and merging the terms (d1 and d2 are sums over d):
    # = lagrange_soft_nurse * (preference ** 2 - 2 preference * min_duty_days) * sum_n sum_d q_i(n,d)
    # + lagrange_soft_nurse * preference ** 2 * sum_n sum_d1 sum_d2 q_i(n,d1)
    #                      * q_j(n, d2)

    # Diagonal terms in soft nurse constraint, without the min_duty_days**2 term
    for nurse in range(n_nurses):
        for day in range(n_days):
            ind = get_index(nurse, day)
            Q[ind,
              ind] += lagrange_soft_nurse * (preference**2 -
                                             (2 * min_duty_days * preference))

    # Off-diagonal terms in soft nurse constraint
    # Include only the same nurse, across days
    for nurse in range(n_nurses):
        for day1 in range(n_days):
            for day2 in range(day1 + 1, n_days):

                ind1 = get_index(nurse, day1)
                ind2 = get_index(nurse, day2)
                Q[ind1, ind2] += 2 * lagrange_soft_nurse * preference**2

    # Solve the problem, and use the offset to scale the energy
    e_offset = (lagrange_hard_shift * n_days * workforce**2) + (
        lagrange_soft_nurse * n_nurses * min_duty_days**2)
    bqm = BinaryQuadraticModel.from_qubo(Q, offset=e_offset)

    endpoint = 'https://cloud.dwavesys.com/sapi/'
    client = 'qpu'
    #solver = 'DW_2000Q_5' # Use this to specify a solver, but leave commented out to let D-Wave's system autochoose a solver
    try:
        qpu_sampler = DWaveSampler(client=client,
                                   endpoint=endpoint,
                                   token=token)
        #solver=solver)
    except:
        return {'error': 'Token not accepted'}
    sampler = LeapHybridSampler(token=token)
    results = sampler.sample(bqm, qpu_sampler=qpu_sampler)

    # Get the results
    ret_value = dict()
    smpl = results.first.sample
    energy = results.first.energy
    print("Size ", size)
    print("Energy ", energy)

    ret_value["Size"] = "Size " + str(size)
    ret_value["Energy"] = "Energy " + str(energy)

    # Check the results by doing the sums directly
    # J sum
    # sum_j = 0
    # for i in range(size):
    #     for j in range(size):
    #         sum_j += J[i, j] * smpl[i] * smpl[j]
    # print("Checking Hard nurse constraint ", sum_j)

    # Removed that method, as it created too many empty elements in J
    # This one only iterates over non-zero values in J

    sum_j = 0
    for (i, j), val in J.items():
        sum_j += val * smpl[i] * smpl[j]
    print("Checking Hard nurse constraint ", sum_j)

    ret_value["HardNurseConstraint"] = "Checking Hard nurse constraint " + str(
        sum_j)

    # workforce sum
    sum_w = 0
    for d in range(n_days):
        sum_n = 0
        for n in range(n_nurses):
            sum_n += effort * smpl[get_index(n, d)]
        sum_w += lagrange_hard_shift * (sum_n - workforce) * (sum_n -
                                                              workforce)
    print("Checking Hard shift constraint ", sum_w)

    ret_value["HardShiftConstraint"] = "Checking Hard shift constraint " + str(
        sum_w)

    # min_duty_days sum
    sum_f = 0
    for n in range(n_nurses):
        sum_d = 0
        for d in range(n_days):
            sum_d += preference * smpl[get_index(n, d)]
        sum_f += lagrange_soft_nurse * (sum_d - min_duty_days) * (
            sum_d - min_duty_days)
    print("Checking Soft nurse constraint ", sum_f)

    # Graphics
    sched = [get_nurse_and_day(j) for j in range(size) if smpl[j] == 1]
    str_header_for_output = " " * 11
    str_header_for_output += "  ".join(map(str, range(n_days)))
    print(str_header_for_output)

    schedule_mat = np.zeros((n_nurses, n_days))
    for n in range(n_nurses):
        str_row = ""
        for d in range(n_days):
            if (n, d) in sched:
                outcome = "X"
                schedule_mat[n, d] = 1
            else:
                outcome = " "

            if d > 9:
                outcome += " "
            str_row += "  " + outcome
        print("Nurse ", n, str_row)

    ret_value["n_days"] = n_days
    ret_value["n_nurses"] = n_nurses
    ret_value["schedule"] = [
        np.where(row == 1)[0].tolist() for row in schedule_mat
    ]
    # print(ret_value)
    return ret_value
from dwave.system import LeapHybridSampler
import dimod
import sys

# Graph partitioning on clique
N = int(sys.argv[1])
gamma = 3
linear = (N - 1) * (1 - gamma)
quad = (2 * gamma) - 2

bqm = dimod.AdjVectorBQM(dimod.Vartype.BINARY)
bqm.offset = gamma * N**2 / 4
for i in range(N):
    bqm.set_linear(i, linear)
    for j in range(i + 1, N):
        bqm.quadratic[i, j] = quad

sampler = LeapHybridSampler(profile='hss')
response = sampler.sample(bqm)

print(response.info)
for sample, energy in response.data(['sample', 'energy']):
    print(sample, energy)
    for i in range(0, num_spots):
        if our[i] == 0:
            continue
        #idx = b.get_rowcol_idx(i) # This is the original
        idx = b.get_neighbor_idx(i)
        for j in idx:
            if i < j:
                quadratic[(i + 1, j + 1)] -= 2 * anti_mill_constant
    offset += (2 * num_spots) * anti_mill_constant
    vartype = dimod.SPIN

    bqm = dimod.BinaryQuadraticModel(linear, quadratic, offset, vartype)
    #sampler = dimod.SimulatedAnnealingSampler()
    sampler = LeapHybridSampler()
    #sampler=KerberosSampler()
    sample_set = sampler.sample(bqm, num_reads=10)
    #sampler = dimod.ExactSolver()
    #sample_set = sampler.sample(bqm)
    #print("sample_set:", sample_set)
    next_state = sample_set.samples()[0]  # Maybe do sampling instead??
    print("next_state:", next_state)
    for i in range(1, num_spots + 1):
        if next_state[i] == 1 and enemy[i - 1] != 1:  # We added condition here
            enemy[i - 1] = 1
            b.place_marker(pos=i - 1, player_num=2)
            play_counter += 1
    print(enemy)
    print(b)

    # Choose our input
    our_pos = int(eval(input('Give position to place marker (1-24): ')))
示例#14
0
import dimod
import sys

# Graph partitioning on clique
N = int(sys.argv[1])
time_limit = int(sys.argv[2])

gamma = 3
linear = (N - 1) * (1 - gamma)
quad = (2 * gamma) - 2

Q = {}
for i in range(N):
    Q[i, i] = linear
    for j in range(i + 1, N):
        Q[i, j] = quad

chainstrength = 20

offset = gamma * N**2 / 4
bqm = dimod.BinaryQuadraticModel.from_qubo(Q, offset=offset)

sampler = LeapHybridSampler(profile='hss')
response = sampler.sample(bqm, time_limit=time_limit)

print(response.info)
for sample, energy in response.data(['sample', 'energy']):
    count_ones = sum([v for v in sample.values() if v == 1.])
    if count_ones == N / 2:
        print(sample, energy, count_ones)
示例#15
0
def solve_knapsack(incidencias, controles, sampler=None, samplerSpin=None):
    """Construct BQM and solve the knapsack problem
    
    Args:
        costs (array-like):
            Array of costs associated with the items
        weights (array-like):
            Array of weights associated with the items
        weight_capacity (int):
            Maximum allowable weight
        sampler (BQM sampler instance or None):
            A BQM sampler instance or None, in which case
            LeapHybridSampler is used by default
    
    Returns:
        Tuple:
            List of indices of selected items
            Solution energy
    """

    #solved, rest = find_necessary_incidents(incidencias, controles)

    #remaining = find_already_completed(solved, controles)

    #bqm, J = createBQM(rest, remaining)

    time5 = datetime.now()
    bqm, J = createBQM(incidencias, controles)
    time6 = datetime.now()
    print(time6 - time5)

    print(J)

    time3 = datetime.now()
    sampler = LeapHybridSampler()
    #sampler = ExactSolver()
    time4 = datetime.now()
    print(time4 - time3)

    time1 = datetime.now()
    sampleset = sampler.sample(bqm)
    time2 = datetime.now()
    solverTime = time2 - time1
    time7 = datetime.now()
    sample = sampleset.first.sample
    energy = sampleset.first.energy
    time8 = datetime.now()
    print(time8 - time7)

    time9 = datetime.now()
    # Build solution from returned binary variables:
    selected_item_indices = []
    for varname, value in sample.items():
        # For each "x" variable, check whether its value is set, which
        # indicates that the corresponding item is included in the
        # knapsack
        # The index into the weight array is retrieved from the
        # variable name
        if (sample[varname] == 1):
            selected_item_indices.append(int(varname))
    time10 = datetime.now()
    print(time10 - time9)

    #for i in solved.keys():
    #    selected_item_indices.append(i)

    return sorted(selected_item_indices), energy, solverTime, sampleset
示例#16
0
def solve_cities(cities: List, gdps: List, sick: List, total_capacity: int,
                 value_r=0, weight_r=0, num_reads=1, verbose=False) -> Dict:
    """
    Solves problem: "Which cities should I should I shut down in order to stay
    within healthcare resources constraints while maximizing overall GDP"
    parameters:
        cities - list of city names
        gdps - corresponding list of GDP per city
        sick - corresponding number of sick people per city
        total_capacity - max capacity for sick people summed over all cities
        num_reads - number of samples to take
        verbose - whether to print out best result
    returns:
        (dict) - list of dictionaries with individual results and selected attributes
                    sorted in order of least energy first
    """
    if sum(sick) < total_capacity:
        print("Warning in solve_cities: Total number of sick people is less "
              + "than total capacity. There's no knapsack problem to solve!")

    bqm = knapsack_bqm(cities, gdps, sick, total_capacity,
                       value_r=value_r, weight_r=weight_r)
    sampler = LeapHybridSampler()
    samplesets = [sampler.sample(bqm) for _ in range(num_reads)]

    df = pd.DataFrame({'city': cities, 'gdp': gdps, 'sick': sick})
    df = df.set_index('city')

    solution_set = []
    for sampleset in samplesets:
        open_cities = []
        closed_cities = []
        for k, v in sampleset.first.sample.items():
            if k in cities:
                if v == 1:
                    open_cities.append(k)
                else:
                    closed_cities.append(k)
        solution_set.append({
            'open_cities': open_cities,
            'closed_cities': closed_cities,
            'energy': sampleset.first.energy,
            'salvaged_gdp': sum(df.loc[open_cities]['gdp']) + sum(df.loc[closed_cities]['gdp']) * value_r,
            'used_capacity': int(round(sum(df.loc[open_cities]['sick'])))
        })

    # do sorting from lowest to highest energy
    if num_reads > 1:
        energies = [solution['energy'] for solution in solution_set]
        solution_set = [x for _, x in sorted(zip(energies, solution_set))]

    if verbose:
        print('BEST SOLUTION')
        print('Open cities')
        print(solution_set[0]['open_cities'])
        print('\n')
        print('Closed cities')
        print(solution_set[0]['closed_cities'])
        print('\n')
        total_gdp = sum(df['gdp'])
        salvaged_gdp = solution_set[0]['salvaged_gdp']
        print(
            f'Salvaged GDP: {salvaged_gdp} ({(100*salvaged_gdp/total_gdp):.1f}%)')
        used_capacity = solution_set[0]['used_capacity']
        print(
            f'Used up hospital capacity: {used_capacity:d} of {total_capacity} ({(100*used_capacity/total_capacity):.1f}%)')

    return solution_set
示例#17
0
# Off-diagonal terms in soft nurse constraint
# Include only the same nurse, across days
for nurse in range(n_nurses):
    for day1 in range(n_days):
        for day2 in range(day1 + 1, n_days):

            ind1 = get_index(nurse, day1)
            ind2 = get_index(nurse, day2)
            Q[ind1, ind2] += 2 * lagrange_soft_nurse * preference**2

# Solve the problem, and use the offset to scale the energy
e_offset = (lagrange_hard_shift * n_days *
            workforce**2) + (lagrange_soft_nurse * n_nurses * min_duty_days**2)
bqm = BinaryQuadraticModel.from_qubo(Q, offset=e_offset)
sampler = LeapHybridSampler()
results = sampler.sample(bqm, label='Example - Nurse Scheduling')

# Get the results
smpl = results.first.sample
energy = results.first.energy
print("Size ", size)
print("Energy ", energy)

# Check the results by doing the sums directly
# J sum
sum_j = 0
for i in range(size):
    for j in range(size):
        sum_j += J[i, j] * smpl[i] * smpl[j]
print("Checking Hard nurse constraint ", sum_j)