cplex error: cos float doesnot exists i.e,showing error while typing cos and sin functions - error-handling

error correction. I have to include cos and sin functions in my model.But it is showing error.I have tried the expression Math.cos and Opl.cos But both won't work. The error is after the forall statement,and iam facing this error after including the cos function.
float c1[0..3]=[50,0,0,50];
float c2[0..3]=[351,0,0,389];
float c3[0..3]=[44.6,0,0,40.6];
float pd[0..3]=[50,170,200,80];
float qd[0..3]=[10,20,30,40];
float V[0..3]=[1.0,1.0,1.0,1.0];
float del[0..3]=[0,0,0,0];
/*float pg[1..4]=[10,0,0,10];*/
float p[0..3];
float q[0..3];
int i=0;
float G[0..3][0..3]=[ [5.724138, -1.724138,0,-4],
[-1.724138,4.224138,-2.5,0],
[0,-2.5,4.386792,-1.886792],
[-4,0,-1.886792,5.886792]];
float B[0..3][0..3]=[ [-12.31034,4.310345,0,8],
[4.310345,-11.810340,7.5,0],
[0,7.5,-14.10377,6.603774],
[8,0,6.603774,-14.603770]];
dvar float+ pg[0..3];
dvar float+ Qg[0..3];
minimize sum(i in 0..3)(c1[i]*pg[i]^2 + c2[i]*pg[i] + c3[i]);
subject to
{forall(i in 0..3)
p[i]==V[i]*(sum(j in 0..3)(V[j]*(G[i][j]*cos(del[i]-del[j]))));
p[i]-pg[i]+pd[i]==0;
forall(i in 0..3)
q[i]==V[i]*(sum(j in 0..3)(V[j]*(G[i][j])));
q[i]-Qg[i]+qd[i]==0;
//forall(i in 0..3)
// pg[i]<=30;
}

cos is not linear so you cannot use cos in a MIP model within CPLEX.
If you need non linear function you could either use:
CPOptimizer within CPLEX
approximate with a piecewise linear function
But in your case you use cos of data so you can write the following model that works fine:
float c1[0..3]=[50,0,0,50];
float c2[0..3]=[351,0,0,389];
float c3[0..3]=[44.6,0,0,40.6];
float pd[0..3]=[50,170,200,80];
float qd[0..3]=[10,20,30,40];
float V[0..3]=[1.0,1.0,1.0,1.0];
float del[0..3]=[0,0,0,0];
/*float pg[1..4]=[10,0,0,10];*/
float p[0..3];
float q[0..3];
int i=0;
float deltacos[0..3][0..3];
range r=0..3;
execute fill_deltacos
{
for(var i in r) for (var j in r) deltacos[i][j]=Math.cos(del[i]-del[j]);
}
float G[0..3][0..3]=[ [5.724138, -1.724138,0,-4],
[-1.724138,4.224138,-2.5,0],
[0,-2.5,4.386792,-1.886792],
[-4,0,-1.886792,5.886792]];
float B[0..3][0..3]=[ [-12.31034,4.310345,0,8],
[4.310345,-11.810340,7.5,0],
[0,7.5,-14.10377,6.603774],
[8,0,6.603774,-14.603770]];
dvar float+ pg[0..3];
dvar float+ Qg[0..3];
minimize sum(i in 0..3)(c1[i]*pg[i]^2 + c2[i]*pg[i] + c3[i]);
subject to
{forall(i in 0..3)
p[i]==V[i]*(sum(j in 0..3)(V[j]*(G[i][j]*deltacos[i][j])));
p[i]-pg[i]+pd[i]==0;
forall(i in 0..3)
q[i]==V[i]*(sum(j in 0..3)(V[j]*(G[i][j])));
q[i]-Qg[i]+qd[i]==0;
//forall(i in 0..3)
// pg[i]<=30;
}

Related

CPLEX, replace variable with a constant

I already have a CPLEX model with variables x[0], x[1],...,x[n-1]. In order to create heuristics, I need to insert constants instead of all but one variable.
Say, I will keep x[0] and instead of x[i] I will insert constants a[i] (i=1,...,n-1).
One way to do this is to create a new model where variables will be replaced by constants manually. The model is big and I would need go through entire code to do this.
Is there another way?
What if I insert additional constraints: x[i]==a[i] (i=1,...,n-1) into the model? Will x[i] be converted to constants at the very beginning or the model with n variables (x[i], i=0,...,n-1) will be solved?
You can set Upper bound and lower bound on any decision variable to make it a constant.
For instance, with the zoo example , in OPL you can write
int nbKids=300;
float costBus40=500;
float costBus30=400;
float costBus50=700;
dvar int+ nbBus40;
dvar int+ nbBus30;
dvar int+ nbBus50;
minimize
costBus40*nbBus40 +nbBus30*costBus30+nbBus50*costBus50;
subject to
{
ctKids:40*nbBus40+nbBus30*30+nbBus50*50>=nbKids;
}
execute
{
writeln(nbBus30," ",nbBus40," ",nbBus50, " buses");
}
main
{
thisOplModel.generate();
cplex.solve();
thisOplModel.postProcess();
thisOplModel.nbBus50.UB=2;
thisOplModel.nbBus50.LB=2;
cplex.solve();
thisOplModel.postProcess();
}
that gives
2 6 0 buses
0 5 2 buses

Can Cplex prioritize some variables so that they're likely to be chosen together?

So my problem contains a vehicle that moves from one node to the next. I have a bunch of nodes that may or may not be related to each other. I want the nodes that are similar to each other to be visited by the vehicle as much as possbible.
Is there any possible ways that i can prioritize the related nodes so that they're more likely to be grouped together? I thought to create sets or tuples that represent the different groups, and to have a variable X[i][j] = 1 if the vehicle moves from node i to node j, but i'm stuck at the "prioritize i and j if they come from the same set" part. Is it the boolean value that makes it impossible to render that? Should I modify my formulations somehow?
This is my code for the problem for now, i still haven't come out with the priority part
int nNode = 20;
range N = 1..nNode; //set of locations to visit
range V = 0..nNode; //set of locations plus the depot
range Vehicle = 1..6; //there are six vehicles
range boxType = 1..3; //three types of boxes to be transported
int demand[V][boxType] =...; //demand for a location in terms of different boxes
int timeBox[boxType] =...; //time associated with the actions on a type of box
dvar int+ totalLoad[Vehicle];
dvar int+ load[Vehicle][boxType]; //load in terms of box type
dvar boolean X[V][V][Vehicle]; /*1 if the vehicle Vehicle goes from node V to the
next node, 0 if not*/
dvar int+ t[Vehicle]; //total time a vehicle spends
dvar int time[Vehicle]; /*equals |t[vehicle] - target cycle time|, this is to make sure
each vehicle spends as close to target cycle time as possible*/
minimize sum (v in Vehicle)time[v];
subject to
{
forall (i in V)
sum (j in V, k in Vehicle)X[i][j][k] == 1; /* so that each starting node will have
exactly one destination node, i.e it will belong to exactly 1 route only*/
forall (j in V)
sum (i in V, k in Vehicle)X[i][j][k] == 1; // similar but for ending node
forall (k in Vehicle)
totalLoad[k] == sum(i in V, j in V)X[i][j][k]* (sum(b in boxType)demand[j][b]); /*total
load of a vehicle equals the total boxes collected at each stop on its path */
forall (b in boxType, k in Vehicle)
load[k][b] == sum(i in V, j in V) X[i][j][k]*(sum(j in Vehicle)demand[j][b]); /* calculate
separate number of boxes for each route*/
forall (k in Vehicle)
{
time[k] >= t[k] - 1.5;
time[k] >= - t[k] + 1.5;
time[k] <= t[k] + 1.5;
time[k] <= 2 - t[k] - 1.5; // breakdown of time[k] = |t[k]-1.5|, 1.5 is target cycle time
t[k] == sum(b in boxType) load[k][b]*timeBox[b]; // calculate the total time involved in a route
}
}
You could try adding a term into your objective that penalises giving different values to those sets of variables. Easy enough if there are only two of them but more fiddly if there are bigger subsets and/or lots of subsets to coordinate.
I would do something along the lines of what Tim suggested. Here is a little bit more meat on the bones:
x[i,j,k]=1 => L[g] ≤ k ∀i∈g, ∀j,k A lowerbound on the route k for group g
x[i,j,k]=1 => U[g] ≥ k ∀i∈g, ∀j,k An upperbound on the route k for group g
U[g]-L[g] ≥ 1 => δ[g]=1 δ[g]=1 if g is on different routes
min sum(g,δ[g]) objective
δ[g] ∈ {0,1} δ[g] is a binary variable
One way to implement the first 3 equations is:
L[g] ≤ k⋅x[i,j,k] + M(1-x[i,j,k]) ∀i ∈ g, ∀j,k
U[g] ≥ k⋅x[i,j,k] ∀i ∈ g, ∀j,k
M⋅δ[g] ≥ U[g]-L[g]
here g indicates a group. This makes the problem a multi-objective problem, so you can choose from a few possible approaches for that.
you could use priorities if you do not want to change the model from a logical point of view.
See https://github.com/AlexFleischerParis/zooopl/blob/master/zoopriorities.mod
int nbKids=300;
float costBus40=500;
float costBus30=400;
dvar int+ nbBus40;
dvar int+ nbBus30;
execute
{
nbBus40.priority=100;
nbBus30.priority=0;
}
minimize
costBus40*nbBus40 +nbBus30*costBus30;
subject to
{
40*nbBus40+nbBus30*30>=nbKids;
}
in Making optimization Simple
If you want to change the model from a logical point of view you can change the objective or add a second objective
int nbKids=350;
float costBus40=400;
float costBus30=300;
dvar int+ nbBus40;
dvar int+ nbBus30;
dexpr float absdistancebetweennumbers=abs(nbBus40-nbBus30);
minimize
staticLex(costBus40*nbBus40 +nbBus30*costBus30,absdistancebetweennumbers);
subject to
{
40*nbBus40+nbBus30*30>=nbKids;
}

How to code Epsilon constraint method in CPLEX

How to solve a bi-/multi-objective problem by the Epsilon constraint method in CPLEX using OPL?
Thanks!
In OPL CPLEX you can directly use multiobjective
int nbKids=200;
float costBus40=500;
float costBus30=400;
float costBus50=625;
dvar int+ nbBus40;
dvar int+ nbBus30;
dvar int+ nbBus50;
dvar float cost;
dvar float co2emission;
minimize
staticLex(cost,co2emission);
subject to
{
cost==costBus40*nbBus40 +nbBus30*costBus30+nbBus50*costBus50;
co2emission==nbBus50+nbBus40*1.1+nbBus30*1.2;
40*nbBus40+nbBus30*30+nbBus50*50>=nbKids;
}
execute DISPLAY_After_SOLVE
{
writeln("The minimum cost is ",cost);
writeln("CO2 emission is ",co2emission);
writeln("We will use ",nbBus40," 40 seats buses ",nbBus30,
" 30 seats buses and ", nbBus50," buses 50 seats");
}
but if you prefer to use flow control you can write
int nbKids=200;
float costBus40=500;
float costBus30=400;
float costBus50=625;
dvar int+ nbBus40;
dvar int+ nbBus30;
dvar int+ nbBus50;
dvar float cost;
dvar float co2emission;
minimize
cost+co2emission;
subject to
{
cost==costBus40*nbBus40 +nbBus30*costBus30+nbBus50*costBus50;
co2emission==nbBus50+nbBus40*1.1+nbBus30*1.2;
40*nbBus40+nbBus30*30+nbBus50*50>=nbKids;
}
execute DISPLAY_After_SOLVE
{
writeln("The minimum cost is ",cost);
writeln("CO2 emission is ",co2emission);
writeln("We will use ",nbBus40," 40 seats buses ",nbBus30,
" 30 seats buses and ", nbBus50," buses 50 seats");
}
main
{
var epsilon=0.01;
thisOplModel.generate();
// remove co2emission from the objective by setting coef 0
cplex.setObjCoef(thisOplModel.co2emission,0);
cplex.solve();
thisOplModel.postProcess();
var cost=thisOplModel.cost.solutionValue;
// add a new constraint that cost should not move up too much
thisOplModel.cost.UB=cost*(1+epsilon);
// keep only CO2 emission in the objective
cplex.setObjCoef(thisOplModel.co2emission,1);
cplex.setObjCoef(thisOplModel.cost,0);
cplex.solve();
thisOplModel.postProcess();
}
or if you want to update bounds on a constraint
int nbKids=200;
float costBus40=500;
float costBus30=400;
float costBus50=625;
dvar int+ nbBus40;
dvar int+ nbBus30;
dvar int+ nbBus50;
dvar float cost;
dvar float co2emission;
minimize
cost+co2emission;
subject to
{
cost==costBus40*nbBus40 +nbBus30*costBus30+nbBus50*costBus50;
co2emission==nbBus50+nbBus40*1.1+nbBus30*1.2;
40*nbBus40+nbBus30*30+nbBus50*50>=nbKids;
ctMaxCost:cost<=maxint;
}
execute DISPLAY_After_SOLVE
{
writeln("The minimum cost is ",cost);
writeln("CO2 emission is ",co2emission);
writeln("We will use ",nbBus40," 40 seats buses ",nbBus30,
" 30 seats buses and ", nbBus50," buses 50 seats");
}
main
{
var epsilon=0.01;
thisOplModel.generate();
// remove co2emission from the objective by setting coef 0
cplex.setObjCoef(thisOplModel.co2emission,0);
cplex.solve();
thisOplModel.postProcess();
var cost=thisOplModel.cost.solutionValue;
// add a new constraint that cost should not move up too much
thisOplModel.ctMaxCost.UB=cost*(1+epsilon);
// keep only CO2 emission in the objective
cplex.setObjCoef(thisOplModel.co2emission,1);
cplex.setObjCoef(thisOplModel.cost,0);
cplex.solve();
thisOplModel.postProcess();
}

How to include if-statement with decision variables in cplex which have summation function

How can i convert If statement in constraint part which have decision variable. The costvship is the variable cost of shipment which needs to be included only when sum(m in M)x[m][n]*h[p][n]*weight[m] is greater than threshold Weight. Here x[m][n] and h[p][n] are binary variables.
forall(p in P, n in N){costship[p][n] == costfship*z[p][n] + costvship*(sum(m in M)(x[m][n]*h[m][p]*weight[m])- Weight);
}
You may use a logical constraint to add an additional cost if a constraint is true.
Let me change the zoo example to show that:
int nbKids=300;
float costBus40=500;
float costBus30=400;
int penalty=1000;
dvar int+ nbBus40;
dvar int+ nbBus30;
minimize
costBus40*nbBus40 +nbBus30*costBus30 + (nbBus40+nbBus30<=8)*penalty;
subject to
{
40*nbBus40+nbBus30*30>=nbKids;
}
that you can also write with sum
int nbKids=300;
{int} sizes={40,30};
float costBus[sizes]=[500,400];
int penalty=1000;
dvar int+ nbBus[sizes];
minimize
sum(s in sizes)costBus[s]*nbBus[s] + (sum(s in sizes) nbBus[s]<=8)*penalty;
subject to
{
sum(s in sizes)s*nbBus[s]>=nbKids;
}

Sphere-plane collision resolve

I want to write a c++ program that will calculate collision between sphere and plane.
The rule is that the angle of the falling object equals to angle of reflection.
What do I have for sphere:
//sphere coordinates and radius
float x;
float y;
float z;
float r;
//sphere velocity vector projections
float vx;
float vy;
float vz;
Plane is described by plane equation coefficients:
float A;
float B;
float C;
float D;
With sphere-plane collision detection I have no problem. But how to find velocity after collision?
What did I find:
So, ultimately I need to calculate updated values for vx vy vz.
#Beta’s answer on c++:
float wl = sqrt(plane->A*plane->A+plane->B*plane->B+plane->C+plane->C); // “W” vector length
float nx = plane->A/wl; //Normal components
float ny = plane->B/wl;
float nz = plane->C/wl;
float scope = (sphere->vx*nx + sphere->vy*ny + sphere->vz*nz)*2; // 2(V . n)
nx = nx*scope; // 2(V . n)n
ny = ny*scope;
nz = nz*scope;
sphere->vx -= nx; // V' = V - 2(V . n)n
sphere->vy -= ny;
sphere->vz -= nz;
The equation defining the plane is
Ax + By + Cz + D = 0
So the vector normal to the plane is
W = (A, B, C)
Normalize it:
n = W/|W|
Now take the velocity vector:
V = (vx, vy, vz)
Its component normal to the plane is
Vn = (V . n) n
and the rest of it, the part parallel to the plane is
Vp = V - Vn
We want to reverse the normal component and leave the parallel component unchanged:
V' = -Vn + Vp
which works out to
V' = V - 2(V . n)n