0

I am stuck with a flow control problem and failed to get a way out from the given CPLEX examples. I want to solve the optimization problem for 16 times, and the only thing that differs is the input of demand. (Because we have trouble running the “SheetConnection” code in our server so I want to build the model that reads raw data from dat file).

I have 16 demands for 16 different periods. For the 1st run, I want the demand of the model to be the 1st number of the demand array. And for the nth run, the demand of the model to be the nth number of the demand array.

I have already modified the model from the CPLEX example “mulprod”, but I found that the example changes the capacity of flour increasingly (by adding 1 unit every time). So, it didn’t mention how to read the data in order. I guess the problem lies in if I want to set Demand as a range in the beginning, then my code to call the nth number is problematic.

/*mod.file*/
{string} Units_ = ...;
int NbUnits = ...;
range Units = 1..NbUnits;
int NbLoops = ...;

float Demand[1..16] = ...;
float MaxGen [Units] = ...; 
float MinGen [Units] = ...; 
float MarginalC [Units] = ...; 

dvar boolean Opr [u in Units];
dvar float+ Gen [u in Units] in 0..MaxGen [u];

execute {
  writeln("* This OPL model is not compliant with cloud execution");
}

minimize 
  sum(u in Units) (Gen[u] * MarginalC[u]);

subject to {
//Meet demand       
      ctPowerBalance: 
        sum(u in Units) Gen[u] == Demand;  
//Max/Min Unit Constraints           
    forall(u in Units)
      ctMaxGeneration:
        Gen[u] <= MaxGen[u]*Opr[u];
    forall(u in Units)
      ctMinGeneration:
        Gen[u] >= MinGen[u]*Opr[u];
}

tuple plan {
  float Operation;
  float Generation;
}

plan Plan[u in Units] = 
  <Opr[u], Gen[u]>;



main {
  thisOplModel.generate();

  var produce = thisOplModel;
  var Demandt = produce.Demand_[NbLoops];

  var best;
  var curr = Infinity;
  var ofile = new IloOplOutputFile("BAU_T2030.txt");
  while ( 1 ) {
    best = curr;
    writeln("Solve with Demand[", NbLoops, "] is ", Demandt);
    if ( cplex.solve() ) {
      curr = cplex.getObjValue();
      writeln();
      writeln("OBJECTIVE: ",curr);
      ofile.writeln("Objective with Demand[", NbLoops, "] is ", curr);
      ofile.writeln("plan = ",produce.Plan);      
} 
    else {
      writeln("No solution!");
      break;
    }
    if ( best==curr ) break;

NbLoops ++;
    for(var Demand in thisOplModel.Demand)          
      thisOplModel.ctPowerBalance[Demand].UB = Demandt;
  }

  ofile.close();

  0;
}

/*dat.file*/
Units_ = {G11, G12, G13, G14, G15};
NbUnits = 5;
NbLoops = 1;
Demand = [1133.16, 1826.47, 1304.79, 1330.03, 1556.02, 1952.19, 1124.82, 1622.05, 1567.69, 1499.43, 1315.01, 1135.05, 1029.67, 1949.19, 1972.64, 1812.24];
MaxGen = [519.2, 665.6, 46.5, 212, 464];
MarginalC = [55.21, 36.32, 41.62, 34.16, 36.71]; 
xz284
  • 3
  • 1

1 Answers1

0

this is flow control with incremental in https://www.linkedin.com/pulse/making-decision-optimization-simple-alex-fleischer/

.mod

{string} Units_ = ...;
int NbUnits = ...;
range Units = 1..NbUnits;
int NbLoops = ...;

float Demand[1..16] = ...;
float MaxGen [Units] = ...; 
float MinGen [Units] = ...; 
float MarginalC [Units] = ...; 

dvar boolean Opr [u in Units];
dvar float+ Gen [u in Units] in 0..MaxGen [u];

dvar float currentDemand;

execute {
  writeln("* This OPL model is not compliant with cloud execution");
}

minimize 
  sum(u in Units) (Gen[u] * MarginalC[u]);

subject to {
//Meet demand       
      ctPowerBalance: 
        sum(u in Units) Gen[u] == currentDemand;  
//Max/Min Unit Constraints           
    forall(u in Units)
      ctMaxGeneration:
        Gen[u] <= MaxGen[u]*Opr[u];
    forall(u in Units)
      ctMinGeneration:
        Gen[u] >= MinGen[u]*Opr[u];
}

tuple plan {
  float Operation;
  float Generation;
}

plan Plan[u in Units] = 
  <Opr[u], Gen[u]>;



main {
  thisOplModel.generate();
 var NbLoops=1;
  var produce = thisOplModel;


  var best;
  //var curr = Infinity;
  var ofile = new IloOplOutputFile("BAU_T2030.txt");
  while ( NbLoops<=16 ) {
    var Demandt = produce.Demand[NbLoops];
    //best = curr;
    writeln("Solve with Demand[", NbLoops, "] is ", Demandt);
    if ( cplex.solve() ) {
      curr = cplex.getObjValue();
      writeln();
      writeln("OBJECTIVE: ",curr);
      ofile.writeln("Objective with Demand[", NbLoops, "] is ", curr);
      ofile.writeln("plan = ",produce.Plan);      
} 
    else {
      writeln("No solution!");
      //break;
    }
    //if ( best==curr ) break;

NbLoops ++;
    //for(var Demand in thisOplModel.Demand)          
      thisOplModel.currentDemand.UB = Demandt;
      thisOplModel.currentDemand.LB = Demandt;
  }

  ofile.close();

  0;
}

.dat

Units_ = {G11, G12, G13, G14, G15};
NbUnits = 5;
NbLoops = 16;
Demand = [1133.16, 1826.47, 1304.79, 1330.03, 1556.02, 1952.19, 1124.82, 1622.05, 1567.69, 1499.43, 1315.01, 1135.05, 1029.67, 1949.19, 1972.64, 1812.24];
MaxGen = [519.2, 665.6, 46.5, 212, 464];
MinGen = [];
MarginalC = [55.21, 36.32, 41.62, 34.16, 36.71]; 

works better

Alex Fleischer
  • 5,860
  • 2
  • 8
  • 10
  • Thank you very much, Alex! The code works! I am going to read through the linkedin webpage carefully! Thanks! – xz284 May 25 '20 at 16:57