# Decision Optimization

View Only

## 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

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:

[...]

[...]

[...]

dexpr float usageOfCosts =

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

[...]

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

#DecisionOptimization