Objective 每周函数 - 帮助编写代码 - CPLEX

Objective function per week - help writing the code - CPLEX

(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);

}
}

这看起来很可疑:

//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 决策变量或 FreshnessForest 的东西。相反,在 LINDO 模型中,Trucks 似乎是决策变量,并且也在数周内编入索引。

这是一个 OPL 模型,应该等同于您的 LINDO 模型(第 1、2、3 周没有修复:


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

// In the LINDO model not all variables are used. For example, variable
// X111 (which means going from pickup 1 to destination 1 in week 1) is
// never used. We use a tuple and a tuple set to list all the
// pickup/destination combinations that are actually used.
tuple P {
  string pickup;      // Pickup location
  string destination; // Destination location
}
{P} Pairs = { <"C", "D1">, // 31
              <"E", "D1">, // 51
              <"B", "D2">, // 22
              <"D", "D2">, // 42
              <"E", "D2">  // 52
};
int PickupCost[Pickup] = [ 140, 100, 90, 50, 10 ];

//Decision Variables
dvar int+ Trucks[Pairs][Weeks];

//Expressions
dexpr int Week1 = sum(p in Pairs) Trucks[p]["W1"] * PickupCost[p.pickup];
dexpr int Week2 = sum(p in Pairs) Trucks[p]["W2"] * PickupCost[p.pickup];
dexpr int Week3 = sum(p in Pairs) Trucks[p]["W3"] * PickupCost[p.pickup];
dexpr int Week4 = sum(p in Pairs) Trucks[p]["W4"] * PickupCost[p.pickup];


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


//Constraint
subject to {
  // Number of trucks
  forall(p in Pairs)
    sum(w in Weeks) Trucks[p][w] >= 1;

  // Week restriction
  // At least one truck must be used per week
  forall(w in Weeks)
    sum(p in Pairs) Trucks[p][w] >= 1;
}