我正在尝试在Cplex / OPL中运行此模型,以找到商店距离的最佳路径,以及每个商店中不同产品的数量+价格。 问题是我得到了脱节的路径 - “岛屿”。 我需要添加什么约束才能获得一个在节点1开始和结束的闭合路径? 这是模型:
dvar float+ x[products,stores];
dvar boolean y[stores,stores];
minimize ((sum(i in products, j in stores) prices[i,j]*x[i,j]) + (sum(j in stores, k
in stores) gas*distance[j,k]*y[j,k]));
subject to {
sum(k in stores) y[1,k] == 1;
sum(j in stores) y[j,1] == 1;
forall(j in stores)
sum(i in products) x[i,j] <= M*sum(k in stores) y[j,k];
forall(j in stores)
sum(i in products) x[i,j] <= M*sum(k in stores) y[k,j];
forall(i in products) sum(j in stores) x[i,j] == demand[i];
forall(i in products, j in stores) x[i,j] <= quantity[i,j];
forall(j in stores, k in stores) y[j,k] + y[k,j] <= 1;
forall(j in stores) sum(k in stores) y[j,k] == sum(k in stores) y[k,j];
}
谢谢!
答案 0 :(得分:2)
你要解决的是 traveling salesman problem的变体。具体来说,你得到的是 subours,,这是一个涉及更少的封闭路径比所有节点(你的情况下的商店)。
给定的一组节点有一个指数的子层。围绕 subour elimination 约束存在大量文献。幸运的是,对于实际中的小问题,我们可以根据需要添加减少消耗的约束。
以下是如何消除涉及 s 商店(s&lt; num_stores)的 S 的想法:
英文:我们从将节点(商店)集合开始分为两组S和T.让S成为子集中的商店集合。设T为S的外部商店,即所有其他商店。我们希望打破单循环路径,只涉及S的商店。
Do while:
Solve the current problem
If you don't find any subtours, you are done. Exit.
If there are subtours, add the subtour elimination constraints (see details below)
Continue
对于每个子句(“岛屿”),您必须先创建一组shops_in_subtour
。所有其他节点(商店)进入另一组(T)shops_not_in_subtour
将以下内容添加到约束集:
forall(s in shops_in_subtour)
forall(t in shops_not_in_subtour)
sum y[s,t] > = 1; // at least one edge must leave S and go to T
sum y[t,s] > = 1; // at least one edge must enter the set S from T
如果您的问题很小,您会发现添加一些这些约束就足够了。希望能帮助你前进。
根据OP的后续问题进行更新
您将检查CPLEX / Solver 外的
> 英语理念:您从原点商店开始并遍历路径,跟踪每个visited
商店。如果你回到原点,并且仍然有一些二进制Y变量,你有一个或多个子。 (从技术上讲,你可以从任何商店开始,但从一个商店开始更容易理解。)
Initialize visited_shop = NULL;
Find the Yij that is 1. (Starting edge for the path)
Do while (There are more Y variables = 1 remaining)
Add the destination of the new binary variable to list of visited_shops
Check if you are done (are you back at shop 1):
if Yes:
If no more binary variables left, you are done. Exit.
If there are some more non-zero binary variables, subtour detected
if No:
pick the next Y variable whose origin is current Y_variable's destination
Continue