每周的目标功能-帮助编写代码-CPLEX

时间:2019-11-04 10:31:39

标签: cplex opl lexicographic

(OPL模型和Lindo模型在代码框中) 我需要有关此问题的帮助。我的目标是组织每周(第1、2、3和4周)哪些卡车从始发地运到目的地。在此示例中,总共有6辆卡车,每周必须至少运送一辆。每次装运都有相关的成本,目标是在第一周,然后在第二,第三和第四周将成本降到最低。这是一个字典目标编程问题。我用其他软件(Lindo)制作了扩展模型,并且可以使用,但是用OPL编写时遇到了困难。有人可以帮我吗?

Xijt,i =接送点(1,2,3,4,5),j =目的地(1,2),t =周(1,2,3,4)

! My code in Lindo:
MIN p4
subject to
p1 = 10
p2 = 10
p3 = 100

! Cost 

0 X111 + 0 X211 + 90 X311+  0 X411 + 10 X511 + 0 X121 + 100 X221 + 0 X321 + 50 X421 + 10 X521 -p1 + n1 = 0 ! Week 1 
0 X112 + 0 X212 + 90 X312+  0 X412 + 10 X512 + 0 X122 + 100 X222 + 0 X322 + 50 X422 + 10 X522 -p2 + n2 = 0 ! Week 2 
0 X113 + 0 X213 + 90 X313+  0 X413 + 10 X513 + 0 X123 + 100 X223 + 0 X323 + 50 X423 + 10 X523 -p3 + n3 = 0 ! Week 3 
0 X114 + 0 X214 + 90 X314+  0 X414 + 10 X514 + 0 X124 + 100 X224 + 0 X324 + 50 X424 + 10 X524 -p4 + n4 = 0 ! Week 4 


! Number of trucks

X311 + X312 + X313 + X314  = 1 !In 4 weeks, there is 1 truck from pickup point 3 to destination 1
X511 + X512 + X513 + X514  = 1
X221 + X222 + X223 + X224  = 2
X421 + X422 + X423 + X424  = 1
X521 + X522 + X523 + X524  = 1 


! Week restriction
!At least one truck must be used per week
X311 + X511 + X221 + X421 + X521 >=1
X312 + X512 + X222 + X422 + X522 >=1
X313 + X513 + X223 + X423 + X523 >=1
X314 + X514 + X224 + X424 + X524 >=1


END

INT X311 
INT X312 
INT X313 
INT X314 

INT X511
INT X512 
INT X513 
INT X514

INT X221 
INT X222
INT X223 
INT X224 

INT X421 
INT X422 
INT X423 
INT X424

INT X521
INT X522
INT X523
INT X524 
---------------------------------------------------
// CPLEX
using CP;
// decision variables

{string} Pickup = {"A","B","C","D","E"};
{string} Destination = {"D1" , "D2"};
{string} Weeks = {"W1", "W2", "W3", "W4"};

int Trucks [Pickup][Destination]= [[0,0],[0,2],[1,0],[0,1],[1,1]]; 
int Cost [Pickup]=[140,100,90,50,10]; 

//Decision Variables
dvar int  Delivered [Forest][Destination][Weeks]; //not sure if it is right

//Expressions
dexpr int Week1 = sum (u in Pickup, c in Destination, W1 in Weeks) Trucks[u][c] * Cost [u] * Delivered[u][c][W1];
dexpr int Week2 = sum (u in Pickup, c in Destination, W2 in Weeks) Trucks[u][c] * Cost [u] * Delivered[u][c][W2];
dexpr int Week3 = sum (u in Pickup, c in Destination, W3 in Weeks) Trucks[u][c] * Cost [u] * Delivered[u][c][W3];
dexpr int Week4 = sum (u in Pickup, c in Destination, W4 in Weeks) Trucks[u][c] * Cost [u] * Delivered[u][c][W4];



//Objective Function
minimize staticLex (Week1,Week2,Week3,Week4);

//Constraint
subject to {
forall (u in Pickup)
    forall (c in Destination)
        sum (W1 in Weeks)
            Trucks [u][c] >= 1;

forall (u in Forest)
    forall (c in Destination)
        sum (W2 in Weeks)
            Trucks [u][c] >= 1;

forall (u in Pickup)
    forall (c in Destination)
        sum (W3 in Weeks)
            Trucks [u][c] >= 1;

forall (u in Pickup)
    forall (c in Destination)
        sum (W4 in Weeks)
            Trucks [u][c] >= 1;

}


execute Output {
    writeln ("Delivered Plan")
        for (var t in Trucks)
            for (var u in Pickup)
                for (var c in Destination)
                    for (var w in Weeks)
                        if (Delivered [t][u][c][w]>0) {
                        writeln (Delivered [t][u][c][w] + '' + " number of trucks " + '' + t + '' + "  delivered from pickup poit " + '' + u +" to destination " +''+ c + " in the week "+''+ w);

}
}

1 个答案:

答案 0 :(得分:2)

这看起来很腥:

//Expressions
dexpr int Week1 = sum (u in Pickup, c in Destination, W1 in Weeks) Trucks[u][c] * Freshness [u] * Delivered[u][c][W1];
dexpr int Week2 = sum (u in Pickup, c in Destination, W2 in Weeks) Trucks[u][c] * Freshness [u] * Delivered[u][c][W2];
dexpr int Week3 = sum (u in Pickup, c in Destination, W3 in Weeks) Trucks[u][c] * Freshness [u] * Delivered[u][c][W3];
dexpr int Week4 = sum (u in Pickup, c in Destination, W4 in Weeks) Trucks[u][c] * Freshness [u] * Delivered[u][c][W4];

//Objective Function
minimize staticLex (Week1,Week2,Week3,Week4);

周的表达式中,您要汇总所有周的变量。我猜想您要的是这个

//Expressions
dexpr int Week1 = sum (u in Pickup, c in Destination) Trucks[u][c] * Freshness [u] * Delivered[u][c]["W1"];
dexpr int Week2 = sum (u in Pickup, c in Destination) Trucks[u][c] * Freshness [u] * Delivered[u][c]["W2"];
dexpr int Week3 = sum (u in Pickup, c in Destination) Trucks[u][c] * Freshness [u] * Delivered[u][c]["W3"];
dexpr int Week4 = sum (u in Pickup, c in Destination) Trucks[u][c] * Freshness [u] * Delivered[u][c]["W4"];

请注意,Delivered的最后一个索引现在在每个表达式中都是恒定的。现在,每个表达式只将一个星期的变量求和。

更新:模型还有其他问题:首先,所有四个约束都完全相同。您可以将它们写为一个约束:

forall (u in Pickup)
    forall (c in Destination)
        sum (w in Weeks)
            Trucks [u][c] >= 1;

然后这些约束看起来很奇怪,因为您对w in Weeks求和,但是对您求和的量(Trucks)却没有按周索引。 Trucks也不是决策变量。因此,您在这里并没有真正说明约束,而只是对常数值求和。

下一个问题是您的决策变量Delivered没有出现在任何约束中。因此,这里没有太多要优化的地方。

您可能需要返回并查看应该完全优化的内容。优化器可以更改或必须决定的内容是什么,约束是什么,等等。例如,在您的LINDO模型中,我看不到任何与Delivered决策变量或{{ 1}}或Freshness事物。取而代之的是,在LINDO模型中,Forest是决策变量,并且也在数周内被索引。

这里是一个OPL模型,应该与您的LINDO模型等效(第1、2、3、3周无需修复)

Trucks