I'm having a real challenge declaring a 2D variable in Zimpl. (Parameters seem to work fine.)
The following is my MWE:
set I := {1 to 10};
set J := {1 to 5};
param A[I*J] := read InputFile as "n+";
var x[I] binary;
var s[J] binary; # this works but doesn't do what I need
var s2[I*J] binary; # this does what I need but doesn't work
minimize sum<i,j> in I*J with A[i,j] < 5: (s2[i,j] - x[i]) * A[i,j];
# this constraint compiles
subto constraint1:
forall <j> in J do sum <i> in I with A[i,j] < 5: x[i] <= 1 + s[j];
# this constraint does not compile
subto constraint2:
forall <j> in J do sum <i> in I with A[i,j] < 5: x[i] <= 1 + s2[i,j];
When try to create my lp file, I get
Error 133: Unknown symbol "i"
Does anyone have any insights into how I can get the second constraint to work? As far as I can tell this is identical to the implementation of the capacitated facility problem (Section 6.3) in the Zimpl user's manual.
Thanks in advance.
You have the sum over i on the left-hand side of the constraint, but then reference i on the right-hand side as well. Which value of i do you expect there?
What would work is
forall <j> in J do sum <i> in I with A[i,j] < 5: (x[i] - s2[i,j]) <= 1;
but I am not sure this is what you want to achieve.
Adding Leon's comment to make a more complete answer:
To add to what Gerald wrote, in ZIMPL sums always only consider the next variable, so you have to put parenthesis to make it work.
To add to what Gerald wrote, in ZIMPL sums always only consider the next variable, so you have to put parenthesis to make it work.
at minimize there is the name missing.
It should be minimize obj: sum ...
Related
I am converting a cpp prog (from another author) to a Fortran prog, my C is not too strong. I came across for-loop constructs starting with
for (int n = 1; 1; ++n) {
...
I would have expected this to convert to a Fortran Do as per
Do n=1, 1, 2
...
... at least that is my guess based on my understanding of what ++n will do.
Is my translation correct? If so, the loop will cycle at most once, so what am I missing ???
I understand that in some ways c for-loops have a "do-while" aspect, and hence wrinkles porting to Fortran Do's.
Anyway ... a clarification would be much appreciated.
EDITED: after some prompt responses, and I think I see where this is going
First, the exact C code copy/paste but "trimming" a little, is
for (int n = 1; 1; ++n) {
const double coef = exp(-a2*(n*n)) * expx2 / (a2*(n*n) + y*y);
prod2ax *= exp2ax;
prodm2ax *= expm2ax;
sum1 += coef;
sum2 += coef * prodm2ax;
sum4 += (coef * prodm2ax) * (a*n);
sum3 += coef * prod2ax;
sum5 += (coef * prod2ax) * (a*n);
// test convergence via sum5, since this sum has the slowest decay
if ((coef * prod2ax) * (a*n) < relerr * sum5) break;
}
So yes, there is a "break" in the loop, which on the Fortran side is replaced with an "Exit".
I think the key seems to be from the answers below that the original code's author created the
for (int n=1; 1 ; ++n )
precisely to create a an infinite loop, and I had not guessed that this for construct would create an infinite loop.
Anyway, I can certainly create an infinite loop with an "Exit" in Fortran (though I expect I might "do" it a bit more judiciously)
Many thanks to all.
It seems the Mr Gregory's response was the one that imediately lead to a solution for me, so I will mark his correct. As for the Fortran side, there are a number of alternatives such as:
Do While
:
If( something ) Exit
End Do
but being old fashioned I would probably use a construct with a "limit" such as
Do i=1, MaxIter
:
If( something ) Exit
End Do
For slightly fancier applications I might include a return flag in case it did not converge in MaxIter's etc.
It's difficult to be definitive without seeing how the C++ program breaks out of that loop, but a straightforward Fortran equivalent would be
n = 1
do
! code, including an exit under some condition, presumably on the value of n
n = n+1
end do
If the loop is terminated when n reaches a critical value then the equivalent might be
do n = 1, critical_value ! no need to indicate step size if it is 1
! code
end do
Are you sure you wrote the C code correctly? Typically loops in C/C++ are done like this:
for (int n = 1; n < 10; ++n) {
// ...
}
Note the "n < 10" test condition. Your code's test condition is simply 1, which will always evaluate to Boolean "true". This means the code will loop infinitely, unless there's a break inside the loop, which you haven't shown.
++n means "increment n".
So if the code you've shown is indeed correct, the FORTRAN equivalent would be:
n = 1
do
[Body of the loop, which you haven't shown]
n = n + 1
enddo
Here's what
for (int n = 1; 1; ++n)
does:
It sets n to 1, then loops infinitely, incrementing n by 1 at the end of each loop iteration. The loop will never terminate unless something inside the loop breaks out.
It's been a long time since I wrote Fortran but as I recall the do loop you translated it to is not correct.
I don't think you can translate
for (int n = 1; 1; ++n)
to a FORTRAN DO loop. From what I recall, the notion of the generic conditional in C/C++ cannot be emulated in a FORTRAN DO loop.
The equivalent of
Do n=1, 1, 2
in C/C++ is
for ( int n = 1; n <= 1; n += 2 )
A few notes in addition to CareyGregory’s answer.
++n means ‘increment n by one (before n is evaluated)’
In C and C++, a for loop has three clauses, much like in FORTRAN:
for (init; condition; increment)
The difference is that each of the clauses must be a complete expression, whereas in FORTRAN the clauses are just values. It is just a ‘short’ way of writing an equivalent while loop:
int n = 1; │ for (int n = 1; 1; ++n) │ n = 1
while (1) │ { │ do
{ │ ... │ ...
... │ } │ n = n + 1
++n; │ │ enddo
} │ │
I'm using Julia to solve an integer program. My variables are of the form z[i,j], i in N and j in N and N=10and z[i,j] is a binary variable.
In the first half of the program, I have a set of solutions for which z[1,2]= 1 and z[1,3]=1 and all other variables are zero. Now, I need to pass these values to another set S in such a way that S={1,2,3}. I tried to code it in Julia, but I couldn't get it in the right way. The following is the what I've tried.Here, z_value is the way that I declare my variables z[i,j]. Can someone please help me to make it correct?
for i in N
for j in N
z_value = Pair(i,j)
if z_value == 1;
push!(S, Pair(i,j))
print(S)
end
end
end
Thanks, Michael and Stefan, I got required set S by rearranging the code as
for i in N
for j in N
if getvalue(z[i,j]) == 1
push!(S, i)
push!(S, j)
end
end
end
Thanks for your effort!!
I am trying to evaluate a certain expression under consideration of assumption. Specifically my problem is related to indexedBase objects.
See the following code:
from sympy import *
init_printing(use_latex="mathjax")
ntot = symbols("n_tot", integer = True)
i = Idx("i",(1,ntot))
k = Idx("k", (1,ntot))
j = Idx("j",(1,ntot))
x = IndexedBase("x")
As an example let's take the derivative of two summations over x[i].
expr = Sum(Sum(x[i],(i,1,ntot)),(k,1,ntot)).diff(x[j])
(NOTE: this is not possible in the current SymPy version 1.0, it is possible with the development version and will be available in future SymPy stable versions.)
I want to evaluate the expression and get a piecewise answer:
print(expr.doit())
OUTPUT: n_tot*Piecewise((1, And(1 <= j, j <= n_tot)), (0, True))
So my problem is, how can I tell sympy that I know for certain that j is between 1 and ntot. So that my result is 1:
I tried the following but with no luck:
with assuming(j==2):
expr=Sum(Sum(x[i],(i,1,ntot)),(k,1,ntot)).diff(x[j]).doit()
Assumptions on inequalities are a sorely missed feature in SymPy.
Technically the Idx object was created to allow a symbol to contain a definition range, so as to put limits on indexed symbols. Your j already has this information:
In [28]: j.upper
Out[28]: n_tot
In [29]: j.lower
Out[29]: 1
Unfortunately, the inequality class is not meant to handle Idx objects, so its range gets disregared.
You could actually try:
In [32]: simplify(expr.doit()).args[0][0]
Out[32]: n_tot
This manually extracts the first term of the Piecewise expression.
Obviously, the current algorithm needs improvement, it should already tell to Sum that j is within the correct range in order to give 1 as a result.
I am trying to do something that logically should be possible to do. However, I am not sure how to do this within the realm of linear programming. I am using ZMPL/SCIP, but this should be readable to most.
set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;
var a;
var b;
subto bval:
b == 2;
subto works:
a == u[2];
#subto does_not_work:
# a == u[b];
I am trying to make sure that the variable a is equal to the value at the index b in u. So for example, I ensure that b == 2 and then I try to set the constraint that a == u[b], but that does not work. It complains that I am trying to index with a variable. I am able to just do a == u[2] however, which makes a equal to 20.
Is there a way to easily access u at an index specified by a variable? Thanks for any help/guidance.
EDIT: I think the consensus is that this is not possible because it no longer becomes an LP. In that case, can anyone think of another way to write this so that, depending on the value of b, I can get an associated value from the set u? This would have to avoid directly indexing it.
SOLUTION: Based on the response from Ram, I was able to try it out and found that it was definitely a viable and linear solution. Thanks, Ram! Here is sample solution code in ZMPL:
set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;
var a;
var b;
var y[I] binary;
subto bval:
b == 4;
subto only_one:
sum <i> in I : y[i] == 1;
subto trick:
b == (sum <i> in I : y[i] * i);
subto aval:
(sum <i> in I : u[i]*y[i]) == a;
Yes, you can rewrite and linearize your constraints, by introducing a few extra 0/1 variables (indicator variables). These kinds of tricks are not uncommon in Integer Programming.
Constraints In English
b can take on values from 1 through 5. b = {1..5}
and depending on b's value, the variable a should become u[b]
Indicator Variables
Let's introduce 5 Y variables - Y1..Y5 (one for each possible value of b)
Only one of them can be true at any given time.
Y1 + Y2 + Y3 + Y4 + Y5 = 1
All Y's are binary {0,1}
Here's the trick. We introduce one linear constraint to ensure that the corresponding Y variable will take on value 1, only when b is that value.
b - 1xY1 - 2xY2 - 3xY3 - 4xY4 - 5xY5 = 0
(For example, if b is 3, the constraint above will force Y3 to be 1.)
Now, we want a to take on the value u[b].
a = u[1]xY1 + u[2]xY2 + u[3]xY3 + u[4]xY4 + u[5]xY5
Since u[ 1] ...u[5] are constants known beforehand, the constraint above is also linear.
Here is one reference on these kinds of IF-THEN conditions in Integer Programming. Many of these tricks involve the Big-M, though we didn't need it in this case.
Hope that helps you move forward.
Can anyone please explain how this works
#define maxMacro(a,b) ( (a) > (b) ) ? (a) : (b)
inline int maxInline(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int i = 1; j = 2, k = 0;
k = maxMacro(i,j++); // now i = 1, j = 4 and k = 3, Why ?? Where is it incremented ?
//reset values
i = 1; j = 2, k = 0;
k = maxInline(i,j++); // now i = 1, j = 3, and k = 2, Why ??
return 0;
}
So, I want to know where exactly is the value of j incremented, while checking
condition or while returning or while calling ?
a. using macro
b. using inline method
UPDATE :
Thanks to all, now I understand this. But just out of curiosity, why would anyone do j++ while calling method, why not increment j after calling method, this way it would be less confusing. I saw this piece of code somewhere so asking it !!
The issue is the preprocessor does just straight text substitution for macros.
maxMacro(i, j++)
becomes
( (i) > (j++) ) ? (i) : (j++)
As you can see, it does two increments when j is greater.
This is exactly why you should prefer inline functions over macros.
k = maxMacro(i,j++);
expands to:
k = ( (i) > (j++) ) ? (i) : (j++)
Because of the sequence point of ?: the behaviour of this is well defined. When i is less than the initial value of j, j is incremented twice and k receives the once incremented value of j.
(If i were greater than the initial value of j, then j would be incremented only once when evaluating (i) > (j++), k would be assigned that value of (i) and the second increment would not be performed.)
In:
k = maxInline(i,j++);
maxInline is called with the values i and j before increment (1 and 2), j is incremented before the function call, and k is assigned the return value of maxInline (2).
Macro results in textual expansion. It happens before the compiler is even considering expressions and operators, and immediately after it had split the input text into individual tokens. Thus, the following line:
k = maxMacro(i,j++);
is exactly equivalent to the following line after macro expansion:
k = ( (i) > (j++) ) ? (i) : (j++);
Obviously, there are two increments here.
On the other hand, inline functions are just functions, and work exactly like non-inline ones for the purpose of the call. And in function calls, expressions in the argument list are evaluated first, and then their values are bound to respective parameter names inside the function body. Thus, the evaluation only happens once.
This is why macro is evil!
A macro is literal text subsitution by the proprocessor before your compiler gets to it so k = maxMacro(i,j++); becomes ( (i) > (j++) ) ? (i) : (j++);. I hope you see the problem here.
In the (inline) function call, the value of a and b is passed by value into the function where the initial value of i and j is passed in, after which j increment.
Calling a macro is not the same as calling a function.
The preprocessor replaces the reference to maxMacro(i,j++)
with literal text that looks like this.
(i) > (j++) ? (i) : (j++)
A post increment operator uses the current value of its target,
and then increments its target. So if i = 1 and j = 2, the following
happens:
(i) > (j++) // 1 is compared to 2, and j is incremented to 3
? (i) : (j++) 2 is greater than 1, so the "b" value is passed
along. j++ is invoked again, so the previous value 3 is returned
from the expression, but as a side effect, j is incremented to 4.
On the other hand, the inline function works just like a non
inline function as far as how the parameter variables are treated.
j++ is referenced once when it is put on the
stack as part of the function call. The function call operates
with a b value of 2 and returns its result(2) while j is incremented
to 3 as a side effect.
Note: your question indicates k=3 after the call to maxInline. I got
k=2 after that call - the result I'd expect.
I hope this clarifies things . . .
K
Check out the CERT C Coding standard:
PRE00-C. Prefer inline or static functions to function-like macros
This is a great resource, lots of information about various little gotchas that one should avoid to make their code clean, stable, and secure :)
Weird. So far nobody has mentioned that the inline function option is type-safe, where the macro isn't!