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

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

Related

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]);

Determining the time complexity of this program

void f2(int n)
{
if (n<=1)
return;
g2(n, n/3);
}
void g2(int n, int m)
{
int i=1;
while (m < n) {
m += i;
i++;
}
f2(n/2);
}
I tried alot to calculate the time complexity and got it wrong, I would really appreciate it if someone could help me on how to approach these programs. (The answer is O(sqrt(n)).
The following explanation can be simplified, but I tried to be as much scrupulous as possible.
Sum of arithmetic progression
First of all lets talk about complixity of the following loop (note the m=0):
int m=0;
int i=1;
while (m < n) {
m += i;
i++;
}
Invariant of the loop is: after ith iteration m == 1+2+...+i == (1+i)*i/2. So the loop stops when the following condition is met:
which is equavalent to
Big O of the left and right parts are equal and both equal to O(i), so O(i)=O(sqrt(n)) is the complexity of the loop.
Complexity of the loop inside g2
The loop inside the g2 is equavalent to the following loop:
int n_modified = n - m;
m = 0;
int i=1;
while (m < n_modified) {
m += i;
i++;
}
which complexity is O(sqrt(n-m)) as we've shown in the previous section.
Complexity of the f2
Now lets get overall formula for complexity of the f2 function. Its complexity is essentially the same as complexity of the g2(n, n/3) call. It consists of two parts: complexity of the g2's loop and complexitiy of the recursion. That is, the formula is
This can be simplified and estimated (factoring and sum of geometric progression):
which gives us the final answer: the complexity of f2 is O(sqrt(n)).

Big-O Complexity of Two Problems

I was practicing a few Big-O complexity problems for one of my classes and these two problems seem to stump me the most.
For both of these, I need to determine the best and worst-case complexity.
Q1
function FUNC3(int array[n], int n, int key)
int i = 1;
while (i < n) do {
if (key == array[0]) then
i = i + n^0.25;
else
i = i + n^0.5;
}
The best-case I got was: O(n / n^0.5) while my worst-case was: O(n / n^0.25)
Q2
function FUNC4(int array[n], int n, int key)
for (int i=1; i<n; i = i * 2) do
for (int j=0; j<sqrt(n); j++) do {
if(array[0] == key) then {
int k = 1;
while (k < n) do
k = k * sqrt(n);
}
}
For this one, I got best-case: O(logn x sqrt(n)), with a worst-case of: O(logn x n)
Although, I am not very confident in these answers, do any of these look about right?
Let's visit each of these individually. Here's your first function:
function FUNC3(int array[n], int n, int key)
int i = 1;
while (i < n) do {
if (key == array[0]) then
i = i + n^0.25;
else
i = i + n^0.5;
}
You are correct that the best-case runtime is Θ(n / n0.5) and that the worst case is Θ(n / n0.25). It might help to rewrite these by simplifying the exponents; the first runtime is
Θ(n / n0.5) = Θ(n0.5) = Θ(√n)
and the second runtime is
Θ(n / n0.25) = Θ(n3/4).
Now, let's look at the second function:
function FUNC4(int array[n], int n, int key)
for (int i=1; i<n; i = i * 2) do
for (int j=0; j<sqrt(n); j++) do {
if(array[0] == key) then {
int k = 1;
while (k < n) do
k = k * sqrt(n);
}
}
To determine the runtime, let's use the time-honored maxim
"When in doubt, work inside out!"
Let's begin with the innermost loop:
int k = 1;
while (k < n) do
k = k * sqrt(n);
This loop is sneaky - it never runs more than three times because the values of k will be 1, then √n, then n. This means that the loop does O(1) total work. As a result, we can rewrite the overall code as
function FUNC4(int array[n], int n, int key)
for (int i=1; i<n; i = i * 2) do
for (int j=0; j<sqrt(n); j++) do {
if(array[0] == key) then {
do O(1) work;
}
}
Since the if statement does O(1) work regardless of whether it executes, we're left with
function FUNC4(int array[n], int n, int key)
for (int i=1; i<n; i = i * 2) do
for (int j=0; j<sqrt(n); j++) do {
do O(1) work;
}
If we do O(1) work √n times, then the runtime is Θ(√n), so the inner loop becomes
function FUNC4(int array[n], int n, int key)
for (int i=1; i<n; i = i * 2) do
do sqrt(n) work
Since the work done in the inner loop is independent of the value of i, the work done here is simply the product of the number of outer loop iterations and the work done by one iteration. The outer loop runs Θ(log n) times, so the work here is Θ(√n log n), regardless of the array contents. So that makes the best- and worst-case runtimes for the function the same, since the total work done is (asymptotically) always the same.
Hope this helps!

Number of possible combinations

How many possible combinations of the variables a,b,c,d,e are possible if I know that:
a+b+c+d+e = 500
and that they are all integers and >= 0, so I know they are finite.
#Torlack, #Jason Cohen: Recursion is a bad idea here, because there are "overlapping subproblems." I.e., If you choose a as 1 and b as 2, then you have 3 variables left that should add up to 497; you arrive at the same subproblem by choosing a as 2 and b as 1. (The number of such coincidences explodes as the numbers grow.)
The traditional way to attack such a problem is dynamic programming: build a table bottom-up of the solutions to the sub-problems (starting with "how many combinations of 1 variable add up to 0?") then building up through iteration (the solution to "how many combinations of n variables add up to k?" is the sum of the solutions to "how many combinations of n-1 variables add up to j?" with 0 <= j <= k).
public static long getCombos( int n, int sum ) {
// tab[i][j] is how many combinations of (i+1) vars add up to j
long[][] tab = new long[n][sum+1];
// # of combos of 1 var for any sum is 1
for( int j=0; j < tab[0].length; ++j ) {
tab[0][j] = 1;
}
for( int i=1; i < tab.length; ++i ) {
for( int j=0; j < tab[i].length; ++j ) {
// # combos of (i+1) vars adding up to j is the sum of the #
// of combos of i vars adding up to k, for all 0 <= k <= j
// (choosing i vars forces the choice of the (i+1)st).
tab[i][j] = 0;
for( int k=0; k <= j; ++k ) {
tab[i][j] += tab[i-1][k];
}
}
}
return tab[n-1][sum];
}
$ time java Combos
2656615626
real 0m0.151s
user 0m0.120s
sys 0m0.012s
The answer to your question is 2656615626.
Here's the code that generates the answer:
public static long getNumCombinations( int summands, int sum )
{
if ( summands <= 1 )
return 1;
long combos = 0;
for ( int a = 0 ; a <= sum ; a++ )
combos += getNumCombinations( summands-1, sum-a );
return combos;
}
In your case, summands is 5 and sum is 500.
Note that this code is slow. If you need speed, cache the results from summand,sum pairs.
I'm assuming you want numbers >=0. If you want >0, replace the loop initialization with a = 1 and the loop condition with a < sum. I'm also assuming you want permutations (e.g. 1+2+3+4+5 plus 2+1+3+4+5 etc). You could change the for-loop if you wanted a >= b >= c >= d >= e.
I solved this problem for my dad a couple months ago...extend for your use. These tend to be one time problems so I didn't go for the most reusable...
a+b+c+d = sum
i = number of combinations
for (a=0;a<=sum;a++)
{
for (b = 0; b <= (sum - a); b++)
{
for (c = 0; c <= (sum - a - b); c++)
{
//d = sum - a - b - c;
i++
}
}
}
This would actually be a good question to ask on an interview as it is simple enough that you could write up on a white board, but complex enough that it might trip someone up if they don't think carefully enough about it. Also, you can also for two different answers which cause the implementation to be quite different.
Order Matters
If the order matters then any solution needs to allow for zero to appear for any of the variables; thus, the most straight forward solution would be as follows:
public class Combos {
public static void main() {
long counter = 0;
for (int a = 0; a <= 500; a++) {
for (int b = 0; b <= (500 - a); b++) {
for (int c = 0; c <= (500 - a - b); c++) {
for (int d = 0; d <= (500 - a - b - c); d++) {
counter++;
}
}
}
}
System.out.println(counter);
}
}
Which returns 2656615626.
Order Does Not Matter
If the order does not matter then the solution is not that much harder as you just need to make sure that zero isn't possible unless sum has already been found.
public class Combos {
public static void main() {
long counter = 0;
for (int a = 1; a <= 500; a++) {
for (int b = (a != 500) ? 1 : 0; b <= (500 - a); b++) {
for (int c = (a + b != 500) ? 1 : 0; c <= (500 - a - b); c++) {
for (int d = (a + b + c != 500) ? 1 : 0; d <= (500 - a - b - c); d++) {
counter++;
}
}
}
}
System.out.println(counter);
}
}
Which returns 2573155876.
One way of looking at the problem is as follows:
First, a can be any value from 0 to 500. Then if follows that b+c+d+e = 500-a. This reduces the problem by one variable. Recurse until done.
For example, if a is 500, then b+c+d+e=0 which means that for the case of a = 500, there is only one combination of values for b,c,d and e.
If a is 300, then b+c+d+e=200, which is in fact the same problem as the original problem, just reduced by one variable.
Note: As Chris points out, this is a horrible way of actually trying to solve the problem.
link text
If they are a real numbers then infinite ... otherwise it is a bit trickier.
(OK, for any computer representation of a real number there would be a finite count ... but it would be big!)
It has general formulae, if
a + b + c + d = N
Then number of non-negative integral solution will be C(N + number_of_variable - 1, N)
#Chris Conway answer is correct. I have tested with a simple code that is suitable for smaller sums.
long counter = 0;
int sum=25;
for (int a = 0; a <= sum; a++) {
for (int b = 0; b <= sum ; b++) {
for (int c = 0; c <= sum; c++) {
for (int d = 0; d <= sum; d++) {
for (int e = 0; e <= sum; e++) {
if ((a+b+c+d+e)==sum) counter=counter+1L;
}
}
}
}
}
System.out.println("counter e "+counter);
The answer in math is 504!/(500! * 4!).
Formally, for x1+x2+...xk=n, the number of combination of nonnegative number x1,...xk is the binomial coefficient: (k-1)-combination out of a set containing (n+k-1) elements.
The intuition is to choose (k-1) points from (n+k-1) points and use the number of points between two chosen points to represent a number in x1,..xk.
Sorry about the poor math edition for my fist time answering Stack Overflow.
Just a test for code block
Just a test for code block
Just a test for code block
Including negatives? Infinite.
Including only positives? In this case they wouldn't be called "integers", but "naturals", instead. In this case... I can't really solve this, I wish I could, but my math is too rusty. There is probably some crazy integral way to solve this. I can give some pointers for the math skilled around.
being x the end result,
the range of a would be from 0 to x,
the range of b would be from 0 to (x - a),
the range of c would be from 0 to (x - a - b),
and so forth until the e.
The answer is the sum of all those possibilities.
I am trying to find some more direct formula on Google, but I am really low on my Google-Fu today...