【问题标题】:Graph coloring Gurobi constraints图着色 Gurobi 约束
【发布时间】:2018-11-08 09:55:57
【问题描述】:

我正在尝试使用 networkx 和 gurobi 解决图形着色问题的一些限制。这是我写的所有代码:

import networkx as nx
import gurobi as gb
from itertools import combinations, chain
import pygraphviz as pygv
import os
import matplotlib.pyplot as plt
from IPython.display import SVG, display

创建图表,添加节点和边以及两个列表。

G = nx.Graph()
G.add_nodes_from ([1,2,3,4,5])
G.add_edge(1,2)
G.add_edge(1,3)
G.add_edge(1,4)
G.add_edge(1,5)
G.add_edge(2,3)
G.add_edge(2,4)
G.add_edge(3,5)
G.add_edge(4,5)
U = list(G.nodes)
K = G.number_of_edges()
Z = []

用颜色创建一个列表。我们假设 K = {0, 1, . . . , K − 1} 和 K ≤ |E|

def nrofCol():
    Z.clear()
    z = 0
    while z < K - 1:
        Z.append(z)
        z = z+1
    return Z

Z = nrofCol()

为每条边添加颜色属性

for colored_arc in ((u,v,z) for u,v in G.edges() for z in Z):
    G[colored_arc[0]][colored_arc[1]][colored_arc[2]] = colored_arc

并使用 Gurobi 向模型添加变量:

mdic = gb.Model()
indices = []

for u,v in G.edges(): 
    for z in Z:
        indices.append((u,v,z))

# binary variable that assing 1.0 to the color associated to the edge and 0.0 to the others

x = mdic.addVars(indices, vtype = gb.GRB.BINARY)

# decision variable S i for i ∈ V represents the maximum color in the set of colors assigned to edges incident to vertex i

S_i = []
for u in U:
    S_i.append(mdic.addVar(vtype=gb.GRB.CONTINUOUS, lb = G.degree[u] - 1, ub = K - 1, \
                        name = 'max_color'+str(u)))

# decision variable s_i for i ∈ V represents the minimum color in the set of colors assigned to edges incident to vertex i
s_i = []
for u in U:
    s_i.append(mdic.addVar(vtype=gb.GRB.CONTINUOUS, lb = 0.0, ub = K - G.degree[u], \
                        name='min_color'+str(u)))

mdic.update()

然后是约束:

# 1a- Guarantee that adjacent edges take different colors

for u in U:
    for z in Z: 
        mdic.addConstr(x.sum(u,'*',z) <= 1, name='different_color')


mdic.update()


# 1a- Guarantee that adjacent edges take different colors

for u in U:
    for z in Z:
        mdic.addConstr(x.sum('*',u,z) <= 1, name='different_color')


mdic.update()

# 1b- Guarantee that every edge takes exactly one color
for u,v in G.edges():
    mdic.addConstr(x.sum(u,v) == 1, name='one_color')

mdic.update()

# 1c- Enforce Si to be greater than or equal to the max color assigned to the edges incident to vertex i

expr = 0
for u,v in G.edges():
    for z in Z:       
        expr += z * x[u,v,z]
    mdic.addConstr(S_i[u] >= expr, name='max')
    expr = 0

# 1d- Enforce si to be less than or equal to the min color assigned to the edges incident to vertex i

expr = 0
for u,v in G.edges():
    for z in Z:       
        expr += z * x[u,v,z]
mdic.addConstr(s_i[u] <= expr, name='min')
expr = 0

mdic.update()

其中 Z 是可用颜色的集合。

# objective function
expr20=0
for u in U:
    expr20+=(S_i[u] - s_i[u] - G.degree[u] + 1)
mdic.setObjective(expr20, gb.GRB.MINIMIZE)

mdic.update()

mdic.optimize()

Constraints

第一个是目标函数,1a到1d是约束,其他是ub和lb。

【问题讨论】:

  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。由于缺少几个依赖项,您发布的代码没有按给定的方式运行。
  • 另外,您没有提供对您的程序和 cmets 假设的 gurobi 功能的任何引用:您将您的受众限制为 gurobi 大师。如果问题仅出在设置而不是优化步骤中,那么您已经排除了我们许多可能解决问题的人。
  • 对算法的简单解释会有所帮助。例如,为什么要将每种颜色添加到每个边缘?您如何确定最初与每条边相关联的颜色,以便您可以“为它设置 1.0”?为什么要使用浮点数来表示二进制值?这仅仅是后来仅仅是概率类型权重的初始条件吗?
  • 优化模型后是否调用了 S_i?你的目标函数是什么? S_i 的上下界是多少?
  • 是的,优化模型后调用 S_i。您可以在 S_i 的声明中看到 lb 及以上。这里是返回索引超出范围错误的目标函数。 expr=0 for u in U: expr+=(S_i[u] - s_i[u] - G.degree[u] + 1) mdic.setObjective(expr, gb.GRB.MINIMIZE)

标签: python networkx graph-theory gurobi


【解决方案1】:

假设你使用无向图,我发现了几个问题:

屏幕截图中的约束 (1a) 确保相邻边缘具有不同的颜色。但是,通过您实施此约束,可能会发生传入和传出边缘具有相同颜色的情况。例如,边 {1,3} 和 {3,5} 可以具有相同的颜色。那是因为您分别处理传入和传出边缘。作为一种解决方案,您可以将循环组合成一个:

for u in U:
    for z in Z: 
        mdic.addConstr(x.sum(u,'*',z) + x.sum('*',u,z) <= 1, name='different_color')

约束 (1c) 在您的实现中也只考虑出边。例如,S_i[5] 不会被分配,因为它只有传入边。这应该有效:

expr = 0
for u,v in G.edges():
    for z in Z:       
        expr += z * x[u,v,z]
    mdic.addConstr(S_i[u] >= expr, name='max')
    mdic.addConstr(S_i[v] >= expr, name='max')
    expr = 0

约束 (1d) 也是如此。 Morover addConstr 行在循环之外,但这可能只是一个格式错误:

expr = 0
for u,v in G.edges():
    for z in Z:       
        expr += z * x[u,v,z]
    mdic.addConstr(s_i[u] <= expr, name='min')
    mdic.addConstr(s_i[v] <= expr, name='min')
    expr = 0

【讨论】:

  • 使用第二个选项它工作,但不正确。来自具有相同颜色的节点的 2 个传出边,并且最大和最小颜色是错误的。我上传了问题中的约束图片,你能检查我是否犯了一些错误吗? @仙王座
  • 老实说,我不知道两个传出边缘如何具有相同的颜色,因为这是您的第一个约束所阻止的。但我发现了其他问题。 @迈克
  • 你能看看我的另一个问题吗? stackoverflow.com/questions/53263559/…@仙王座
猜你喜欢
  • 1970-01-01
  • 2015-07-31
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多