예제 #1
0
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
예제 #2
0
파일: gc_solver.py 프로젝트: adadima/QUBO
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
예제 #3
0
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
예제 #4
0
# 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]:
예제 #8
0
# 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,