Search code examples
cplexprobability-distribution

Model leadtimes with a given probability distribution in Cplex


For my consolidation problem in Cplex, I want to make the travel time (leadtime) from origin terminal to gateway terminal 'emerge' with a given probability. The transportation from gateway to the final destination will then depend on this outcome. Here is a simplified version of my code where x is 1 if order n is shipped from terminal i to terminal j at time t:

int leadtime[terminal, terminal] = ...;
dvar int+ x[terminal, terminal, time, order] in 0..1;

forall(i terminal, j in terminal, d in terminal, t in time, n in order) x[i,j,t,n] <= x[j,d,t+leadtime[i,j],n];

The leadtime between origin and gateway is equal to 1 time period in 80% of the times, for example, and equal to 2 time periods in the remaining 20% of the time. I want to include different probability distributions for this. Is there a way to model this?

Thank you very much in advance! Kind regards


Solution

  • you can index your data with some scenarii and probabilities and then use array of your decisions variables per scenarii.

    Very simple example in Making optimization simple

    /*

    Now let's suppose all those options have some probabilities and we need to book buses the day before but in real time in the morning we may book some additional buses with an extra price. (+10%) This is stochastic optimization. We want to minimize average cost. We call extra buses recourse variables. In OPL, it is quite simple to move from a deterministic model to a stochastic model: */

    int nbKids=300;
    
    {int} nbKidsScenarii={nbKids+i*10 | i in -10..2};
    float proba[nbKidsScenarii]=[ 1, 1, 2, 2, 2 ,3 ,3 ,4,  5 ,10 ,50 ,10, 7];
    
    assert sum(s in nbKidsScenarii) proba[s]==100; // total probability is 100
    
    float costBus40=500;
    float costBus30=400;
    
    float costIncreaseIfLastMinute=1.1;
    
    // number of buses booked in advance
    dvar int+ nbBus40;
    dvar int+ nbBus30;
    // number of buses booked at the last minute which is far more expensive
    // we call those recourse decision
    dvar int+ nbBus40onTop[nbKidsScenarii] ;
    dvar int+ nbBus30onTop[nbKidsScenarii] ;
     
    minimize
     costBus40*nbBus40  +nbBus30*costBus30
     +
    1/100*costIncreaseIfLastMinute*
    sum(nbKids in nbKidsScenarii) proba[nbKids]*(costBus40*nbBus40onTop[nbKids]  +nbBus30onTop[nbKids]*costBus30);
     
    subject to
    {
    
    
     forall(nbKids in nbKidsScenarii)
       ctKids:40*(nbBus40+nbBus40onTop[nbKids])+(nbBus30+nbBus30onTop[nbKids])*30>=nbKids;
    }
    
    execute
    {
    writeln("nbBus40 = ",nbBus40);
    writeln("nbBus30 = ",nbBus30);
    writeln();
    writeln("nbBus40 on top = ",nbBus40onTop);
    writeln("nbBus30 on top = ",nbBus30onTop);
    }
    

    gives

    // solution (optimal) with objective 3775.5
    nbBus40 = 6
    nbBus30 = 0
    nbBus40 on top =  [0 0 0 0 0 0 0 0 1 0 0 1 2]
    nbBus30 on top =  [0 0 0 0 0 1 1 1 0 2 2 1 0]