Binary variable in divisor
回答済みDear Community,
I face a problem that I could not completely solve:
x is my binary decision variable that determines if a facility should be opened (x=1) or not (x=0)
(10)/((1- x * .1) * 100) + s * (1 - x * r)
I could rewrite the first part as:
minimize: (10*y)/(100)
s.t. y- x* y .1 = 1.
However, I am struggling with the second part.
I have two questions:
a) What does it tell me if the solver says y = 1 and x = 0? Should a facility be built or no?
b) Do I have to rewrite the second component in terms of y? If yes, how?
Thank you for your support!
-
正式なコメント
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi Marcel,
The case \(y=1\) and \(x=0\) is the same as \(x=0\), i.e., the facility shall not be built, since you used \(y\) only to formulate the division. The case \(y=\frac{10}{9}\) and \(x=1\) represents the case \(x=1\).
You have to rewrite the second component only if all three terms \(s,x,\) and \(r\) are optimization variables, since then you get a trilinear product. The reformulation of multilinear products is discussed in our Knowledge Base article How do I model multilinear terms in Gurobi?
Best regards,
Jaromił0 -
Hi Jaromił,
thank you very much for your response. Actually the .1 is not a constant but an input variable (m). The problem is like this:
a / ((1- x * m ) * b) + c * (1 - x * d) a, b, c, d are constants, m = changing input variable, x=binary
Can I simply rewrite this problem as:
a*y / b + c * (1 - x * d)
s.t. y - x * y * m = 1I classified y as y = m.addVar(vtype=GRB.CONTINUOUS, name="y"), correct?
If I plug in several input values of m and solve the problem to determine x, the solver solution does not determine the correct overall solution for x in comparison to manual computation. What do you think is the error?
Thank you,
Marcel0 -
Hi Marcel,
You should always provide lower and upper bounds for the new variable \(y\), see How do I divide by a variable in Gurobi?
The bounds of \(y\) depend in your case on the value of \(m\).What exactly do you mean by an incorrect overall solution for \(x\) in comparison to manual computation. Could you provide a minimal example showing the issue?
Best regards,
Jaromił0 -
Dear Jaromił,min costs = setup costs + regular service costs + special service costsmin costs = x * s + a / ((1 - x * m ) * b) + c * b * x * mCondition for b: all demand must be satisfied (if no facility is built, only the second component of the term should determine total costs)b >= 0 number of used services0<m<1 fraction of people using special servicesx binary variable if facility should be built in an areaa, c, s constantsFor one area, b and m are constant. I read your post about how to divide by a variable.If I add m.addConstr(1 < y < 1/(1-1*m)) to my model, it does not work.How should the constraints look like in Python?Thank you,Marcel0
-
Dear Marcel,
Strict inequalities are not allowed in (Mixed-Integer) Linear Programming, since then the (relaxed) feasible set would not be closed.
You could use a small \(\epsilon\) to formulate the inequalites, e.g.,
\[1+\epsilon \leq y \leq \frac{1}{1-1*m} - \epsilon\]
with, e.g., \(\epsilon = 10^{-6}\).
In Python this would be
y = z.addVar(vtype=GRB.CONTINUOUS, name ="y")
eps = 1e-6
m = 0.1
z.addConstr( 1.0 + eps <= y, name = "lower_bound_y" )
z.addConstr( y <= 1.0/(1.0 - 1.0*m)-eps, name = "upper_bound_y")In your case, using the \(\epsilon\) should be avoided, since you introduced \(y\) to reformulate the division. Thus, you should just use
m = 0.1
y = z.addVar(vtype=GRB.CONTINUOUS, lb=1.0, ub = 1.0/(1.0 - 1.0*m), name ="y")Best regards,
Jaromił0 -
Dear Jaromił,
thank you very much for your response. So I added the variable and it does still not work. Do I need the following constraint:
m.addConstr(y - x * y * m == 1 )?
If I run the model with the constraint or without, it leads to an error and points at the "y = z.addVar(vtype= ...) that you stated above.
TypeError: unsupported operand type(s) for *: 'float' and 'Model'
Thank you,
Marcel
0 -
Hi Marcel,
Is it possible that your Model object is called \(\texttt{m}\)? Please use a different variable for the constant value \(m\) then, e.g., \(\texttt{m_const}\).
Best regards,
Jaromił1
投稿コメントは受け付けていません。
コメント
8件のコメント