首页 > 解决方案 > 每周目标函数 - 帮助编写代码 - 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);

}
}

标签: cplexopllexicographic

解决方案


This looks fishy:

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

In the expression for a single week you are summing variables for all weeks. I guess what you want instead is this:

//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"];

Note that the last index for Delivered is now constant in each expression. Each expression now only sums the variables for one single week.

Update: And there are other issues with your model: First of all, all the four constraints are exactly the same. You could just write them as a single constraint:

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

Then these constraints look strange since you sum over w in Weeks but the quantity you sum over (Trucks) is not indexed by weeks. And Trucks is not a decision variable either. So you are not really stating a constraint here but are just summing up constant values.

The next issue is that your decision variable Delivered does not appear in any constraint. So there is not much to optimize here.

You may want to go back and review what exactly should be optimized. What are the things the optimizer is allowed to change or must decide, what are the constraints, etc. For example, in your LINDO model I don't see anything that looks related to the Delivered decision variables or the Freshness or Forest things. Instead in the LINDO model it seems that Trucks are the decision variables and are also indexed over weeks.

Here is an OPL model that should be equivalent to your LINDO model (without fixing things for weeks 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;
}

推荐阅读