メインコンテンツへスキップ

Binary variable in divisor

回答済み

コメント

8件のコメント

  • 正式なコメント
    Simranjit Kaur
    • Gurobi Staff Gurobi Staff
    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?.
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    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
  • M
    • Gurobi-versary
    • Conversationalist
    • First Question

    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 = 1

    I 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,
    Marcel

    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    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
  • M
    • Gurobi-versary
    • Conversationalist
    • First Question
    Dear Jaromił,
     
    Basically my problem refers to  a facility location problem:
    min costs = setup costs + regular service costs + special service costs
    min costs = x * s + a / ((1 - x * m ) * b)   +   c * b * x * m
     
    Condition 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 services
    0<m<1        fraction of people using special services
    x                   binary variable if facility should be built in an area
    a, c, s           constants
     
    For 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,
    Marcel
    0
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    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
  • M
    • Gurobi-versary
    • Conversationalist
    • First Question

    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
  • Jaromił Najman
    • Gurobi Staff Gurobi Staff

    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

投稿コメントは受け付けていません。