Skip to main content

Encountered an attribute error when running SetObjective()

Answered

Comments

10 comments

  • Official comment
    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?.
  • Eli Towle
    • Gurobi Staff Gurobi Staff

    Can you try using m.setObjective() (lowercase "s") instead of m.SetObjective()?

    1
  • Filip Horák
    • Gurobi-versary
    • First Comment
    • First Question

    Hello Eli,

    thank you very much for super fast answer. Its working now. I apologise for posting question for a rookie mistake like this. I went through the code dozen of times and this little thing eluded me. Thank you!

    0
  • Reza Farzadnia
    • Gurobi-versary
    • First Comment

    I have the same issue but don't know what the problem is. Could someone check it, please?

    try:

        # Create the primary supply chain model
        primarySC = gp.Model("Primary Supply Chain Model")

        # Create variables
        P_n = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_n")
        P_o = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_o")
        Q   = primarySC.addVars(set_p, set_i, set_t, set_t, vtype=GRB.CONTINUOUS, lb=0, name="q")
        U_n = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_n")
        U_o = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_o")
        Z   = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="z")
        Y   = primarySC.addVars(set_p, set_i, set_t, vtype=GRB.BINARY, name="y")

        

        # Add constraint: 6b
        ###########################################
        def tau_l(p,tau): # because in constraints 6_b, t is a function of tau it was needed to calculate each t dependent to each tau
            global new_set_t
            new_set_t = tau.copy()
            global j
            j=0
            for value in tau:  
                if j < (len(tau) - l[p]):
                    new_set_t.remove(value)
                j +=1
            #print(j)
            return new_set_t
        #tau_l('p1',set_t)
            
        cons_6b = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] + U_n[p,tau] == d_n(p,t) for i in set_i for t in tau_l(p,tau)) for tau in set_t for p in set_p)
        primarySC.addConstrs(cons_6b, "cons_6b")

        # Add constraint: 6c
        ###########################################
        def tau_f(p,tau): # because in constraints 6_c, t is a function of tau it was needed to calculate each t dependent to each tau
            global new_set_tau
            new_set_tau = tau.copy()
            global j
            j=0
            for value in tau:  
                if (j < (len(tau) - f_hat[p])) or (j > ( len(tau) - l[p]) + 1 ):
                    new_set_tau.remove(value)
                j +=1
            #print(j)
            return new_set_tau
        cons_6c = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] + U_o[p,tau] == d_o(p,t) for i in set_i for t in tau_f(p,tau)) for tau in set_t for p in set_p)
        primarySC.addConstrs(cons_6c, "cons_6c")
        
        # Add constraint: 6d
        ###########################################
        def t_f_1(p,tau): # because in constraints 6_d, t is a function of tau it was needed to calculate each t dependent to each tau
            t = tau - f_hat[p] - 1
            return t
        cons_6d = (gp.quicksum(kappa[p,(t_f_1(p,tau)),tau]*Q[p,i,(t_f_1(p,tau)),tau] for i in set_i) == Z[tau] for tau in set_t)
        primarySC.addConstrs(cons_6d, "cons_6d")
        
        # Add constraint: 6e
        ###########################################
        def tau_t(p,t): # because in constraints 6_e, t is a function of tau it was needed to calculate each t dependent to each tau
            global new_set_tau_t
            new_set_tau_t = ()
            new_set_tau_t = set_t.copy()
            global j
            j=0
            for value in set_t:  
                if j < int(t[1])-1:
                    new_set_tau_t.remove(value)
                j +=1
            #print(j)
            return new_set_tau_t
        cons_6e = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] for tau in tau_t(p,t)) - delta[p,i,t]*Y[p,i,t] <= 0 for i in set_i for t in set_t)
        primarySC.addConstrs(cons_6d, "cons_6e")

        
        # Set objective
        ###########################################
        obj_ksi = gp.quicksum(s[p,i]*Y[p,i,t] for p in set_p for t in set_t for i in set_i)
        -gp.quicksum(alpha_n[p]*P_n[p] + alpha_o[p]*P_o[p] - beta_n[p]*(P_n[p]**2) 
                     - teta_o[p]*(P_o[p]**2) + (beta_o[p] + teta_n[p])*P_n[p]*P_o[p]
                     for p in set_p)*len(set_t)
        obj_phi = gp.quicksum(f_n_pt[p,t]*U_n[p,t] + f_o_pt[p,t]*U_o[p,t] - (P_n[p]*w_n[p,s] + P_o[p]*w_o[p,s])
                              + gp.quicksum(c(p,i,t,tau)*Q[p,i,t,tau] for i in set_i for tau in set_t)
                              for s in set_s for t in set_t for p in set_p)
        obj_func= obj_ksi + 1/len(set_s)*obj_phi
        primarySC.setObjective(obj_func, GRB.MINIMIZE)
        # Optimize model
        primarySC.optimize()

        for v in m.getVars():
            print('%s %g' % (v.VarName, v.X))

        print('Obj: %g' % m.ObjVal)

    except gp.GurobiError as e:
        print('Error code ' + str(e.errno) + ': ' + str(e))

    except AttributeError:
        print('Encountered an attribute error')
    0
  • Riley Clement
    • Gurobi Staff Gurobi Staff

    Hi Reza,

    Please edit your code to be a minimal reproducible example, remove the try-except statements and include the resulting traceback.

    - Riley

    0
  • Reza Farzadnia
    • Gurobi-versary
    • First Comment

    Hi Riley,

    I appreciate your help,

    I have made my example, MRE.

    import gurobipy as gp
    from gurobipy import GRB
    #--------------
    import numpy as np
    import random 

    print (' ------------ Libraries are imported  ')
    # ---------------- sets
    # sets: data
    set_i = ['i1', 'i2']
    set_t = ['t1', 't2', 't3', 't4', 't5', 't6', 't7']
    set_p = ['p1', 'p2']
    set_s = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10']

    # ---------------- parameters
    # parameters: functions
    def kappa(p,period,tau_period):
        t= int(period[1])
        tau= int(tau_period[1])
        defer = tau - t
        rhoo = rho[p]
        global result
        result = 1.0
        for i in range(defer):
            result = round(result*(1-rhoo), 4)
        return result

    def c(p,i,period,tau_period):
        t= int(period[1])
        tau= int(tau_period[1])
        defer = tau - t
        #rhoo = rho[p]
        global result
        result = 0
        for n in range(defer):
            result += h[p]*kappa(p,period,"t"+str(t+n+1))
        return round(r[str(p) ,str(i)] + result, 4)

    # parameters: data
    rho =   {'p1': 0.02,'p2': 0.03}
    l =     {'p1': 1,'p2': 2}
    f_hat = {'p1': 2,'p2': 3}
    h =     {'p1': 1,'p2': 1.5}
    f_n_pt, f_o_pt, g_n_pt, g_o_pt = {},{},{},{}
    for t in set_t:
        for p in set_p:
            f_n_pt[p, t] = 1000
            f_o_pt[p, t] = 1500
            g_n_pt[p, t] = 900
            g_o_pt[p, t] = 1200

    w_n, w_o = {},{}

    for s in set_s:
        w_n['p1', s] = random.randint(0,150) # deterministic w for new products
        w_n['p2', s] = random.randint(0,150) # deterministic w for new products
        
        w_o['p1', s] = random.randint(0,175) # deterministic w for old products
        w_o['p2', s] = random.randint(0,175) # deterministic w for old products

    teta_o = {'p1': 1.5,'p2': 1.9}
    teta_n = {'p1': teta_o['p1'] * 1.5,'p2': teta_o['p2'] * 1.9}

    beta_o = {'p1': 2.5,'p2': 2}
    beta_n = {'p1': beta_o['p1'] * 1.5,'p2': beta_o['p2'] * 1.9}

    alpha_n = {'p1': 450,'p2': 400} # price can be p1 : 1.1 $/unit  |  p2 : 1.7 $/unit
    alpha_o = {'p1': 150,'p2': 110} # price can be p1 : 0.8 $/unit  |  p2 : 1.3 $/unit

    s, r = {},{}
    for p in set_p:
        s[p,'i1']= round(random.uniform(150,250), 2)
        s[p,'i2']= round(random.uniform(250,350), 2)
        r[p,'i1']= round(random.uniform(25,30), 2)
        r[p,'i2']= round(random.uniform(20,25), 2)

    #delta = df_delta['delta_pis'].to_dict() # scenario based delta

    for t in set_t:
        delta = {
            ('p1','i1',t): alpha_n['p1'] + random.randint(0,int(alpha_n['p1']*0.1)), # alpha + random(0.1)
            ('p2','i1',t): alpha_n['p2'] + random.randint(0,int(alpha_n['p2']*0.1)),
            ('p1','i2',t): alpha_n['p1'] + random.randint(0,int(alpha_n['p1']*0.1)),
            ('p2','i2',t): alpha_n['p2'] + random.randint(0,int(alpha_n['p2']*0.1)),
                    }

    # nonstationary demand
    def d_n(p,t):
        demand = alpha_n[p] - beta_n[p]*P_n[p] + beta_o[p]*P_o[p] + w_n[p,s]
        return demand

    def d_o(p,t):
        demand = alpha_o[p] - teta_o[p]*P_o[p] + teta_n[p]*P_n[p] + w_o[p,s]
        return demand

    print (' ------------ Data Imported  ')




    # Create the primary supply chain model
    primarySC = gp.Model("Primary Supply Chain Model")

    # Create variables
    P_n = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_n")
    P_o = primarySC.addVars(set_p, vtype=GRB.CONTINUOUS, lb=0, name="p_o")
    Q   = primarySC.addVars(set_p, set_i, set_t, set_t, vtype=GRB.CONTINUOUS, lb=0, name="q")
    U_n = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_n")
    U_o = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="u_o")
    Z   = primarySC.addVars(set_p, set_t, vtype=GRB.CONTINUOUS, lb=0, name="z")
    Y   = primarySC.addVars(set_p, set_i, set_t, vtype=GRB.BINARY, name="y")




    # Add constraint: 6b
    ###########################################
    cons_6b = (gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau]  + U_n[p,tau] >= d_n(p,t) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0))) for tau in set_t for p in set_p)
    primarySC.addConstrs(cons_6b, "cons_6b")

    # Add constraint: 6c
    ###########################################
    cons_6c = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] + U_o[p,tau] >= d_o(p,t) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - f_hat[p])) and (int(t[1]) <= (int(tau[1]) - l[p] + 1)) and ((int(tau[1]) - f_hat[p]) > 0))) for tau in set_t for p in set_p)
    primarySC.addConstrs(cons_6c, "cons_6c")

    # Add constraint: 6d
    ###########################################
    def t_f_1(p,tau): # because in constraints 6_d, t is a function of tau it was needed to calculate each t dependent to each tau
        t = "t" + str(int(tau[1]) - f_hat[p] - 1)
        return t
    cons_6d = (gp.quicksum(kappa[p,(t_f_1(p,tau)),tau]*Q[p,i,(t_f_1(p,tau)),tau] for i in set_i) == Z[tau] for tau in set_t if (int(tau[1]) - f_hat[p] - 1) > 0)
    primarySC.addConstrs(cons_6d, "cons_6d")

    # Add constraint: 6e
    ###########################################
    cons_6e = (gp.quicksum(kappa[p,t,tau]*Q[p,i,t,tau] for tau in set_t if tau >= t) - delta[p,i,t]*Y[p,i,t] <= 0 for i in set_i for t in set_t)
    primarySC.addConstrs(cons_6d, "cons_6e")


    # Set objective
    ###########################################
    obj_ksi = gp.quicksum(s[p,i]*Y[p,i,t] for p in set_p for t in set_t for i in set_i)
    -gp.quicksum(alpha_n[p]*P_n[p] + alpha_o[p]*P_o[p] - beta_n[p]*(P_n[p]**2) 
                 - teta_o[p]*(P_o[p]**2) + (beta_o[p] + teta_n[p])*P_n[p]*P_o[p]
                 for p in set_p)*len(set_t)
    obj_phi = gp.quicksum(f_n_pt[p,t]*U_n[p,t] + f_o_pt[p,t]*U_o[p,t] - (P_n[p]*w_n[p,s] + P_o[p]*w_o[p,s])
                          + gp.quicksum(c(p,i,t,tau)*Q[p,i,t,tau] for i in set_i for tau in set_t)
                          for s in set_s for t in set_t for p in set_p)
    obj_func= obj_ksi + 1/len(set_s)*obj_phi
    primarySC.setObjective(obj_func, GRB.MINIMIZE)
    # Optimize model
    primarySC.optimize()

    for v in m.getVars():
        print('%s %g' % (v.VarName, v.X))

    print('Obj: %g' % m.ObjVal)

    The traceback is as below:

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-5-c96e14f2af17> in <module>
         16 ###########################################
         17 cons_6b = (gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau]  + U_n[p,tau] >= d_n(p,t) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0))) for tau in set_t for p in set_p)
    ---> 18 primarySC.addConstrs(cons_6b, "cons_6b")
         19 
         20 # Add constraint: 6c
    
    src\gurobipy\model.pxi in gurobipy.Model.addConstrs()
    
    src\gurobipy\model.pxi in gurobipy.Model.addConstr()
    
    TypeError: unsupported operand type(s) for -: 'gurobipy.LinExpr' and 'NoneType'

     

    0
  • Riley Clement
    • Gurobi Staff Gurobi Staff

    Hi Reza,

    There's an issue with your d_n and d_o function, in that they try to use s as an index, e.g. w_n[p,s], but s is a dictionary.  I suspect this is a typo, but it will need to be fixed.

    You will also need to address the generator you are passing to the quicksum function in the creation of cons_6b.  At the moment it is trying to sum together constraints of the form:

    kappa(p,t,tau)*Q[p,i,t,tau]  + U_n[p,tau] >= d_n(p,t)

    It may just be a case of mismatched parentheses.

    - Riley

    1
  • Reza Farzadnia
    • Gurobi-versary
    • First Comment

    Hi Riley,

    Thank you very much for your help,

    I solved the problems thanks to your help.

    I solved the second problem (quicksum) by replacing:

    gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau]  + U_n[p,tau] >= d_n(p) for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0)))

    with the following corrected code:

    gp.quicksum(kappa(p,t,tau)*Q[p,i,t,tau]  + U_n[p,tau] for i in set_i for t in set_t if ((int(t[1]) >= (int(tau[1]) - l[p])) and (int(t[1]) <= int(tau[1])) and ((int(tau[1]) - l[p]) > 0))) >= d_n(p)

    Thanks,

     

    0
  • Riley Clement
    • Gurobi Staff Gurobi Staff

    Hi Reza,

    No problem, good to hear you were able to resolve it.  My only other advice is that some indentation, limiting line length, and use of functions could help readability of the code.

    Eg

    def meaningful_function_name(i,t,tau,p):
        tau_1, t_1 = int(tau[1]), int(t[1])
      return 0 < tau_1 - l[p] <= t_1 <= tau_1

    gp.quicksum(
        kappa(p,t,tau)*Q[p,i,t,tau]  + U_n[p,tau]
        for i in set_i
        for t in set_t 
        if meaningful_function_name(i,t,tau,p)
    )


    - Riley

    1
  • Reza Farzadnia
    • Gurobi-versary
    • First Comment

    Hi Riley,

    Many thanks for your fantastic support and advice !!

    Cheers.

    0

Post is closed for comments.