Skip to main content

setting division in objective function

Answered

Comments

5 comments

  • Ryuta Tamura
    Gurobi Staff Gurobi Staff

    Hi Audrius,

    As the error message states, the objective function must be linear or quadratic. This can be resolved using auxiliary variable and addGenConstrNL method:

    obj = m.addVar(name="obj")
    m.addGenConstrNL(obj,sinx/(cos2x+1))
    m.setObjective(obj, GRB.MINIMIZE)

    Moreover, you can also define an obj directly (without the variables "sinx","cos2x"...)

    obj = m.addVar(name="obj")
    m.addGenConstrNL(obj, gp.nlfunc.sin(x)/(gp.nlfunc.cos(2*x) + 1))
    m.setObjective(obj, GRB.MINIMIZE)

     

    Thanks,
    Ryuta

    0
  • Audrius Kabasinskas

    this is good. what if at initial point we get division by 0? i'v changed the objective a little bit to force get division by 0:

    import gurobipy as gp
    from gurobipy import GRB


    def printsol(m, x):
        print(f"x = {x.X}")
        print(f"Obj = {m.ObjVal}")


    try:
        # Create a new model
        m = gp.Model()

        # Create variables
        x = m.addVar(lb=-4, ub=4, name="x")
        twox = m.addVar(lb=-8, ub=8, name="2x")
        sinx = m.addVar(lb=-1, ub=1, name="sinx")
        cos2x = m.addVar(lb=-1, ub=1, name="cos2x")
        expx = m.addVar(name="expx")

        # Set objective
        obj = m.addVar(name="obj")
        m.addGenConstrNL(obj,sinx/(cos2x-1))
        m.setObjective(obj, GRB.MINIMIZE)


        # Add linear constraints
        lc1 = m.addConstr(0.25 * expx - x <= 0)
        lc2 = m.addConstr(2.0 * x - twox == 0)

        # Add general function constraints
        # sinx = sin(x)
        gc1 = m.addGenConstrSin(x, sinx, "gc1")
        # cos2x = cos(twox)
        gc2 = m.addGenConstrCos(twox, cos2x, "gc2")
        # expx = exp(x)
        gc3 = m.addGenConstrExp(x, expx, "gc3")

        # Approach 1) Set FuncNonlinear parameter

        m.params.FuncNonlinear = 1

        # Optimize the model
        m.optimize()
    except gp.GurobiError as e:
        print(f"Error code {e.errno}: {e}")

    except AttributeError:
        print("Encountered an attribute error")

    Model has 3 function constraints treated as nonlinear
      1 EXP, 1 SIN, 1 COS
    Model has 1 general nonlinear constraint (1 nonlinear terms)
    Variable types: 6 continuous, 0 integer (0 binary)
    Coefficient statistics:
      Matrix range     [2e-01, 2e+00]
      Objective range  [1e+00, 1e+00]
      Bounds range     [1e+00, 8e+00]
      RHS range        [0e+00, 0e+00]
    Presolve time: 0.00s
    
    Explored 0 nodes (0 simplex iterations) in 0.01 seconds (0.00 work units)
    Thread count was 1 (of 112 available processors)
    
    Solution count 0
    
    Model is infeasible
    Best objective -, best bound -, gap -
    0
  • Ryuta Tamura
    Gurobi Staff Gurobi Staff

    Hi,

    Please see this description. Gurobi implicitly tries to avoid division by zero. However, to avoid unexpected behavior, it is recommended to explicitly constrain the denominator to be non-zero so that division by zero does not occur.

    Thanks,
    Ryuta

    0
  • Audrius Kabasinskas

    if this happens at stage of initial point selection, so how I can prevent this? I'd like to try something like numerator = 10
    denominator = 0
    result = numerator / denominator if denominator != 0 else float('inf'
    Would it work within gurobi environment?

    0
  • Ryuta Tamura
    Gurobi Staff Gurobi Staff

    This model will be Infeasible: 

    m = gp.Model()
    x = m.addVar(lb=10, ub=10, name="x")
    y = m.addVar(lb=0,ub=0, name="y")
    z = m.addVar(name="z")
    m.addGenConstrNL(z,x/y)
    m.optimize()

    As this description states, the denominator cannot be 0. So it should be taken into account that the denominator should not be zero at the stage of building a math model (before solving).

    Thanks,
    Ryuta

    0

Please sign in to leave a comment.