# Decision Optimization

View Only

## heightAtEnd

• #### 1.  heightAtEnd

Posted Fri April 03, 2020 11:46 AM

Originally posted by: AndyHam

Can you please help me out to understand heightAtEnd? I would like to subtract the cum function value from the starting value as tasks are being completed. The following code failed to keep track of the cum function. Namely, the initial value of 100 does not change. I could not identify my error. Thanks!

using CP;
range M=1..2;
range J=1..5;
dvar interval T[j in J] size j*10;
dvar interval T2M[J][M] optional;
dvar sequence seqM[m in M] in all(j in J) T2M[j][m];

cumulFunction cumf[m in M]= step(0,100)
- sum(j in J) stepAtEnd (T2M[j][m], 0, 100);

minimize max(j in J) endOf(T[j]);
constraints {
forall(j in J) alternative(T[j], all(m in M) T2M[j][m] );

forall(m in M, j in J) heightAtEnd(T2M[j][m],cumf[m]) == - sizeOf(T2M[j][m]);

forall(m in M) noOverlap(seqM[m]);
}

#DecisionOptimization
#OPLusingCPOptimizer

• #### 2.  Re: heightAtEnd

Posted Mon April 06, 2020 04:29 AM

Originally posted by: Petr Vilím

Hello Andy,

I think the problem is that capacity of cumul function cumulf[m] is not constrained, there are only heightAtEnd expressions.

Cumul functions are implicitly constrained to be >= 0. However it is done only for those cumul functions that have some another capacity constraint (heightAtEnd is not counted). So I think that the following constraint should fix the problem:

```forall(m in M)
cumf[m] >= 0;
```

Best regards, Petr

#DecisionOptimization
#OPLusingCPOptimizer

• #### 3.  Re: heightAtEnd

Posted Mon April 06, 2020 06:11 AM

Originally posted by: AndyHam

Thanks! Once I have added the constraint, it worked.
However, I encountered another issue when I changed the heightAtEnd constraint as follow:
forall(m in M, j in J) heightAtEnd(T2M[j][m],cumf[m]) == - 1; //sizeOf(T2M[j][m]);
It should simply subtract by 1 from the initial value as the machine is completing tasks.
Instead, the model generates "conflict error".

using CP;
range M=1..2;
range J=1..5;
dvar interval T[j in J] size j*10;
dvar interval T2M[J][M] optional;
dvar sequence seqM[m in M] in all(j in J) T2M[j][m];

cumulFunction cumf[m in M]= step(0,100)
- sum(j in J) stepAtEnd (T2M[j][m], 0, 100);

minimize max(j in J) endOf(T[j]);
constraints {
forall(j in J) alternative(T[j], all(m in M) T2M[j][m] );
forall(m in M, j in J) heightAtEnd(T2M[j][m],cumf[m]) == - 1; //sizeOf(T2M[j][m]);
forall(m in M) noOverlap(seqM[m]);
forall(m in M) cumf[m] >= 0;
}

#DecisionOptimization
#OPLusingCPOptimizer

• #### 4.  Re: heightAtEnd

Posted Tue April 07, 2020 04:00 AM

Originally posted by: Petr Vilím

Hello Andy,

I exported your model into a cpo file model.cpo. Then I run cpoptimizer executable, imported the model using "read model.cpo", then I computed the conflict by "tools conflict" and finally displayed the conflict by "display conflict". Here is the output:

```alternative("T(5)", ["T2M(5)(1)", "T2M(5)(2)"], 1);
-1 == heightAtEnd("T2M(5)(1)", "cumf(1)");
-1 == heightAtEnd("T2M(5)(2)", "cumf(2)");
```

The problem is that constraint -1 == heightAtEnd("T2M(5)(1)", "cumf(1)") is forcing interval variable T2M(5)(1) to be present because heightAtEnd of an absent interval variable is 0. Similarly T2M(5)(2) must be present. However the constraint "alternative" says that only one of them should be present.

It was working before with sizeOf because sizeOf of an absent interval variable is zero (unless specified otherwise by additional parameter to sizeOf).

Similar to sizeOf, heightAtEnd accepts also additional parameter to specify the value when the interval variable is absent. So if you want to constraint the height only for the case the interval is present you can use that additional parameter:

```-1 == heightAtEnd("T2M(5)(2)", "cumf(2)", -1);
```

This way, if the interval variable is absent then heightAtEnd returns -1 and therefore the constraint will be satisfied.

Best regards, Petr

#DecisionOptimization
#OPLusingCPOptimizer

• #### 5.  Re: heightAtEnd

Posted Tue April 07, 2020 08:05 AM

Originally posted by: AndyHam

I have made many different attempts but all failed. The last thing I tried was to make another interval variable (move) that has the size of travel distance.
Then, I feed the heightAtEnd with sizeOf(move[j][t]).

presenceOf(itvJ2T[j][t])==presenceOf(move[j][t]);
startOf(itvJ2T[j][t])==startOf(move[j][t]);
sizeOf(move[j][t])==dNtoN[j.id][typeOfNext(seqTrk[t], itvJ2T[j][t], j.id, j.id)];
heightAtEnd(itvJ2T[j][t],cumBattery[t]) ==  -sizeOf(move[j][t]) ;

If you can shed some light, it will be great!.

Hi Petr,
Thanks for looking into the issue. I think I understand the cause.
Now, I am trying to port the lesson to my battery-charging VRP problem.
I still could not make the code work. I am enclosing the entire model and data files.
The problematic codes are showing below.
I sincerely appreciate your help.

cumulFunction cumBattery[t in Trucks]=  step(0, Q)      // initial Battery level
- sum(j in aJobs) stepAtStart (itvJ2T[j][t], 0, Q)            //Battery consumption
+ sum(j in aJobs: j.t=="f") stepAtEnd (itvJ2T[j,t], 0, Q); //Battery recharging

forall(j in aJobs,t in Trucks) //Battery consumption
// heightAtStart(itvJ2T[j][t],cumBattery[t],0) == - dNtoN[j.id][typeOfNext(seqTrk[t], itvJ2T[j][t], j.id, j.id)];
heightAtStart(itvJ2T[j][t],cumBattery[t],-dNtoN[j.id][typeOfNext(seqTrk[t], itvJ2T[j][t], j.id, j.id)]) == - dNtoN[j.id][typeOfNext(seqTrk[t], itvJ2T[j][t], j.id, j.id)];
heightAtStart(itvJ2T[j][t],cumBattery[t],0) == - presenceOf(itvJ2T[j][t])*dNtoN[j.id][typeOfNext(seqTrk[t], itvJ2T[j][t], j.id, j.id)];

forall(j in aJobs,t in Trucks: j.t=="f")  //Battery charging
heightAtEnd(itvJ2T[j][t],cumBattery[t])  == g*sizeOf(itvJ2T[j][t]);

Thanks,
Andy

#DecisionOptimization
#OPLusingCPOptimizer

• #### 6.  Re: heightAtEnd

Posted Thu April 09, 2020 11:10 AM

Originally posted by: Petr Vilím

Hello Andy,

I'm sorry, I don't understand what is the problem now. The attached model finds a solution easily. You don't like the solution for some reason? Is something wrong with it?

Petr

#DecisionOptimization
#OPLusingCPOptimizer

• #### 7.  Re: heightAtEnd

Posted Thu April 09, 2020 11:21 AM

Originally posted by: AndyHam

Sorry to make you confused.
The cumBattery is not being calculated correctly. After the initial value of 78 is set, the function value should have been updated as the vehicle tour progresses.
I am enclosing the screen capture of the function value.

#DecisionOptimization
#OPLusingCPOptimizer

• #### 8.  Re: heightAtEnd

Posted Tue April 14, 2020 04:19 AM

Originally posted by: Petr Vilím

Hello Andy,

I think the problem is that cumBattery is not constrained in other ways than by heightAtStatrt/End (similarly as cumf was not constrained at the beginning of our discussion). I think the following additional constraint should fix it:

```forall(t in Trucks) {
cumBattery[t] >= 0;
}
```

However then the problem doesn't have any solution. There are other too strong constraints?

Petr

#DecisionOptimization
#OPLusingCPOptimizer

• #### 9.  Re: heightAtEnd

Posted Tue April 14, 2020 07:52 AM

Originally posted by: AndyHam

The code works well without the battery related codes, meaning the battery is causing issue. So I increased the battery capacity to a big number so that a vehicle does not need to visit a charge station. But the cum function still failed to track the battery consumption at any visit.

I tried all possible trials I can imagine, but all failed.

Thanks,

Andy

#DecisionOptimization
#OPLusingCPOptimizer