Decision Optimization

 View Only
Expand all | Collapse all

RCPSP & CP Optimizer: cumulFunction

  • 1.  RCPSP & CP Optimizer: cumulFunction

    Posted Mon March 16, 2020 08:17 AM

    Originally posted by: fw2610


    Hi,

    I am working on a model similar to the RCPSP. In the model activities have to be done by workers. A renewable resource (workers) and a non-renewable resource (money, respectively costs) are used. If a worker is deployed, it costs money every period. Both resources are limited due to capacities:

    [...]

    int capacityOfWorkers = ...;
    int capacityOfCosts = ...;
    float periodicCostRate = ...;

    [...]

    tuple activity {
        key int numberOfActivity;

    [...]

    }
    {activity } activities = ...;

    tuple modeOfActivity {
        key int numberOfActivity;
        key int numberOfMode;
        int durationOfMode;
        int workersOfMode;

    {modeOfActivity} modesOfActivity = ...;

    [...]

    dvar interval performOfActivity [i in activities] optional;
    dvar interval usageOfMode[m in modesOfActivity] optional size m.durationOfMode;

    [...]

    cumulFunction usageOfWorkers =
        sum (m in modesOfActivity)
            pulse (usageOfMode[m], m.workersOfMode);
    dexpr float usageOfCosts = 
         sum (m in modesOfActivity)
             presenceOf (usageOfMode[m]) * m.durationOfMode *
             m.workersOfMode* periodicCostRate;

    [...]

        forall (i in activities)
            alternative (performOfActivity[i],
                all (m in modesOfActivity: m.numberOActivity == i.numberOActivity)
                    usageOfMode[m]);

         usageOfWorkers <= capacityOfWorkers;
         usageOfCosts <= capacityOfCosts;

    [...]

    My question: I want to set up an additional periodic cost rate for a number of deployed workers above a determined level. Please look at the attached file: The capacity of workers is 60. If 50 or less workes are deployed, they cause the normal periodic cost rate. If the remaining 10 workers are deployed (above the red line), they should cause the normal periodic cost rate plus an additional periodic cost rate.

    I have no idea how to set up a dexpr float additionalUsageOfCosts. Unfortunately the function cumulFunctionValue can only be used after a solution has been calculated.

     

    Thank you for help and best regards!


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 2.  Re: RCPSP & CP Optimizer: cumulFunction

    Posted Fri March 20, 2020 03:53 AM

    Hi,

    what you could do is change

    usageOfWorkers <= capacityOfWorkers; 

    into

    usageOfWorkers <= capacityOfWorkers- slackWorkers; // 60

    with slackWorkers a positive dvar integer

    See https://www.ibm.com/developerworks/community/forums/html/topic?id=d74384cc-ffbd-4db2-845c-aa1f8a78280c&ps=25

    And then you write a logical constraint that will set a cost according to whether slackWorkers is more or less than 10.

    regards

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 3.  Re: RCPSP & CP Optimizer: cumulFunction

    Posted Fri March 20, 2020 10:40 AM

    Originally posted by: fw2610


    Hi Alex,

    thank you very much for this interesting hint. I added to my model:

    [...]

    float additionalPeriodicCostRate = ...;

    int capacityOfAdditionalWorkers = ...;

    [...]

    dvar int usageOfAdditionalWorkers;

    [...]

    dexpr float usageOfCosts =

         usageOfAdditionalWorkers * additionalPeriodicCostRate +
         sum (m in modesOfActivity)
              presenceOf (usageOfMode[m]) * m.durationOfMode *
              m.workersOfMode* periodicCostRate;

    [...]

         usageOfAdditionalWorkers <= capacityOfAdditionalWorkers; // x <= 10

         usageOfWorkers <= capacityOfWorkers - usageOfAdditionalWorkers ; // y <= 60 - x

    [...]

    Now, the used additional workers (maximum 10) are paid with the normal periodic cost rate and the additional periodic cost rate. Unfortunately they are paid with the additional cost rate the whole time. My intent is to pay them only the time they work (in the attached schedule of my recent post: period 6 to 11 and 12 to 24) similar to the normal periodic cost rate.

    Do you have another idea for this? Thank you very much.

     

    Best regards


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 4.  Re: RCPSP & CP Optimizer: cumulFunction

    Posted Fri March 20, 2020 02:11 PM

    Hi

    let me try to help with a much simpler example.

    The first way I gave you is global.

    In a nutshell

    using CP;
     
     {string} workers={"A","B"};
     int nbTotalWorkers;
     int nbMaxWorkers=1; // beyond 1 we have to pay overtime
     
     dvar interval itvs[workers] in 0..2;
     dvar boolean overTime;
     
     
     cumulFunction cumulWork=sum(w in workers) pulse(itvs[w],1);
     dexpr float cost=overTime;
     dexpr float unfairness=max(w in workers) lengthOf(itvs[w])-min(w in workers) lengthOf(itvs[w]);
     
     minimize staticLex(cost,unfairness);
     
     subject to
     {
     // demand
     
     alwaysIn(cumulWork,0,1,1,10);
     alwaysIn(cumulWork,1,2,2,10);
     
     // max workers
     cumulWork<=nbMaxWorkers+overTime;
     
     }

    gives a flat cumul for cumulWork

     

    But what you need is a bit more subtle.

     

    using CP;
     
     {string} workers={"A","B"};
     int nbTotalWorkers;
     int nbMaxWorkers=1; // beyond 1 we have to pay overtime
     
     dvar interval itvs[workers] in 0..2;
     dvar interval overTime[i in 0..2]  optional in i..i+1 size 1;
     
     
     cumulFunction cumulWork=sum(w in workers) pulse(itvs[w],1);
     cumulFunction cumulWorkMinusOverTime=sum(w in workers) pulse(itvs[w],1)-sum(i in 0..2)pulse(overTime[i],1);
     dexpr float cost=sum(i in 0..2) presenceOf(overTime[i]);
     dexpr float unfairness=max(w in workers) lengthOf(itvs[w])-min(w in workers) lengthOf(itvs[w]);
     
     minimize staticLex(cost,unfairness);
     
     subject to
     {
     // demand
     
     alwaysIn(cumulWork,0,1,1,10);
     alwaysIn(cumulWork,1,2,2,10);
     
     // max workers
     cumulWorkMinusOverTime<=nbMaxWorkers;
     
     }

     

    gives

     

     

    for cumulWork.

     

    This is inline with your request to measure overtime per time slot and not globally

     

    regards

     

    https://www.linkedin.com/pulse/making-decision-optimization-simple-alex-fleischer/

     


    #DecisionOptimization