Skip to main content

binary variable multiplying by another variable in python

Answered

Comments

6 comments

  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Saina,

    The capitalization matters here, i.e. use gp.GRB.MINIMIZE.

    Based off the second code block, it looks like you solved your original problem?

    - Riley

    0
  • Saina Akbari Kouchaksaraei
    Gurobi-versary
    First Comment
    First Question

    Many thanks for your reply
    I tried the capital letters but still doesn’t work
    I’m not sure if I did the linearisation correctly, I only tried to use the relations based on big M like this link

    https://or.stackexchange.com/questions/39/how-to-linearize-the-product-of-a-binary-and-a-non-negative-continuous-variable

    I was wondering if there is any way that I can run the model without converting the model into linear one (based on first model)
    Sincere thanks

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Saina,

    When using gp.GRB.MINIMIZE the second code block you posted above runs without problems.

    The model is infeasible - but the code is fine.

    If you wish to understand why the model is infeasible you can compute an IIS.

    You also have the option of not linearizing the model and asking Gurobi to solve a non-convex model.  You may need to set the NonConvex parameter to 2 to allow this - the solver output will tell you.

     

    - Riley

    0
  • Saina Akbari Kouchaksaraei
    Gurobi-versary
    First Comment
    First Question

    Dear Riley

    I am so thankful for your help. It was my mistake that only checked capital letters on my first block. But yes the second one works.

    I only have one another question for the first block. As I need to develop my model later, it is easier to work with the first one. I tried to set Nonconvex parameter to 2 but it still returns error (
    TypeError: unsupported operand type(s) for *: 'generator' and 'int'). my modified code is as below. I would be grateful if you could help me to correct this issue as well.

    Sincere thanks

     

    import math
    import gurobipy as gp
    from gurobipy import GRB


    # Set data______________________________________________________________________________________________________________________

    suppliers = [1]
    warehouses = [1]
    retailers = [1]
    time_periods = list(range(1, 11))

    # Parameter data________________________________________________________________________________________________________________

    capacity = {'i': 600, 'j': 600}
    capacity2= {'r':600}
    cost = {(1, 1): 2}
    cost2 = {(1, 1): 2}
    setupcost1={(1,1):300}
    setupcost2={(1,1):300}

    # Create model
    m = gp.Model('Profit_SC')

    m.params.NonConvex = 2
    m.setParam('NonConvex', 2)

    # setup cost for delivering from warehouse to retailer

    for j in warehouses:
        for r in retailers:
            m.addVar(lb=setupcost2.get((j,r), 0), ub=setupcost2.get((j,r), 0), vtype=gp.GRB.CONTINUOUS, name="setupcost2_{}_{}".format(j,r))


    #demand in retailer r at time t

    def demand(r,t):
        for r in retailers:
              return (50*0.7*(8 * (100*0.01 / (math.e ** (0.1 * t)))))
    for t in range(1, 11):
        print("t =", t, "r=",r, "Demand =", demand(r,t))




    # Add variables

    #quantity of products delivers from supplier to warehouse
    x = {}
    for i in suppliers:
        for j in warehouses:
            for t in time_periods:
                x [i,j,t] = m.addVar(vtype="C", name="x" )

    #quantity of products delivers from warehouseto retailer     
    y = {}
    for j in warehouses:
        for r in retailers:
            for t in time_periods:
                y [j,r,t] = m.addVar(vtype="C", name="y" )  

            
    # binary variable equals to 1 ifdelivery between warehouse and retailer happens otherwise zero        
    gama2={}
    for r in retailers:
        for t in time_periods:
            gama2[r,t] = m.addVar(vtype=gp.GRB.BINARY, name="gama2")


    #inventory level at retailer        
    inv={}
    for r in retailers:
        for t in time_periods:
            inv[r,t]=m.addVar(vtype="C", name="inventory" ) 
            
    # Add constraints_______________________________________________________________________________________________________________


    #constraints for capacity            
    m.addConstrs((gp.quicksum(x[i, j, t] for j in warehouses  for i in suppliers for t in time_periods) <= capacity['i']
                  for i in suppliers for t in time_periods), name='supply')
    m.addConstrs((gp.quicksum(y[j, r, t] for j in warehouses) <= capacity['j']*gama2[r,t]
                 for r in retailers for t in time_periods), name='supply2')


    #constraints for binary variable
    m.addConstr((gp.quicksum(gama2[r,t]  for r in retailers for t in time_periods)<=1), name='binary variable 2')


    #constraints for inventory
    for r in retailers:
        for t in time_periods:
            if t>1:
              m.addConstrs((inv[r, t] == inv[r,t-1]+(y[j,r,t]*gama2[r,t])-demand(r,t) for j in warehouses ), name='inventory')

    m.addConstrs((inv[r,t]+ gp.quicksum(y[j,r,t]*gama2[r,t] for j in warehouses)<= demand(r, t) for r in retailers for t in time_periods) , name='inventory balance')




    # Set objective function________________________________________________________________________________________________________


    m.setObjective(gp.quicksum(((y[j, r, t]*gama2[r,t] for j in warehouses for r in retailers for t in time_periods )*2 )) +
                   gp.quicksum(((x[i, j, t] for i in suppliers for j in warehouses for t in time_periods ) * 2 )) +
                   ((gama2[r,t] for r in retailers for t in time_periods)*300  ),
                  sense=gp.GRB.MINIMIZE)

    m.update()

    # Solve the model
    m.optimize()


    # Print the results_____________________________________________________________________________________________________________

    print('x values:',x)
    for i in suppliers:
        for j in warehouses:
            for t in time_periods:
                print(f"x({i}, {j}, {t}) = {x[i, j, t].X}")

    print('y values:',y)
    for j in warehouses:
        for r in retailers:
            for t in time_periods:
                print(f"y({j}, {r}, {t}) = {y[j, r, t].X}")
                

    print('inventory:',inv)
    for r in retailers:
        for t in time_periods:
            print(f"inv({r}, {t}) = {inv[r, t].X}")
             
    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Saina,

    Let's have a look at the objective that is causing you the problem

    m.setObjective(gp.quicksum(((y[j, r, t]*gama2[r,t] for j in warehouses for r in retailers for t in time_periods )*2 )) +
                   gp.quicksum(((x[i, j, t] for i in suppliers for j in warehouses for t in time_periods ) * 2 )) +
                   ((gama2[r,t] for r in retailers for t in time_periods)*300  ),
                  sense=gp.GRB.MINIMIZE)

    and compare it to the other objective which works fine:

    m.setObjective(gp.quicksum((z[j,r,t] for j in warehouses for r in retailers for t in time_periods ))*2 +
                   gp.quicksum((x[i, j, t] for i in suppliers for j in warehouses for t in time_periods ))*2
                 (gp.quicksum(gama2[r,t] for r in retailers for t in time_periods))*300,
                  sense=gp.GRB.Minimize)

    One works, but one doesn't.  Can you spot the difference (noting that your error message specifically highlights the * operator)?

    - Riley

     

    0
  • Saina Akbari Kouchaksaraei
    Gurobi-versary
    First Comment
    First Question

    I got it, it works now

    Thanks

    0

Please sign in to leave a comment.