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")
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]]
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
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
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
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)
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)
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)
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): ')))
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)
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
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
# 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)