Update Param with constraint - pyomo

i want to define a constraint, which update param when assignment is occur. The constraint is as follow.
Where d is Param and Z is decision variable define as:
model.d = Param(model.V, mutable=True)
model.Z = Var(model.Vs, model.Vc2, within = Binary)
I have tried:
def Cons24_rule(model,i):
return model.d[i] == sum(model.d[j] * model.Z[i,j] for j in model.Vc2)
model.Cons24 = Constraint(model.Vs , rule = Cons24_rule)
but i get infeasibility error. How Can i able to define this constraint?
Pyomo code and test data can be found here.
Thanks - Soheil

Your instance is infeasible. Your constraint says:
d[i] = sum {j in V_c2} d[j] * Z[i,j]
for all i. This means the amount shipped out of i must exactly equal its d, and the amount shipped must fully equal the d of the destinations. But for example, d[9] = 6, and there are no other nodes j such that sum {j} d[j] = 6. So, there is no way to satisfy this constraint, i.e., no way to ship exactly 6 units out of node 9.
I suspect that the real problem is in the logic of your constraint formulation, not in your data. I don't think you want to assume that if i ships to j, then it must ship all of d[j]. Either that, or you don't want to require the total shipped out of i to equal d[i] exactly.

Related

What does Big M method do in constraints when converting nonlinear programming into linear programming?

I got a question regarding this constraints in the paper. This paper says it used big M method in order to make non-linear programming model into LP. I get that big number M1is a huge number, but I don't get what big number M1 really does on the constraints. Would you guys give me some insight on the use of the big M in this constraints?
Below is constraints with big number M1.
The paper says these constraints are
when K[m][i] = p[i]*x[m][i],
maximize sum(m in M, i in I) (K[m][i]-c[i]*x[m][i]
K[m][i]-M[1]*(1-x[m][i]) <= p[i]
K[m][i]+M[1]*(1-x[m][i]) >= p[i]
K[m][i]-M[1]*x[m][i] <= 0
it originally looked like this in non linear programming
maximize sum(m in M, i in I)(p[i]-c[i])*x[m][i]
So, basically, converting nonlinear programming into linear programming led to a little change in some decision variables and 3 additional constraints with big number M.
Here is another constraint that includes big number M.
sum (j in J) b[i][j]*p[j]-p[i]<= M[1]*y[i]
which originally looked like
p[i]<sum (j in J) b[i][j]*p[j], if y[i]==1
Here is the last constraint with big number M
(r[m][j]=p[j])*b[i][j]*x[m][i] >= -y[i]*m[1]
which was
(r[m][j]-p[j])*b[i][j]*x[m][i](1-y[i])>=0
in nonlinear program.
I really want to know what does big M do in the model.
It would be really appreciated if anyone gives me some insight.
Thank you.
As you said, the big-M is used to model the non-linear constraint
K[m][i] = p[i] * x[m][i]
in case x is a binary variable. The assumption is that M is an upper bound on K[m][i] and that K[m][i] is a non-negative variable, i.e. 0 <= K[m][i] <= M. Also p is assumed to be non-negative.
Since x[m][i] is binary, we can have two cases in a feasible solution:
x[m][i] = 0. In that case the product p[i] * x[m][i] is 0 and thus K[m][i] should be zero as well. This is enforced by constraint K[m][i] - M * x[m][i] <= 0 which in this case becomes just K[m][i] <= 0. The two other constraints involving M become redundant in this case. For example, the first constraint reduces to K[m][i] <= p[i] + M which is always true since M is an upper bound on K[m][i] and p is non-negative.
x[m][i] = 1. In that case the product p[i] * x[m][i] is just p[i] and the first two constraints involving M become K[m][i] <= p[i] and K[m][i] >= p[i] (which is equivalent to K[m][i] = p[i]). The last constraint involving M becomes K[m][i] <= M which is redundant since M is an upper bound on K[m][i].
So the role of M here is to "enable/disable" certain constraints depending on the value of x.
to model logical constraints you may either use logical constraints or rely on big M
https://www.ibm.com/support/pages/difference-between-using-indicator-constraints-and-big-m-formulation
I tend to suggest logical constraint as the default choice.
In https://www.linkedin.com/pulse/how-opl-alex-fleischer/
let me share the example
How to multiply a decision variable by a boolean decision variable in CPLEX ?
// suppose we want b * x <= 7
dvar int x in 2..10;
dvar boolean b;
dvar int bx;
maximize x;
subject to
{
// Linearization
bx<=7;
2*b<=bx;
bx<=10*b;
bx<=x-2*(1-b);
bx>=x-10*(1-b);
// if we use CP we could write directly
// b*x<=7
// or rely on logical constraints within CPLEX
// (b==1) => (bx==x);
// (b==0) => (bx==0);
}

How to include if-statement with decision variables in cplex constraints properly

This is similar to a problem of moving from a decentralized system to a centralized one. Therefore, I want to identify the optimal locations to use as centralized points and the locations that need to be closed. These are my binary decision variables Xi and Yj.
I have two constraints that include an if-statement with decision variables. I have read that in this case I must use logical constraints, so I did.
forall (i in Drives, j in Locations)(Y[j]==1 && Distance[j][i]<=20) => X[i]==0;
I want this constraint to say that if a location j is chosen (Yj = 1) and if the distance between i and j is less than 20 , then => I want to close location i (Xi = 0)
forall (j in Locations, k in Locations)(Y[j]==1 && Distance2[j][k]<=40) => Y[k]==0;
Similarly, this constraint says that if a location j is chosen (Yj = 1) and if the distance between 2 potential locations is less than 40, then I do not want to choose location k (Yk = 0)
The model gives a result but as I check the numbers, it seems to ignore these 2 constraints. So, something is not working properly in the terms used.
The constraints look mostly correct to me. What looks a bit fishy in the second constraint is that you don't exclude the case j==k. If Y[j]==1 then probably Distance2[j][j]==0 and thus the second constraint implies Y[j]==0. A contradiction!
Are you sure that CPLEX claims your solution optimal? Or are you maybe looking at a relaxed solution (which would then be allowed to violate constraints)?
Assuming Distance is data and not a decision variable, your constraints could be written in a more efficient way. For example the first one:
forall(i in Drives)
forall(j in Locations : Distance[j][i] <= 20)
X[i] <= 1 - Y[j]; // If Y[j]==1 then the right-hand side becomes zero and forces X[i]==0
Similary, the second constraint could be written as
forall(j in Locations)
forall(k in Locations : k != j && Distance2[j][k] <= 40)
Y[k] <= 1 - Y[j]; // If Y[j]==1 then the right-hand side becomes zero and forces Y[k]==0
Can you try with these more explicit constraints or at least with excluding the case j==k in the second constraint?

Linear program objective function depends on sign of variable

I'm trying to find Q[i] to maximize
Sum[Q[i] F[i] - C[i], {i, 1, n}]
subject to some linear constraints. The problem: C[i] is a function of Q[i] but isn't linear. It's equal to Q[i] * Cp if Q[i] >= 0, and -Q[i] * Cn if Q[i] < 0 (basically a cost term that's different if Q[i] is positive vs negative).
I suspect I need to use some version of integer programming to reformulate this properly but can't see how to get there. Can anyone point me the right way, or maybe just tell me this can't be done? :)
Here is a Mixed Integer formulation with some additional binary variables:
We use variable splitting to have two components of Q (positive and negative). Using a binary variable we make sure only one of those components is nonzero. This will require new continuous variables q+ and q- and new binary variables delta.
The constant M+ and M- are an upper bound on q+, q-. Make them as small as possible (100 or 1000 is better than 1e6 or 1e7).
Now there is something we can exploit. The objective will push down the C term in order to maximize the total objective. This means we can drop the equations with the binary variable, as automatically only one of q-, q+ will be nonzero. I.e. if Q=-10, it will prefer q+ = 0, q- = 10 above q+ = 2, q- = 12. So the final model is actually a straight LP:

Subset sum variant with a non-zero target sum

I have an array of integers and need to apply a variant of the subset sum algorithm on it, except that instead of finding a set of integers whose sum is 0 I am trying to find a set of integers whose sum is n. I am unclear as to how to adapt one of the standard subset sum algorithms to this variant and was hoping for any insight into the problem.
This is subset sum problem, which is NP-Complete (there is no known efficient solution to NP-Complete problems), but if your numbers are relatively small integers - there is an efficient pseudo polynomial solution to it that follows the recurrence:
D(x,i) = false x<0
D(0,i) = true
D(x,0) = false x != 0
D(x,i) = D(x,i-1) OR D(x-arr[i],i-1)
Later, you need to step back on your choices, see where you decided to "reduce" (take the element), and where you decided not to "reduce" (not take the element), on the generated matrix.
This thread and this thread discuss how to get the elements for similar problems.
Here is a python code (taken from the thread I linked to) that does the trick.
If you are not familiar with python - read it as pseudo code, it's pretty easy to understand python!.
arr = [1,2,4,5]
n = len(arr)
SUM = 6
#pre processing:
D = [[True] * (n+1)]
for x in range(1,SUM+1):
D.append([False]*(n+1))
#DP solution to populate D:
for x in range(1,SUM+1):
for i in range(1,n+1):
D[x][i] = D[x][i-1]
if x >= arr[i-1]:
D[x][i] = D[x][i] or D[x-arr[i-1]][i-1]
print D
#get a random solution:
if D[SUM][n] == False:
print 'no solution'
else:
sol = []
x = SUM
i = n
while x != 0:
possibleVals = []
if D[x][i-1] == True:
possibleVals.append(x)
if x >= arr[i-1] and D[x-arr[i-1]][i-1] == True:
possibleVals.append(x-arr[i-1])
#by here possibleVals contains 1/2 solutions, depending on how many choices we have.
#chose randomly one of them
from random import randint
r = possibleVals[randint(0,len(possibleVals)-1)]
#if decided to add element:
if r != x:
sol.append(x-r)
#modify i and x accordingly
x = r
i = i-1
print sol
You can solve this by using dynamic programming.
Lets assume that:
N - is the sum that required (your first input).
M - is the number of summands available (your second input).
a1...aM - are the summands available.
f[x] is true when you can reach the sum of x, and false otherwise
Now the solution:
Initially f[0] = true and f[1..N] = false - we can reach only the sum of zero without taking any summand.
Now you can iterate over all ai, where i in [1..M], and with each of them perform next operation:
f[x + ai] = f[x + ai] || f[x], for each x in [M..ai] - the order of processing is relevant!
Finally you output f[N].
This solution has the complexity of O(N*M), so it is not very useful when you either have large input numbers or large number of summands.

Integer Linear Programming formulation for Test Cover?

The Test Cover problem can be defined as follows:
Suppose we have a set of n diseases and a set of m tests we can perform to check for symptoms. We also are given the following:
an nxn matrix A where A[i][j] is a binary value representing the result of running the jth test on a patient with the the ith disease (1 indicates a positive result, 0 indicates negative);
the cost of running test j, c_j; and that
any patient will have exactly one disease
The task is to find a set of tests that can uniquely identify each of the the n diseases at minimal cost.
This problem can be formulated as an Integer Linear Program, where we want to minimize the objective function \sum_{j=1}^{m} c_j x_j, where x_j = 1 if we choose to include test j in our set, and 0 otherwise.
My question is:
What is the set of linear constraints for this problem?
Incidentally, I believe this problem is NP-hard (as is Integer Linear Programming in general).
Well if I am correct you just need to ensure
\sum_j x_j.A_ij >= 1 forall i
Let T be the matrix that results from deleting the jth column of A for all j such that x_j = 0.
Then choosing a set of tests that can uniquely distinguish any two diseases is equivalent to ensuring that every row of T is unique.
Observe that two rows k and l are identical if and only if (T[k][j] XOR T[l][j]) = 0 for all j.
So, the constraints we want are
\sum_{j=1}^{m} x_j(A[k][j] XOR A[l][j]) >= 1
for all 1 <= k <= m and 1 <= l <= 1 such that k != l.
Note that the constraints above are linear, since we can just pre-compute the coefficient (A[k][j] XOR A[l][j]).