def build_dqm(G, num_colors): """Build DQM model.""" print("\nBuilding discrete quadratic model...") colors = range(num_colors) # Initialize the DQM object dqm = DiscreteQuadraticModel() # initial value of Lagrange parameter lagrange = max(colors) # Load the DQM. Define the variables, and then set biases and weights. # We set the linear biases to favor lower-numbered colors; this will # have the effect of minimizing the number of colors used. # We penalize edge connections by the Lagrange parameter, to encourage # connected nodes to have different colors. for v in G.nodes: dqm.add_variable(num_colors, label=v) for v in G.nodes: dqm.set_linear(v, colors) for u, v in G.edges: dqm.set_quadratic(u, v, {(c, c): lagrange for c in colors}) return dqm
def test_sampler(self): sampler = MockLeapHybridDQMSampler() self.assertTrue(callable(sampler.sample_dqm)) self.assertTrue(callable(sampler.min_time_limit)) self.assertTrue(hasattr(sampler, 'properties')) self.assertTrue(hasattr(sampler, 'parameters')) dqm = DiscreteQuadraticModel() dqm.add_variable(3) dqm.add_variable(4) result = sampler.sample_dqm(dqm) self.assertTrue(isinstance(result, SampleSet)) self.assertGreaterEqual(len(result), 12) # min num of samples from dqm solver self.assertEqual(len(result.variables), 2) self.assertEqual(result.vartype, ExtendedVartype.DISCRETE)
def bqm_to_dqm(bqm): """Represent a :class:`dimod.BQM` as a :class:`dimod.DQM`.""" try: from dimod import DiscreteQuadraticModel except ImportError: # pragma: no cover raise RuntimeError( "dimod package with support for DiscreteQuadraticModel required." "Re-install the library with 'dqm' support.") dqm = DiscreteQuadraticModel() ising = bqm.spin for v, bias in ising.linear.items(): dqm.add_variable(2, label=v) dqm.set_linear(v, [-bias, bias]) for (u, v), bias in ising.quadratic.items(): biases = np.array([[bias, -bias], [-bias, bias]], dtype=np.float64) dqm.set_quadratic(u, v, biases) return dqm
def build_dqm(): '''Builds the DQM for our problem''' preferences = employee_preferences() num_shifts = 4 # Initialize the DQM object dqm = DiscreteQuadraticModel() # Build the DQM starting by adding variables for name in preferences: dqm.add_variable(num_shifts, label=name) # Use linear weights to assign employee preferences for name in preferences: dqm.set_linear(name, preferences[name]) return dqm
def build_dqm(): '''Builds the DQM for our problem''' preferences = employee_preferences() num_shifts = 4 # Initialize the DQM object dqm = DiscreteQuadraticModel() # Build the DQM starting by adding variables for name in preferences: dqm.add_variable(num_shifts, label=name) # Use linear weights to assign employee preferences for name in preferences: dqm.set_linear(name, preferences[name]) # TODO: Restrict Anna from working shift 4 # TODO: Set some quadratic biases to reflect the restrictions in the README. return dqm
def build_dqm(W, C, n, p, a, verbose=True): """Builds discrete quadratic model representing the optimization problem. Args: - W: Numpy matrix. Represents passenger demand. Normalized with total demand equal to 1. - C: Numpy matrix. Represents airline leg cost. - n: Int. Number of cities in play. - p: Int. Number of hubs airports allowed. - a: Float in [0.0, 1.0]. Discount allowed for hub-hub legs. - verbose: Print to command-line for user. Returns: - dqm: DiscreteQuadraticModel representing the optimization problem. """ if verbose: print("\nBuilding DQM...\n") # Initialize DQM object. dqm = DiscreteQuadraticModel() for i in range(n): dqm.add_variable(n, label=i) # Objective: Minimize cost. for i in range(n): for j in range(n): for k in range(n): dqm.set_linear_case( i, k, dqm.get_linear_case(i, k) + C[i][k] * W[i][j]) dqm.set_linear_case( j, k, dqm.get_linear_case(j, k) + C[j][k] * W[i][j]) for m in range(n): if i != j: dqm.set_quadratic_case(i, k, j, m, a * C[k][m] * W[i][j]) # Constraint: Every leg must connect to a hub. gamma1 = 150 for i in range(n): for j in range(n): if i != j: dqm.set_linear_case(i, j, dqm.get_linear_case(i, j) + 1 * gamma1) dqm.set_quadratic_case( i, j, j, j, dqm.get_quadratic_case(i, j, j, j) - 1 * gamma1) # Constraint: Exactly p hubs required. gamma2 = 250 for i in range(n): dqm.set_linear_case(i, i, dqm.get_linear_case(i, i) + (1 - 2 * p) * gamma2) for j in range(i + 1, n): dqm.set_quadratic_case( i, i, j, j, dqm.get_quadratic_case(i, i, j, j) + 2 * gamma2) return dqm
from dwave.system import LeapHybridDQMSampler # Graph partitioning with DQM solver # Number of nodes in the graph num_nodes = 30 # Create a random geometric graph G = nx.random_geometric_graph(n=num_nodes, radius=0.4, dim=2, seed=518) # Set up the partitions num_partitions = 5 partitions = range(num_partitions) # Initialize the DQM object dqm = DiscreteQuadraticModel() # initial value of Lagrange parameter lagrange = 10 # Define the DQM variables. We need to define all of them first because there # are not edges between all the nodes; hence, there may be quadratic terms # between nodes which don't have edges connecting them. for p in G.nodes: dqm.add_variable(num_partitions, label=p) constraint_const = lagrange * (1 - (2 * num_nodes / num_partitions)) for p in G.nodes: linear_term = constraint_const + (0.5 * np.ones(num_partitions) * G.degree[p]) dqm.set_linear(p, linear_term)
"""Graph partioning program from slide 89""" from dimod import DiscreteQuadraticModel from dwave.system import LeapHybridDQMSampler from networkx import nx lagrange = 10 num_colors = 4 colors = range(num_colors) dqm = DiscreteQuadraticModel() G = nx.Graph() G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (0, 6)]) n_edges = len(G.edges) for p in G.nodes: dqm.add_variable(num_colors, label=p) for p in G.nodes: dqm.set_linear(p, colors) for p0, p1 in G.edges: dqm.set_quadratic(p0, p1, {(c, c): lagrange for c in colors}) for p0, p1 in G.edges: dqm.set_quadratic(p0, p1, {(c, c): lagrange for c in colors}) sampler = LeapHybridDQMSampler() sampleset = sampler.sample_dqm(dqm) sample = sampleset.first.sample energy = sampleset.first.energy valid = True for edge in G.edges: i, j = edge if sample[i] == sample[j]: valid = False
rows, cols, _ = img.shape linear_biases = np.zeros(rows * cols * num_segments) case_starts = np.arange(rows * cols) * num_segments num_interactions = rows * cols * (rows * cols - 1) * num_segments / 2 qb_rows = [] qb_cols = [] qb_biases = [] for i in range(rows * cols): for j in range(i + 1, rows * cols): for case in range(num_segments): qb_rows.append(i * num_segments + case) qb_cols.append(j * num_segments + case) qb_biases.append(weight(i, j, img)) quadratic_biases = (np.asarray(qb_rows), np.asarray(qb_cols), np.asarray(qb_biases)) dqm = DiscreteQuadraticModel.from_numpy_vectors(case_starts, linear_biases, quadratic_biases) # Initialize the DQM solver print("\nRunning DQM solver...") sampler = LeapHybridDQMSampler() # Solve the problem using the DQM solver sampleset = sampler.sample_dqm(dqm) # Get the first solution sample = sampleset.first.sample print("\nProcessing solution...") im_segmented = np.zeros((rows, cols)) for key, val in sample.items(): x, y = unindexing(key)
def build_dqm(G): """ Build the DQM for the problem instance.""" # Two groups (cases 0, 1) and one separator group (case 2) num_groups = 3 # Lagrange parameter on constraints gamma_1 = 1 gamma_2 = 100 # Initialize the DQM object print("\nBuilding DQM...") dqm = DiscreteQuadraticModel() # Build the DQM starting by adding variables for name in G.nodes(): dqm.add_variable(num_groups, label=name) # Add objective to DQM for name in G.nodes(): dqm.set_linear_case(name, 2, 1) # Add constraint to DQM: |G1|=|G2| all_nodes_ordered = list(G.nodes()) for i in range(len(all_nodes_ordered)): dqm.set_linear_case(all_nodes_ordered[i], 0, gamma_1) dqm.set_linear_case(all_nodes_ordered[i], 1, gamma_1) for j in range(i + 1, len(all_nodes_ordered)): dqm.set_quadratic_case(all_nodes_ordered[i], 0, all_nodes_ordered[j], 0, 2 * gamma_1) dqm.set_quadratic_case(all_nodes_ordered[i], 1, all_nodes_ordered[j], 1, 2 * gamma_1) dqm.set_quadratic_case(all_nodes_ordered[i], 0, all_nodes_ordered[j], 1, -2 * gamma_1) dqm.set_quadratic_case(all_nodes_ordered[i], 1, all_nodes_ordered[j], 0, -2 * gamma_1) # Add constraint to DQM: e(G1, G2) = 0 for a, b in G.edges(): if a != b: dqm.set_quadratic_case(a, 0, b, 1, gamma_2) dqm.set_quadratic_case(a, 1, b, 0, gamma_2) return dqm
def buildDQM(G, sudoku): ''' This method builds the DQM based on Sudoku Constraints now modelled as Graph Parameters : G : networkx graph object, which represents the modelled graph sudoku : 2D list which contains the content of text file viz. sudoku problem statement. Returns : dqm : Discrete Quadratic Model object ''' #number of colors required to color the graph num_colors = int(math.sqrt(len(G.nodes()))) colors = range(num_colors) global_row = num_colors global_col = global_row #to map the matrix representation of sudoku to node represenation of graph node_dict = nodeMapping(global_row) dqm = DiscreteQuadraticModel() lagrange = 1000 #adding the variables for p in G.nodes: dqm.add_variable(num_colors, label=p) #linear biasing for p in G.nodes: dqm.set_linear(p, colors) ''' constraints: 1. Nodes sharing an edge cannot share the same color 2. Color of certain nodes are pre-defined ''' #quadratic biasing for constraint 1 for p0, p1 in G.edges: #penalising the case which violate constraint 1 dqm.set_quadratic(p0, p1, {(c, c): lagrange for c in colors}) #quadratic biasing for constraint 2 color_list = list(colors) for i in range(global_row): for j in range(global_col): if (sudoku[i][j] == '*'): continue #penalize_color_list = list(colors) #penalize_color_list.remove(int(sudoku[i][j])-1) #finding the neighbouring nodes of the given node node = node_dict[(i, j)] node_neighbour_set = set() for edge in G.edges(): if (node in edge): node_neighbour_set.add(edge[0]) node_neighbour_set.add(edge[1]) node_neighbour_set.remove(node) '''for node_neighbour in node_neighbour_set: for c1 in color_list: for c2 in penalize_color_list: dqm.set_quadratic(node,node_neighbour,{(c2,c1):lagrange})''' node_color = int(sudoku[i][j]) - 1 for node_neighbour in node_neighbour_set: for c1 in color_list: if (c1 == node_color): continue #favoring the case which agrees upon constraint 2 dqm.set_quadratic(node, node_neighbour, {(node_color, c1): 0}) return dqm
from networkx import nx import dwave_networkx as dnx import dimod from dimod import DiscreteQuadraticModel from dwave.system import LeapHybridDQMSampler from dwave.system import LeapHybridSampler from dimod import DiscreteQuadraticModel from dwave.system import LeapHybridDQMSampler from networkx import nx lagrange = 10 num_colors = 1 #only one colour for travelling salesman colors = range(num_colors) dqm = DiscreteQuadraticModel() G = nx.Graph() G.add_weighted_edges_from({(0, 1, 1), (0, 2, 50), (0, 3, 51), (1, 2, 1), (1, 3, 2), (2, 3, 1)}) #G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (0, 6)]) n_edges = len(G.edges) print(G.nodes) print(G.edges) for p in G.nodes: dqm.add_variable(num_colors, label=p) for p in G.nodes: dqm.set_linear(p, colors) #for p0, p1 in G.edges: #dqm.set_quadratic(p0, p1, {(c, c): G.weights}) dqm.set_quadratic(0, 1, {(0, 0): 1}) dqm.set_quadratic(0, 2, {(0, 0): 50})
def solve(adj_nodes, adj_edges, even_dist=False): dqm = DiscreteQuadraticModel() for i in adj_nodes: dqm.add_variable(NURSES, label=i) # classic graph coloring constraint that no two adjacent nodes have the same color for i0, i1 in adj_edges: dqm.set_quadratic(i0, i1, {(c, c): LAGRANGE for c in range(NURSES)}) shifts_per_nurse = DAYS * SHIFTS // NURSES if even_dist: # we should ensure that nurses get assigned a roughly equal amount of work for i in range(NURSES): for index, j in enumerate(adj_nodes): dqm.set_linear_case( j, i, dqm.get_linear_case(j, i) - LAGRANGE * (2 * shifts_per_nurse + 1)) for k_index in range(index + 1, len(adj_nodes)): k = adj_nodes[k_index] dqm.set_quadratic_case( j, i, k, i, LAGRANGE * (dqm.get_quadratic_case(j, i, k, i) + 2)) # some nurses may hate each other, so we should do out best to not put them in the same shift! for d in range(DAYS): for s in range(SHIFTS): for l1 in range(NURSES_PER_SHIFT): for l2 in range(l1 + 1, NURSES_PER_SHIFT): j = f"l{l1}_d{d}_s{s}" k = f"l{l2}_d{d}_s{s}" for conflict in CONFLICTS: for n1 in conflict: for n2 in conflict: if n1 == n2: continue dqm.set_quadratic_case( j, n1, k, n2, LAGRANGE2 * (dqm.get_quadratic_case(j, n1, k, n2) + 10)) sampler = LeapHybridDQMSampler(token=API_TOKEN) sampleset = sampler.sample_dqm(dqm, time_limit=10) sample = sampleset.first.sample energy = sampleset.first.energy return sample, energy
print("\nEnter number of employees:") num_employees = int(input()) print("\nEnter number of shifts:") num_shifts = int(input()) print("\nScheduling", num_employees, "employees over", num_shifts, "shifts...\n") # Generate random array of preferences over employees preferences = np.tile(np.arange(num_shifts), (num_employees, 1)) rows = np.indices((num_employees,num_shifts))[0] cols = [np.random.permutation(num_shifts) for _ in range(num_employees)] preferences = preferences[rows, cols] # Initialize the DQM object dqm = DiscreteQuadraticModel() # Build the DQM starting by adding variables for name in range(num_employees): dqm.add_variable(num_shifts, label=name) # Distribute employees equally across shifts according to preferences num_per_shift = int(num_employees/num_shifts) gamma = 1/(num_employees*num_shifts) for i in range(num_shifts): for j in range(num_employees): dqm.set_linear_case(j, i, dqm.get_linear_case(j, i) - gamma*(2*num_per_shift+1)) for k in range(j+1, num_employees): dqm.set_quadratic_case(j, i, k, i, gamma*(dqm.get_quadratic_case(j, i, k, i) + 2))