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.
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 ...
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
I'm trying to do some stencil computation using Halide. So assuming a basic 5 point 2D stencil, to evaluate some value at cell i,j I need the values of i-1,j i-2,j, i+1,j i+2,j. Now the way this works in C++ is that I have a for statement:
for(int i = 2; i < max_i - 2; i++)
for(int j = 2; j < max_j - 2; j++)
Calculate out = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j))
Now I'm trying to do the same thing with Halide. so I have a Buffer called in which has the same value as my input array in the C++ code. And I have a Func called out:
out(i,j) = select(i >= 2 && j >= 2, some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j)) ,0.0f)
When I run this code I get the following error:
Error:
Input buffer b0 is accessed at -1, which is before the min (0) in dimension 0
Aborted (core dumped)
From my understanding, the reason for this error is that the select statement evaluates both statements so eventhough I don't want to calculate anything for i and j values less than two, the function is evaluated at i = 0 and j = 0 and thus the invalid address access.
So is there anyway to do this in Halide? Are there any other equivalents for if/else statements?
Using a boundary condition will do what you want:
Func unbounded;
unbounded(i, j,) = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j));
out(i, j) = BoundaryConditions::constant_exterior(unbounded, 0.0f, 2, width - 4, 2, height - 4)(i, j);
I believe you can use "Expr()" instead of "width - 4" or "height - 4" if you want the maximum unbounded.
The use if BoundaryConditions functions allows hinting the compiler which direction of the if/else construct is more likely.
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 have a bug in my program in OCaml and I am looking for help.
the error:
This expression has type unit but an expression was expected of type int
The line error with the error contains soma = soma
let soma = 0;;
let rec nBell n =
if n == 0 then 1
else
for k=0 to n-1 do
soma = soma + ((fact(n-1)/(fact(k)*fact((n-1)-k))) * nBell(k));
done;;`
Can anyone help me?
As has recently been mentioned here quite a few times, OCaml has no statements. It only has expressions. For an if expression to make sense, the then and else parts have to be the same type. In your code the then part is 1. I.e., it has type int. In the else part you have a for expression. The type of a for expression is unit. So that's what the compiler is complaining about.
However, fixing this problem will be just the first step, as your code is based on a misunderstanding of how OCaml variables work. OCaml variables like soma are immutable. You can't change their value. So the expression soma = soma + 1 is actually a comparison that tells whether the two values are equal:
# let soma = 0;;
val soma : int = 0
# soma = soma + 1;;
- : bool = false
Generally speaking, you need to find a way to solve your problem without assigning to variables; i.e., without changing their values.
If you're just starting with functional programming, this seems absurd. However it turns out just to be another way to look at things.