【发布时间】:2021-03-25 11:47:02
【问题描述】:
我完全被这个(整数)线性规划公式任务困住了:
输入:包含循环的有向边加权图。
目标:找到一组边,它们的权重之和最小,这样如果从图中删除这些边,图就会变成非循环的。
编辑:对于任何感兴趣的人,我发现(在朋友的帮助下),您可以使用拓扑排序来解决这个问题。您只需要为每条边引入一个约束,这样:topologicalOrder[ edge.parent ] << topologicalOrder[ edge.child ] + ( M * edgeInactive[edge])
其中topologicalOrder[node] 是节点拓扑位置的整数数组,edgeInactive 是布尔数组,表示边在结果(非循环)图中是否处于活动状态。
M 是用于在 edgeActive[edge] == true 时“关闭”约束的 Big M 方法。
那么你只需要最小化非活动边的权重总和。
旧(较慢)解决方案:
我的想法是创建节点的拓扑排序(对于非循环图,当拓扑排序时,所有边都将从左到右定向),但是当我得到带有循环的图时,我将寻找这样的拓扑排序,即总和从右到左的边数最少。
这种方法有效,但速度很慢......
(我正在尝试用 Gurobi 解决这个问题,但我认为这是非常普遍的线性规划公式问题。) 我的代码:
# Variables
x = model.addVars(nodeCount, nodeCount, vtype=g.GRB.BINARY) # matrix of size nodeCount * nodeCount, where x[i,j] denotes if node i is topologically before node j
#Constraints
for e in edges:
model.addConstr(x[e.child, e.parent] == 1 - x[e.parent, e.child]) # x[i,j] needs to be equal to negative value of x[j,i]
for k in range(nodeCount):
model.addConstr( x[e.parent, e.child] + x[e.child, k] - x[e.parent, k] <= 1) # Without this constraint solver produced invalid ordering results so I came up with this equation. But I'm not sure if this is the best way to solve this issue..
# Objective
sumNegativeEdges = 0;
for e in edges:
sumNegativeEdges+= (x[e.child, e.parent]) * e.weight; # Adding just weight of edges where child is topologically before the parent
model.setObjective(sumNegativeEdges, g.GRB.MINIMIZE)
不胜感激...
【问题讨论】:
标签: graph-theory mathematical-optimization linear-programming gurobi