How to write a Cplex constraint for product types - optimization

I am trying to write a constraint in Cplex that will only allow certain types of items to be packed together (recipe) in a bin. I have all my product data in a tuple with the recipes represented by either "1" "2" or "3". My code so far:
{string} product = ...;
tuple ItemInfo {
int width;
float amps;
int recipe;
int demand;
}
ItemInfo Items[product] = ...;
dvar boolean x[Bin][product];
dvar boolean y[Bin];
minimize sum(b in Bin) y[b];
subject to {
forall(b in Bin) sum(j in product) Items[j].width*x[b][j] <= Width*y[b];
forall(b in Bin) sum(j in product) Items[j].amps*x[b][j] >= MinAmps*y[b];
forall(b in Bin) sum(j in product) Items[j].amps*x[b][j] <= MaxAmps*y[b];
forall(j in product) sum(i in Bin) x[i][j] == Items[j].demand;
}
Any ideas on how to ensure there is only one recipe per bin would be greatly appreciated! Thank you!

if you compute
{int} recipes={Items[i].recipe | i in product};
then you can write the constraint
forall(b in Bin) 1>=sum(r in recipes) (1<=sum(p in product:Items[p].recipe==r) x[b][p]);
which makes sure that you have max one recipe per bin
Full working example:
.mod
{string} product = ...;
tuple ItemInfo {
int width;
float amps;
int recipe;
int demand;
}
int Width=10;
int MinAmps=0;
int MaxAmps=20;
range Bin=1..3;
ItemInfo Items[product] = ...;
{int} recipes={Items[i].recipe | i in product};
dvar boolean x[Bin][product];
dvar boolean y[Bin];
minimize sum(b in Bin) y[b];
subject to {
forall(b in Bin) sum(j in product) Items[j].width*x[b][j] <= Width*y[b];
forall(b in Bin) sum(j in product) Items[j].amps*x[b][j] >= MinAmps*y[b];
forall(b in Bin) sum(j in product) Items[j].amps*x[b][j] <= MaxAmps*y[b];
forall(j in product) sum(i in Bin) x[i][j] == Items[j].demand;
forall(b in Bin) 1>=sum(r in recipes) (1<=sum(p in product:Items[p].recipe==r) x[b][p]);
}
and .dat
product={"A","B","C"};
Items=[<1,1,1,1>,<2,2,2,2>,<3,3,1,1>];

Related

how to print a result in cplex other than the decision variable

I want to print the value of pl[i]+pevdis[tvail][number]-pevch[tvail][number] as my result. The following is my code in Cplex.
int t=24;
int n=20;
int j=0;
range number =1..n;
range tavail=1..t;
float soc[number][tavail]=...;
//forcasted load at 0..4
float pl[tavail]=[10000000,7000000,9000000,6000000,12000000,6000000,4000000,15000000,9000000,12000000,6000000,8000000,10000000,7000000,9000000,6000000,12000000,6000000,4000000,15000000,9000000,12000000,6000000,8000000];
//soc of ev at 0..11
//generation
float pg[tavail]=[10000000,9500000,8500000,11000000,600000,7500000,10000000,9500000,8500000,11000000,600000,7500000,10000000,9500000,8500000,11000000,600000,7500000,10000000,9500000,8500000,11000000,600000,7500000];
//target load at 0..11
float pt[tavail]=[10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000];
//bus voltage at 0..11
float v[tavail]=[240,232,229,233,230,235,228,234,227,229,231,230,226,232,233,230,236,233,231,232,232,233,233,230];
//bus voltage at
// target bus voltage at 0..11
float vt[tavail]=[230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230];
//decision variable charging power ev
dvar float pevch[tavail][number] in 0..100000;
//decision variable discharging power of ev
dvar float pevdis[tavail][number] in 0..100000;
//levelised load
//objective function
minimize sum(i in tavail)((pt[i]-pl[i])+sum(j in number)-pevch[i][j]+sum(j in number)pevdis[i][j]);
subject to
{
forall(i in tavail,j in number)
if(pt[i]-pl[i]<0 && 0.7<soc[j][i]<0.9&& v[i]<vt[i])
pevdis[i][j]==soc[j][i]*100000;
else
pevdis[i][j]==0;
forall(i in tavail,j in number)
if(pt[i]-pl[i]>0 &&
soc[j][i]<=0.7 && v[i]>vt[i])
pevch[i][j]==soc[j][i]*100000;
else
pevch[i][j]==0;
}
After the subject to block you can do whatever printing you need.
For instance
minimize sum(i in tavail)((pt[i]-pl[i])+sum(j in number)-pevch[i][j]+sum(j in number)pevdis[i][j]);
subject to
{
forall(i in tavail,j in number)
if(pt[i]-pl[i]<0 && 0.7<soc[j][i]<0.9&& v[i]<vt[i])
pevdis[i][j]==soc[j][i]*100000;
else
pevdis[i][j]==0;
forall(i in tavail,j in number)
if(pt[i]-pl[i]>0 &&
soc[j][i]<=0.7 && v[i]>vt[i])
pevch[i][j]==soc[j][i]*100000;
else
pevch[i][j]==0;
}
int i=1;
int tvail=2;
int n2=3;
execute
{
writeln(
pl[i]+pevdis[tvail][n2]-pevch[tvail][n2] );
}

writing a boolean decision variable in cplex

PLEASE HELP ME: i have a boolean decision variable. moreover, set t itself in the domain of this variable should be calculated from an equation.**
Xro^t={1 if request r∈R_τ is assigned to offer o ∈ O_τ at time period t∈ Γ_ro,
0 Otherwise}
Γ_ro= [p, a]∩z
in this case, i am not sure if Γ_ro is a set or is a parameter?
You could rely on tuple set in order not to do the full Euclidian product:
range R=1..4;
range O=1..3;
int Tstart[r in R][o in O]=rand(5);
int Tend[r in R][o in O]=Tstart[r][o]+rand(4);
tuple rot
{
int r;
int o;
int t;
}
sorted {rot} rots={<r,o,t> | r in R,o in O,t in Tstart[r][o]..Tend[r][o]};
dvar boolean x[rots];
minimize sum(i in rots) x[i];
subject to
{
}

Write a forall constraint in CPLEX, indexing over a union of variables

I'm modelling a routing problem in CPLEX opl. I am struggling to implement a certain constraint in CPLEX, which sums a decision variable X over a set of indexes j, and this ∀i ∈ V, where V = C ⋃ S.
The constraint is the following: sum(j ∈ (1..10)) Xij < 1 ∀i ∈ V
I implemented this in CPLEX as follows:
forall(i in customers, i in stations) {
sum(j in reach) X[i][j] < 1; }
Customers refers to C, stations refers to S, and reach refers to the range of 1..10.
However, it seems impossible to use the same index (i) twice in the forall statement.
Could anyone help me to solve this problem.
Thanks a lot!
Instead of
forall(i in customers, i in stations) { sum(j in reach) X[i][j] <= 0; }
you could write
forall(i in customers union stations) { sum(j in reach) X[i][j] <= 0; }
I tried
{int} customers={1,2};
{int} stations={2,3};
{int} reach={5};
dvar boolean X[customers union stations][reach];
subject to
{
forall(i in customers union stations) { sum(j in reach) X[i][j] <= 0; }
}
and that works

How to minimize total cost of external resource in MRCPSP?

Hi I'm trying to make a model with objective function to minimize cost of mode 2 usage( mode with using external resource). I confuse when I want to make a limitation total time <=21 the result is no value, but when I set the time <= 50 the result was came out, although the result when I running the model only spending time 25.
tuple Task {
key int id;
{int} succs;
int RelDate;
}
{Task} Tasks = ...;
tuple Mode {
key int taskId;
key int id;
int pt;
int costprod;
int dmdIntRes [IntRes];
int dmdExtRes [ExtRes];
int ExtCost;
}
{Mode} Modes = ...;
dvar interval Taskss [t in Tasks] in t.RelDate..(maxint div 2)-1;
dvar interval mode[m in Modes] optional size m.pt;
dexpr int totaltime = sum(m in Modes) presenceOf(mode[m]) * ( m.pt); //boolean expression
//dexpr int totalExtCost = sum(m in Modes) presenceOf(mode[m])* (m.ExtCost * m.pt);
cumulFunction IntResUsage[r in IntRes] =
sum (m in Modes: m.dmdIntRes[r]>0) pulse(mode[m], m.dmdIntRes[r]);
cumulFunction ExtResUsage[r in ExtRes] =
sum (m in Modes: m.dmdExtRes[r]>0) pulse(mode[m], m.dmdExtRes[r]);
execute {
cp.param.FailLimit = 10000;
}
minimize sum(m in Modes) (m.ExtCost * m.pt) * maxl (presenceOf(mode[m]));
//minimize max(t in Tasks) endOf(Taskss[t]);
subject to {
//Alternative mode of resource productivity in Cost's unit
forall (t in Tasks, m in Modes) {
// if(m.costprod *m.pt == 0 && 0 <= 559717712) presenceOf(mode[first(Modes)]);
alternative(Taskss[t], all(m in Modes: m.taskId==t.id) mode[m]);
}
forall (t in Tasks, m in Modes)
(sum(t in Tasks)sum(m in Modes) m.costprod * m.pt <= 285740966 in 0..NbDays-14) != presenceOf(mode[first(Modes)]);
//External resource's budget limitation
forall ( t in Tasks, m in Modes )
totaltime <= 50;
//forall ( m in Modes )
//totalExtCost <= 30000000;
//Resource Usage
forall (r in IntRes)
IntResUsage[r] <= CapIntRes[r];
forall (r in ExtRes)
ExtResUsage[r] <= CapExtRes[r];
Could you simplify your model so that it illustrates your problem ?
I do not see any value 50 or 25 in the model.
Also:
I do not see why you are using a “max” here:
minimize sum(m in Modes) (m.ExtCost * m.pt) * maxl (presenceOf(mode[m]));
I do not see why you post this constraint for each task and each mode (!). It is independent from the tasks and the modes: forall ( t in Tasks, m in Modes ) { totaltime <= 100; }
By the way, for readability reasons, you could also rewrite your expressions: “presenceOf(mode[m]) * ( m.pt)” as “sizeOf(mode[m])”. If the model duration is a constant, both formulations should be more or less similar from a performance perspective, but if the duration is a decision variable, the formulation with “sizeOf(model[m])” will definitively be better.
For the 'min', you should neither use the min or the max as your are dealing with a singleton, you directly use the presenceOf.
So I would simplify the formulation as follows:
dvar interval Tasks [t in Tasks] in t.RelDate..(maxint div 2)-1;
dvar interval mode[m in Modes] optional size m.pt;
dexpr int totaltime = sum(m in Modes) sizeOf(mode[m]);
dexpr int totalExtCost = sum(m in Modes) (m.ExtCost*sizeOf(mode[m]));
cumulFunction IntResUsage[r in IntRes] =
sum (m in Modes: m.dmdIntRes[r]>0) pulse(mode[m], m.dmdIntRes[r]);
cumulFunction ExtResUsage[r in ExtRes] =
sum (m in Modes: m.dmdExtRes[r]>0) pulse(mode[m], m.dmdExtRes[r]);
execute {
cp.param.FailLimit = 10000;
}
minimize totalExtCost;
subject to {
// Alternative mode of resource productivity in Cost's unit
forall (t in Tasks)
alternative(Tasks[t], all(m in Modes: m.taskId==t.id) mode[m]);
// I have no hint what the constraints below are supposed to do !
// forall (t in Tasks, m in Modes)
// (sum(t in Tasks) sum(m in Modes) m.costprod * m.pt <= 285740966 in 0..NbDays-14) != presenceOf(mode[first(Modes)]);
// External resource's budget limitation
totaltime <= 50;
// totalExtCost <= 30000000;
// Resource Usage
forall (r in IntRes)
IntResUsage[r] <= CapIntRes[r];
forall (r in ExtRes)
ExtResUsage[r] <= CapExtRes[r];
}
Then I still do not understand the problem with limiting the "totalTime" to 50. It does not prevent to compute a solution with "totalTime=25" indeed, as 25<=50.
In fact I do not understand your problem. You seem to say that the problem with "totalTime<=21" is infeasible, and that when you post a constraint "totalTime<=50" it finds a solution where "totalTime=25". I don't see where is the problem here ...

How to make a if and else in alternative function in OPL?

I want to make if the earn value is not same with the plan then choose alternative 2, if same then choose alternative 1. I used tuple mode to determine the 2 alternative in OPL using CP(constraint programming)
I still stuck until this part
**subject to {
forall (p in Precedences, m in Modes) {
alternative(Tasks[p], all(m in Modes: m.taskId==p.id) mode[m]);**
thanks, I need this part to finish my master thesis, because I don't have a basic about programming
You can use presenceOf.
using CP;
int v=1;
// if v is 1 we choose a1p[1] , if not a1p[2];
dvar interval a1;
dvar interval a1p[i in 1..2] optional size i;
subject to {
alternative(a1, a1p);
(v==1) == (presenceOf(a1p[1])==1);
};
execute
{
writeln(a1);
}
gives
<1 0 1 1>
but if I change v=1 to v=2 then I get
<1 0 2 2>
thanks for response my question, I felt bless. this code plicable to using tuple? because I make my mode at tuple? when I tried using range 1..2 the dvar was error. this is my original code
tuple Mode {
key int taskId;
key int id;
int pt;
int costprod;
int dmdIntRes [IntRes];
int dmdExtRes [ExtRes];
}
{Mode} Modes = ...;
dvar interval Tasks [p in Precedences]in p.RelDate..EndMax ; //in p.RelDate..EndMax in 0..EndMax
dvar interval mode[m in Modes] optional size m.pt;
cumulFunction IntResUsage[r in IntRes] =
sum (m in Modes: m.dmdIntRes[r]>0) pulse(mode[m], m.dmdIntRes[r]);
cumulFunction ExtResUsage[r in ExtRes] =
sum (m in Modes: m.dmdExtRes[r]>0) pulse(mode[m], m.dmdExtRes[r]);
execute {
cp.param.FailLimit = 10000;
}
minimize max(p in Precedences) endOf(Tasks[p]);
subject to {
forall (p in Precedences, m in Modes) {
alternative(Tasks[p], all(m in Modes: m.taskId==p.id) mode[m]);