繁体   English   中英

PuLP 仅显示 __dummy 变量

[英]PuLP only shows __dummy variable

我正在尝试在虚拟图形着色问题上使用 PuLP。 为了解决这个问题,我们需要为每个节点分配一种颜色,这样任何相邻节点都不会共享一个公共颜色,同时尽量减少使用的颜色总数。

这是一个虚拟数据:

edges = [('A', 'H'), ('A', 'B'), ('H', 'G'), ('H', 'K'), ('H', 'J'), 
         ('H', 'I'), ('G', 'F'), ('G', 'K'), ('F', 'E'), ('K', 'E'), 
         ('K', 'J'), ('K', 'D'), ('I', 'J'), ('I', 'D'), ('D', 'C'), 
         ('D', 'B')]
nodes = set(sum(edges, ()))
n_nodes = len(nodes)

使用谷歌的 OR-Tools,我可以找到一个解决方案:

from ortools.sat.python import cp_model

model = cp_model.CpModel()

# Set decision variables
var = {}
for node in nodes:
    var[node] = model.NewIntVar(0, n_nodes-1, node)

# Set objective
model.Minimize(len(set(var.values())))

# Add constraints
for edge in edges:
    model.Add(var[edge[0]] != var[edge[1]])

# Solve
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.OPTIMAL:
    print('Status: Optimal \n')

for node in nodes:
    print(f"{node}: {solver.Value(var[node])}")

回报:

Status: Optimal 

C: 0
A: 5
H: 4
K: 2
F: 1
E: 0
D: 1
J: 0
I: 2
B: 0
G: 3

旁注:虽然状态显示为最佳,但我觉得可以使用的颜色更少。

但是,当对 PuLP 使用类似的方法时,我看不到任何解决方案。

from pulp import *

model = LpProblem("coloring", LpMinimize)

# Set decision variables
var = {}
for node in nodes:
    var[node] = LpVariable(node, lowBound=0, upBound=n_nodes-1, cat=LpInteger)

# Set objective
model += len(set(var.values()))

# Add constraints
for edge in edges:
    model += var[edge[0]] != var[edge[1]]

# Solve
status = model.solve()
print(f'Status: {LpStatus[status]} \n')

for variable in prob.variables():
    print(f"{variable.name}, {v.varValue}")

回报:

Status: Optimal 

__dummy, None

任何关于我哪里出错的帮助将不胜感激。

因此,您的配方中有两个问题会导致您出现问题。 首先len(set(...))是一个非线性操作。 当您将表达式添加到问题中时,它们需要表示为线性方程。 你的约束有同样的问题。 您的逻辑是正确的,但您不能将x != y传递给求解器,这也是非线性的。 你必须看看如何用线性表达式来重新制定这些逻辑。

请注意,您始终可以在纸浆中print(model)以查看构建的内容,如果您打印自己的,则没有任何有用的东西出现……谁知道如何评估这些东西并将其放入模型中。 我怀疑它们在构造时会被评估一次,并且您将琐碎的表达式投入到模型中,例如 x = True 或其他东西,并且不会出错。

因此,这是线性表达式问题的另一种表述。 this_color != that_color约束有点复杂,它依赖于指示变量来启用非此即彼的构造。

我很少使用 Google 的 OR 工具,但它主要是这些概念之上的语法糖,所以也许有一种方法可以在 OR 工具中优雅地陈述它,但归根结底,这样的事情正在发生生成并传递给求解器。

图论中可能对此有更好的表述,但这对于简单的 ILP 来说效果很好。 3种颜色就是答案。

from pulp import *

edges = [('A', 'H'), ('A', 'B'), ('H', 'G'), ('H', 'K'), ('H', 'J'), 
         ('H', 'I'), ('G', 'F'), ('G', 'K'), ('F', 'E'), ('K', 'E'), 
         ('K', 'J'), ('K', 'D'), ('I', 'J'), ('I', 'D'), ('D', 'C'), 
         ('D', 'B')]
nodes = set(sum(edges, ()))
n_nodes = len(nodes)
M = n_nodes + 1

model = LpProblem("coloring", LpMinimize)

# Set decision variables
color = {}
for node in nodes:
    color[node] = LpVariable(node, lowBound=1, cat=LpInteger)
num_colors = LpVariable('count', cat = LpInteger)

color_diff = {}
for idx, edge in enumerate(edges):
    color_diff[edge] = LpVariable(str(idx), cat=LpBinary)

# Set objective
# model += len(set(var.values()))
model += num_colors   # seek to minimize the maximal color index

# Add constraints

# get the max value of the colors...
for node in nodes:
    model += num_colors >= color[node]

# ensure the adjacent nodes are different color
for edge in edges:
    # force one or the other of these to be true, based on the color_diff
    # variable, which is just a binary indicator
    model += -M * color_diff[edge] + 1 <= color[edge[0]] - color[edge[1]]
    model += -M * (1-color_diff[edge]) + 1 <= color[edge[1]] - color[edge[0]]  

# Solve
status = model.solve()
print(f'Status: {LpStatus[status]} \n')

for variable in model.variables():
    print(f"{variable.name}, {variable.varValue}")

产量

Result - Optimal solution found

Objective value:                3.00000000
Enumerated nodes:               0
Total iterations:               0
Time (CPU seconds):             0.01
Time (Wallclock seconds):       0.01

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.01   (Wallclock seconds):       0.01

Status: Optimal 

0, 1.0
1, 0.0
10, 0.0
11, 1.0
12, 0.0
13, 1.0
14, 0.0
15, 0.0
2, 0.0
3, 0.0
4, 0.0
5, 0.0
6, 1.0
7, 1.0
8, 0.0
9, 0.0
A, 2.0
B, 1.0
C, 1.0
D, 3.0
E, 1.0
F, 3.0
G, 1.0
H, 3.0
I, 2.0
J, 1.0
K, 2.0
count, 3.0
[Finished in 96ms]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM