我正在开发一个优化问题,该问题是Traveling Salesman的变体。在这种情况下,您不必游览所有城市,没有必要的起点和终点,游览长度有一个最小和最大界限,如果需要,您可以遍历每个弧线多次,并且非线性与所遍历的弧相关联的目标函数(以及遍历每个弧的次数)。决策变量是整数,即您遍历每个圆弧的次数。
我已经在Pyomo中开发了一个非线性整数程序,并且正在从NEOS服务器获得结果。但是我没有设置子行程约束,结果是两个断开的子行程。
我可以找到TSP的整数编程公式,该公式说明了如何制定子轮廓约束,但这与标准TSP略有不同,我正在尝试弄清楚如何开始。我们将不胜感激。
编辑:问题表述
50个弧,节点之间不是穷尽的对。 50个决策变量N_ab是> = 0的整数,对应于您从a遍历到b遍的次数。每个N_ab都有一个长度和利润。有两个约束条件,即所有ab的length_ab * N_ab之和在最小和最大距离之间。我有一个约束,即进入每个节点的N_ab的总和等于离开该节点的N_ab的总和,您根本不能访问一个节点,也不能多次访问它。目标函数是非线性的,与弧对之间的相互作用有关(与子行程无关)。
子游览:查看math.uwaterloo.ca/tsp/methods/opt/subtour.htm,该公式不适用,因为我不需要参观所有城市,并且可能无法访问。例如,假设我有20个节点和50个弧(所有弧的长度为10)。距离限制是针对长度恰好为30的漫游,这意味着我最多可以访问三个节点(从A-> B-> C-> A =长度30开始)。因此,我将完全不会访问其他节点。消除TSP子行程将要求我具有从节点子组ABC到未访问节点子组的边缘-这对于我的问题不是必需的
答案 0 :(得分:1)
这是一种根据奖金收集TSP(例如this paper)进行改编的方法。令V
为所有节点的集合。我假设V
包含一个 depot 节点(称为节点1),该节点必须在巡视中。 (否则,您可以添加一个充当此角色的虚拟节点。)
如果我们至少访问节点x[i]
一次,则让i
等于1,否则为0。 (您的模型中可能已经有这样的决策变量。)
添加这些约束,这些约束定义了x[i]
:
x[i] <= sum {j in V} N[i,j] for all i in V
M * x[i] >= N[i,j] for all i, j in V
换句话说:如果没有边缘出节点x[i]
,i
不能等于1,如果有边缘出节点{{,x[i]
必须等于1。 1}}。
(在这里,如果我们从i
到N[i,j]
,i
为1,而j
是一个足够大的数字,可能等于您可以遍历的最大次数边缘。)
这是为M
的所有子集S
定义的子行程消除约束,以使V
包括节点1,以及{{1}中的所有节点S
}}:
i
换句话说,如果我们访问不在V \ S
中的节点sum {j in S} (N[i,j] + N[j,i]) >= 2 * x[i]
,则必须至少有两个边缘进入或离开i
。 (对于S
而言,子游览违反了此约束,该约束等于子游览中包含1的节点。)
我们还需要一个约束,要求节点1在巡视中:
S
我可能在方向索引上玩得有些松懈,即我不确定您的模型是否设置了S
或类似的东西,但希望这个主意很清楚,您可以修改我的必要的方法。