Declaration of 3D Decision Variable - variables

I need to declarate a 3 dimensional decision variable, which is defined according to the following:
x[m][p][q] in {0,1} with m in M, p in P(m) and q in Q(m,p)
dvar boolean x[M][P][Q] does not work.
Is there a possiblity to define it similar to a constraint, like:
forall(m in M, p in P(m) and q in Q(m,p))
x[m][p][q] in {0,1}
or something?
Regards

array variable indexer size - 3 ways : union , tuple set, decision expression
in Simple OPL CPLEX
could help
/*
Variable indexer size:
we'd like to be able to write
dvar int+ nbBus[s in scenarii][sizes[s]];
but we get an error "Variable indexer size not allowed"
So what can we do ?
We saw 2 options:
1) Rely on a tuple set that contains all options
instead of a multi dimension array
2) For the variable dimension use the union of all options
1) Is good but the drawback is that relying on a tuple set makes the
constraint harder to read for a human being
2) Is good but a bit suboptimal since we use options that are useless and
consume memory for no gain.
We can mix 1) and 2) with decision expressions
*/
int nbKids=300;
tuple busscenario
{
key int nbSeats;
key int scenario;
float cost;
}
{busscenario} busscenarii={<40,1,500>,<30,1,400>,<30,2,410>,<35,2,440>,<40,2,520>};
{int} scenarii={i.scenario | i in busscenarii};
{int} sizeBusesPerScenario[scen in scenarii]={i.nbSeats | i in busscenarii : i.scenario==scen};
{int} busSizes=union(scen in scenarii) sizeBusesPerScenario[scen];
// decision variable array with variable size
dvar int+ nbBus2[busscenarii];
// decision expression array with variable size
dexpr int nbBus[sc in scenarii][b in busSizes]=nbBus2[<b,sc>];
dexpr float cost[sc in scenarii][b in busSizes]=item(busscenarii,<b,sc>).cost;
// objective
minimize
1/card(scenarii)*sum(sc in scenarii,b in sizeBusesPerScenario[sc])
cost[sc][b]*nbBus[sc][b];
// constraints
subject to
{
forall(sc in scenarii) sum(b in sizeBusesPerScenario[sc]) b*nbBus[sc][b]>=nbKids;
}
execute
{
for(sc in scenarii)
{
writeln("scenario ",sc);
for(var b in sizeBusesPerScenario[sc]) writeln(nbBus[sc][b]," buses ",b," seats" );
writeln();
}
}
/*
which gives
// solution (optimal) with objective 3820
scenario 1
6 buses 40 seats
2 buses 30 seats
scenario 2
0 buses 30 seats
4 buses 35 seats
4 buses 40 seats
*/

Related

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
{
}

Using a solution from a model as an input to another one and Outputting each Solution Separately

I'm solving an optimization problem in which I need the result from one model to be used as a input in another model for 180 iterations. I'm using CPLEX with OPL language without any addon.
I tried to save the values from one model into an Excel file and reading those into the next model but since I'm going to do this 180 times I am worried I will make an error and have to restart or not even know I made an error.
Is it possible to have this run for 180 iterations and input each iteration's solution separately?
You can rely on warmstart for that.
2 simple examples in easy OPL
Warm start from a file:
include "zoo.mod";
main {
var filename = "c:/temp/mipstart.mst";
thisOplModel.generate();
cplex.readMIPStarts(filename);
cplex.solve();
writeln("Objective: " + cplex.getObjValue());
}
or with API
int nbKids=300;
// a tuple is like a struct in C, a class in C++ or a record in Pascal
tuple bus
{
key int nbSeats;
float cost;
}
// This is a tuple set
{bus} pricebuses=...;
// asserts help make sure data is fine
assert forall(b in pricebuses) b.nbSeats>0;assert forall(b in pricebuses) b.cost>0;
// To compute the average cost per kid of each bus
// you may use OPL modeling language
float averageCost[b in pricebuses]=b.cost/b.nbSeats;
// Let us try first with a naïve computation, use the cheapest bus
float cheapestCostPerKid=min(b in pricebuses) averageCost[b];
int cheapestBusSize=first({b.nbSeats | b in pricebuses : averageCost[b]==cheapestCostPerKid});
int nbBusNeeded=ftoi(ceil(nbKids/cheapestBusSize));
float cost0=item(pricebuses,<cheapestBusSize>).cost*nbBusNeeded;
execute DISPLAY_Before_SOLVE
{
writeln("The naïve cost is ",cost0);
writeln(nbBusNeeded," buses ",cheapestBusSize, " seats");
writeln();
}
int naiveSolution[b in pricebuses]=
(b.nbSeats==cheapestBusSize)?nbBusNeeded:0;
// decision variable array
dvar int+ nbBus[pricebuses];
// objective
minimize
sum(b in pricebuses) b.cost*nbBus[b];
// constraints
subject to
{
sum(b in pricebuses) b.nbSeats*nbBus[b]>=nbKids;
}
float cost=sum(b in pricebuses) b.cost*nbBus[b];
execute DISPLAY_After_SOLVE
{
writeln("The minimum cost is ",cost);
for(var b in pricebuses) writeln(nbBus[b]," buses ",b.nbSeats, " seats");
}
main
{
thisOplModel.generate();
// Warm start the naïve solution
cplex.addMIPStart(thisOplModel.nbBus,thisOplModel.naiveSolution);
cplex.solve();
thisOplModel.postProcess();
}

Transition matrix not included in my solution of my scheduling problem in CPLEX CP

My distance matrix in my no overlap constraint does not seem to work in my model outcome. I have formulated the distance matrix by means of a tuple set. I have tried this in 2 different ways as can be seen in the code. Both tuple sets seem to be correct and the distance matrix is added in the noOverlap constraint for the dvar sequence.
Nevertheless I do not see the added transition distance between products in the optimal results. Jobs seem to continue at the same time when a job is finished. Instead of waiting for a transition time. I would like this transition matrix to hold both for machine 1 and machine 2.
Could someone tell me what I did wrong in my model formulation? I have looked into the examples, but they seem to be constructed in the same way. So I do not know what I am doing wrong.
mod.
using CP;
// Number of Machines (Packing + Manufacturing)
int nbMachines = ...;
range Machines = 1..nbMachines;
// Number of Jobs
int nbJobs = ...;
range Jobs = 1..nbJobs;
int duration[Jobs,Machines] = ...;
int release = ...;
int due = ...;
tuple Matrix { int job1; int job2; int value; };
//{Matrix} transitionTimes ={<1,1,0>,<1,2,6>,<1,3,2>,<2,1,2>,<2,2,0>,<2,3,1>,<3,1,2>,<3,2,3>,<3,3,0>};
{Matrix} transitionTimes ={ <i,j, ftoi(abs(i-j))> | i in Jobs, j in Jobs };
dvar interval task[j in Jobs] in release..due;
dvar interval opttask[j in Jobs][m in Machines] optional size duration[j][m];
dvar sequence tool[m in Machines] in all(j in Jobs) opttask[j][m];
execute {
cp.param.FailLimit = 5000;
}
// Minimize the max timespan
dexpr int makespan = max(j in Jobs, m in Machines)endOf(opttask[j][m]);
minimize makespan;
subject to {
// Each job needs one unary resource of the alternative set s (28)
forall(j in Jobs){
alternative(task[j], all(m in Machines) opttask[j][m]);
}
forall(m in Machines){
noOverlap(tool[m],transitionTimes);
}
};
execute {
writeln(task);
};
dat.
nbMachines = 2;
nbJobs = 3;
duration = [
[5,6],
[3,4],
[5,7]
];
release = 1;
due = 30;
``
You should specify interval types for each sequence.
In your case, the type is the job id:
int JobId[j in Jobs] = j;
dvar sequence tool[m in Machines] in all(j in Jobs) opttask[j][m] types JobId;

Array issue with endbefore start in CPLEX

I am trying to add an Endbeforestartconstraint to my contrained programming problem. However, I receive an error saying that my end beforestart is not an array type. I do not understand this as I almost copied the constraint and data from the sched_seq example in CPLEX, I only changed it to integers.
What I try to accomplish with the constraint, is that task 3 and task 1 will be performed before task 2 will start.
How I can fix the array error for this constraint?
Please find below the relevant parts of my code
tuple Precedence {int pre;int post;};
{Precedence} Precedences = {<3,2>,<1,2>};
dvar interval task[j in Jobs] in release..due;
dvar interval opttask[j in Jobs][m in Machines] optional size duration[j][m];
dvar sequence tool[m in Machines] in all(j in Jobs) opttask[j][m]
dexpr int makespan = max(j in Jobs, m in Machines)(endOf(opttask[j][m]));
minimize makespan;
subject to {
// Each job needs one unary resource of the alternative set s (28)
forall(j in Jobs){
alternative(task[j], all(m in Machines) opttask[j][m]);
}
// No overlap on machines
forall(j in Jobs)
forall(p in Precedences)
endBeforeStart(opttask[j][p.pre],opttask[j][p.post]);
forall(m in Machines){
noOverlap(tool[m],transitionTimes);
}
};
execute {
writeln(task);
dat.
nbMachines = 2;
nbJobs = 3;
duration = [
[5,6],
[4,4],
[5,8]
];
release = 1;
due = 30;
There are several errors in your model, on ranges or on inverted indices.
Also, next time, please post a complete program showing the problem, not just a partial one, this may help you to get quicker answers.
A corrected program:
using CP;
int nbMachines = 2;
int nbJobs = 3;
range Machines = 0..nbMachines-1;
range Jobs = 0..nbJobs-1;
int duration[Jobs][Machines] = [
[5,6],
[4,4],
[5,8]
];
int release = 1;
int due = 30;
tuple Precedence {int pre;int post;};
{Precedence} Precedences = {<2,1>,<0,1>};
dvar interval task[j in Jobs] in release..due;
dvar interval opttask[j in Jobs][m in Machines] optional size duration[j][m];
dvar sequence tool[m in Machines] in all(j in Jobs) opttask[j][m];
dexpr int makespan = max(j in Jobs, m in Machines)(endOf(opttask[j][m]));
minimize makespan;
subject to {
// Each job needs one unary resource of the alternative set s (28)
forall(j in Jobs){
alternative(task[j], all(m in Machines) opttask[j][m]);
}
// No overlap on machines
forall(m in Machines)
forall(p in Precedences)
endBeforeStart(opttask[p.pre][m],opttask[p.post][m]);
};
execute {
writeln(task);
}
You must have values in p.pre or p.post that are outside of the array indexing range.

Gather AVX2&512 intrinsic for 16-bit integers?

Imagine this piece of code:
void Function(int16 *src, int *indices, float *dst, int cnt, float mul)
{
for (int i=0; i<cnt; i++) dst[i] = float(src[indices[i]]) * mul;
};
This really asks for gather intrinsics e.g. _mm_i32gather_epi32. I got great success with these when loading floats, but are there any for 16-bit ints? Another problem here is that I need to transition from 16-bits on the input to 32-bits (float) on the output.
There is indeed no instruction to gather 16bit integers, but (assuming there is no risk of memory-access violation) you can just load 32bit integers starting at the corresponding addresses, and mask out the upper halves of each value.
For uint16_t this would be a simple bit-and, for signed integers you can shift the values to the left in order to have the sign bit at the most-significant position. You can then (arithmetically) shift back the values before converting them to float, or, since you multiply them anyway, just scale the multiplication factor accordingly.
Alternatively, you could load from two bytes earlier and arithmetically shift to the right. Either way, your bottle-neck will likely be the load-ports (vpgatherdd requires 8 load-uops. Together with the load for the indices you have 9 loads distributed on two ports, which should result in 4.5 cycles for 8 elements).
Untested possible AVX2 implementation (does not handle the last elements, if cnt is not a multiple of 8 just execute your original loop at the end):
void Function(int16_t const *src, int const *indices, float *dst, size_t cnt, float mul_)
{
__m256 mul = _mm256_set1_ps(mul_*float(1.0f/0x10000));
for (size_t i=0; i+8<=cnt; i+=8){ // todo handle last elements
// load indicies:
__m256i idx = _mm256_loadu_si256(reinterpret_cast<__m256i const*>(indices + i));
// load 16bit integers in the lower halves + garbage in the upper halves:
__m256i values = _mm256_i32gather_epi32(reinterpret_cast<int const*>(src), idx, 2);
// shift each value to upper half (removes garbage, makes sure sign is at the right place)
// values are too large by a factor of 0x10000
values = _mm256_slli_epi32(values, 16);
// convert to float, scale and multiply:
__m256 fvalues = _mm256_mul_ps(_mm256_cvtepi32_ps(values), mul);
// store result
_mm256_storeu_ps(dst, fvalues);
}
}
Porting this to AVX-512 should be straight-forward.