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 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
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
# 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) # Quadratic term for node pairs which do not have edges between them for p0, p1 in nx.non_edges(G): dqm.set_quadratic(p0, p1, {(c, c): (2 * lagrange) for c in partitions}) # Quadratic term for node pairs which have edges between them for p0, p1 in G.edges: dqm.set_quadratic(p0, p1, {(c, c): ((2 * lagrange) - 1) for c in partitions}) # Initialize the DQM solver sampler = LeapHybridDQMSampler() # Solve the problem using the DQM solver offset = lagrange * num_nodes * num_nodes / num_partitions sampleset = sampler.sample_dqm(dqm, label='Example - Graph Partitioning DQM') # get the first solution sample = sampleset.first.sample
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 break print("Solution: ", sample) print("Solution energy: ", energy) print("Solution validity: ", valid)
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
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}) dqm.set_quadratic(0, 3, {(0, 0): 51}) dqm.set_quadratic(1, 2, {(0, 0): 1}) dqm.set_quadratic(1, 3, {(0, 0): 2}) dqm.set_quadratic(2, 3, {(0, 0): 1}) sampler = LeapHybridDQMSampler() sampleset = sampler.sample_dqm(dqm) print(sampleset) sample = sampleset.first.sample energy = sampleset.first.energy valid = True for edge in G.edges: i, j = edge if sample[i] == sample[j]:
# We penalize edge connections by the Lagrange parameter, to encourage # connected nodes to have different colors. print("\nBuilding discrete model...") # Initialize the DQM object dqm = DiscreteQuadraticModel() # Add the variables for p in G.nodes: dqm.add_variable(num_colors, label=p) # Add the biases 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}) # Initialize the DQM solver print("\nRunning model on DQM sampler...") sampler = LeapHybridDQMSampler() # Solve the problem using the DQM solver sampleset = sampler.sample_dqm(dqm, label='Example - Graph Coloring') # get the first solution, and print it sample = sampleset.first.sample node_colors = [sample[i] for i in G.nodes()] nx.draw(G, pos=pos, node_color=node_colors, node_size=50,