So i wanted to run this code:
constraint ctMachine[Machine];
subject to{
forall(i in Machine)
forall (k in Week)
ctMachine[i]: sum(j in Product)
ResourceConsumption[i][j] * Units[j][k] <= Capacity[i];
But if I do this, I get the error that ctMachine[1] was already assigned, which makes sense. So I tried to put the second for loop after the sum function, like this:
constraint ctMachine[Machine];
subject to{
forall(i in Machine)
ctMachine[i]: sum(j in Product)
forall(k in Week)
ResourceConsumption[i][j] * Units[j][k] <= Capacity[i];
But then I receive the syntax error, unexpected forall. But how can I do it then. I need the constranint for all k. I am fairly new to linear programming and OPL so I don't have a clue how I can solve this now. Btw I can't just remove the constraint label since I also need that.
I would remove
constraint ctMachine[Machine];
and write
forall(i in Machine)
ctMachine:
sum(j in Product)
sum(k in Week)
ResourceConsumption[i][j] * Units[j][k] <= Capacity[i];
regards
Related
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 ...
I am wondering can I use if operator in ampl? I have a set of variable x_{1},...,x_{n} and some constraints. now I have some constraints whose are valid under some circumstances. for example if x_{1}+...+x_{n}=kn+1 where `k is an integer then constraint A is valid.
is there any way that I can write it in ampl?
In other words the problem is that I want to search layer by layer in feasible reign. the layer is dot product between a point x=(x1,...,xn) and the vector 1=(1,1,1,...1) .
so
if < x,1>=1 then x has to satisfy the constraint A<1,
if =2 then x has to satisfy the constraint B<2,
.
.
.
this is what I found in AMPL website but it does not work! (n is dimension of x and k arbitrary integer)
subject to Time {if < x,1 > =kn+1}:
s.t. S1: A<1;
I'm not clear whether your example means "constraint A requires that x_[1]+...+x_[n]=4m+1 where m is an integer", or "if x_[1]+...+x_[n]=4m+1 where m is an integer, then constraint A requires some other condition to be met".
The former is trivial to code:
var m integer;
s.t. c1: sum{i in 1..n} x_[i] = 4m+1;
It does require a solver with MIP capability. From your tags I assume you're using CPLEX, which should be fine.
For the latter: AMPL does have some support for logical constraints, documented here. Depending on your problem, it's also sometimes possible to code logical constraints as linear integer constraints.
For example, if the x[i] variables in your example are also integers, you can set things up like so:
var m integer;
var r1 integer in 0..1;
var r2 integer in 0..2;
s.t. c1: r2 <= 2*r1; # i.e. r2 can only be non-zero if r1 = 1
s.t. c2: sum{i in 1..n} x_[i] = 4m+r1+r2;
var remainder_is_1 binary;
s.t. c3: remainder_is_1 >= r1-r2;
s.t. c4: remainder_is_1 <= 1-r2/2;
Taken together, these constraints ensure that remainder_is_1 equals 1 if and only if sum{i in 1..n} x_[i] = 4m+1 for some integer m. You can then use this variable in other constraints. This sort of trick can be handy if you only have a few logical constraints to deal with, but if you have many, it'll be more efficient to use the logical constraint options if they're available to you.
I've been experimenting with various prime sieves in Julia with a view to finding the fastest. This is my simplest, if not my fastest, and it runs in around 5-6 ms on my 1.80 GHz processor for n = 1 million. However, when I add a simple 'if' statement to take care of the cases where n <= 1 or s (the start number) > n, the run-time increases by a factor of 15 to around 80-90 ms.
using BenchmarkTools
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
#=if n <= 1 || s > n
return []
end=#
sieve = fill(true, n)
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
pl = [i for i in s - s % 2 + 1:2:n if sieve[i]]
return s == 2 ? unshift!(pl, 2) : pl
end
#btime get_primes_1(1_000_000)
Output with the 'if' statement commented out, as above, is:
5.752 ms (25 allocations: 2.95 MiB)
Output with the 'if' statement included is:
86.496 ms (2121646 allocations: 35.55 MiB)
I'm probably embarrassingly ignorant or being terminally stupid, but if someone could point out what I'm doing wrong it would be very much appreciated.
The problem of this function is with Julia compiler having problems with type inference when closures appear in your function. In this case the closure is a comprehension and the problem is that if statement makes sieve to be only conditionally defined.
You can see this by moving sieve up:
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
sieve = fill(true, n)
if n <= 1 || s > n
return Int[]
end
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
pl = [i for i in s - s % 2 + 1:2:n if sieve[i]]
return s == 2 ? unshift!(pl, 2) : pl
end
However, this makes sieve to be created also when n<1 which you want to avoid I guess :).
You can solve this problem by wrapping sieve in let block like this:
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
if n <= 1 || s > n
return Int[]
end
sieve = fill(true, n)
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
let sieve = sieve
pl = [i for i in s - s % 2 + 1:2:n if sieve[i]]
return s == 2 ? unshift!(pl, 2) : pl
end
end
or avoiding an inner closure for example like this:
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
if n <= 1 || s > n
return Int[]
end
sieve = fill(true, n)
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
pl = Int[]
for i in s - s %2 +1:2:n
sieve[i] && push!(pl, i)
end
s == 2 ? unshift!(pl, 2) : pl
end
Now you might ask how can you detect such problems and make sure that some solution solves them? The answer is to use #code_warntype on a function. In your original function you will notice that sieve is Core.Box which is an indication of the problem.
See https://github.com/JuliaLang/julia/issues/15276 for details. In general this is in my perception the most important issue with performance of Julia code which is easy to miss. Hopefully in the future the compiler will be smarter with this.
Edit: My suggestion actually doesn't seem to help. I missed your output annotation, so the return type appears to be correctly inferred after all. I am stumped, for the moment.
Original answer:
The problem isn't that there is an if statement, but that you introduce a type instability inside that if statement. You can read about type instabilities in the performance section of the Julia manual here.
An empty array defined like this: [], has a different type than a vector of integers:
> typeof([1,2,3])
Array{Int64,1}
> typeof([])
Array{Any,1}
The compiler cannot predict what the output type of the function will be, and therefore produces defensive, slow code.
Try to change
return []
to
return Int[]
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 so new in python and Gurobi!
recently I started to code a problem and I need to code this constraints:
for each i and j (while i is not equal to j):
(y[i][j]) * (D[i] - d[i][j])) <= T
Also I tried to start with not considering the equal part and wrote:
for i in people:
for j in people:
m.addConstr((carpools[i][j])*(distance[i]-distBtw[i][j])) <= 400
but I received this error:
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
I think this is a syntax error. You need your <= inside the addConstr:
for i in people:
for j in people:
m.addConstr((carpools[i][j])*(distance[i]-distBtw[i][j]) <= 400,
name = '%s_%s_constraint'%(i, j)
)
FYI your multiplication in there is gonna give you a quadratic constraint which can make it very difficult for gurobi to find a solution.