예제 #1
0
    def SolveDetModel(self, demandScenario):
        def GetResults(self, DetModel, I, Z, Transshipment_X):
            resultsdict = {}
            plants = range(self.supplier)
            items = range(self.holding_cost.shape[0])
            resultsdict['# of Open DC'] = sum([Z[i].x for i in plants])
            resultsdict['Open DC'] = [Z[i].x for i in plants]
            resultsdict['Total Inventory'] = sum(
                [I[k, i].x for k in items for i in plants])
            resultsdict['Inventory'] = [[I[k, i].x for i in plants]
                                        for k in items]
            resultsdict['Fixed Cost'] = sum(
                [Z[i].x * self.fixed_cost[i] for i in plants])
            resultsdict['Holding Cost'] = [
                sum([I[k, i].x * self.holding_cost[k, i] for i in plants])
                for k in items
            ]
            return resultsdict

        DetModel = grb.Model('DetModel')
        DetModel.setParam('OutputFlag', 0)
        DetModel.modelSense = grb.GRB.MINIMIZE

        plants = range(self.supplier)
        demand = range(self.retailer)
        items = range(self.lower_demand.shape[0])

        I = DetModel.addVars(items, plants, vtype=grb.GRB.CONTINUOUS, name='I')
        Z = DetModel.addVars(plants, vtype=grb.GRB.BINARY, name='Z')
        Transshipment_X = DetModel.addVars(items,
                                           plants,
                                           demand,
                                           vtype=grb.GRB.CONTINUOUS,
                                           name='Transshipment_X')

        objFunc_holding = sum(
            [I[k, i] * self.holding_cost[k, i] for k in items for i in plants])
        objFunc_fixed = sum([Z[i] * self.fixed_cost[i] for i in plants])
        objFunc_transportation = grb.quicksum([
            Transshipment_X[k, i, j] * self.transportation_cost[k, i, j]
            for k in items for i in plants for j in demand
        ])
        objFunc = objFunc_holding + objFunc_fixed + objFunc_transportation

        DetModel.setObjective(objFunc)

        #添加评估模型的约束
        #约束1
        for i in plants:
            for k in items:
                DetModel.addConstr(
                    grb.quicksum([Transshipment_X[k, i, j]
                                  for j in demand]) <= I[k, i])

        #约束2
        for j in demand:
            for k in items:
                DetModel.addConstr(
                    grb.quicksum([Transshipment_X[k, i, j]
                                  for i in plants]) == demandScenario[k, j])

        #约束3 其实是paper中的4,gurobi自带正数约束
        for i in plants:
            for j in demand:
                if round(self.graph[i, j]) == 0:
                    for k in items:
                        DetModel.addConstr(Transshipment_X[k, i, j] <= 0)

        #约束4 I_i<=M*Z_i
        for i in plants:
            for k in items:
                DetModel.addConstr(I[k, i] <= 100000 * Z[i])

        #求解评估模型
        DetModel.optimize()
        return GetResults(self, DetModel, I, Z, Transshipment_X)
예제 #2
0
    def learn_rule(self, domain, data, pos_uncovered_indices, neg_indices):
        # Create a new model
        m = milp.Model("kDNF")

        print("Data")
        for row, l in data:
            print(*([
                "{}: {:.2f}".format(v, Learner._convert(row[v]))
                for v in domain.variables
            ] + [l]))
        print()

        # --- Computed constants
        n_r = len(domain.real_vars)
        n_b = len(domain.bool_vars)
        n_h = self.max_hyperplanes_per_rule
        n_e = len(data)
        k = self.max_terms_per_rule
        mu = 0.005

        x_er = [[Learner._convert(row[v]) for v in domain.real_vars]
                for row, _ in data]
        x_eb = [[Learner._convert(row[v]) for v in domain.bool_vars]
                for row, _ in data]

        # --- Variables

        # Inequality h is selected for the rule
        s_h = [
            m.addVar(vtype=milp.GRB.BINARY, name="s_h({h})".format(h=h))
            for h in range(n_h)
        ]

        # Example e covered by inequality h
        c_eh = [[
            m.addVar(vtype=milp.GRB.BINARY,
                     name="c_eh({e}, {h})".format(e=e, h=h))
            for h in range(n_h)
        ] for e in range(n_e)]

        # Example e covered by rule
        c_e = [
            m.addVar(vtype=milp.GRB.BINARY, name="c_e({e})".format(e=e))
            for e in range(n_e)
        ]

        # Boolean feature (or negation) selected
        s_b = [
            m.addVar(vtype=milp.GRB.BINARY, name="s_b({b})".format(b=b))
            for b in range(2 * n_b)
        ]

        # Coefficient of the r-th variable of inequality h
        a_hr = [[
            m.addVar(vtype=milp.GRB.CONTINUOUS,
                     lb=-1,
                     ub=1,
                     name="a_hr({h}, {r})".format(h=h, r=r))
            for r in range(n_r)
        ] for h in range(n_h)]

        # Offset of inequality h
        b_h = [
            m.addVar(vtype=milp.GRB.CONTINUOUS,
                     lb=-1,
                     ub=1,
                     name="b_h({h})".format(h=h)) for h in range(n_h)
        ]
        b_abs_h = [
            m.addVar(vtype=milp.GRB.CONTINUOUS,
                     lb=-1,
                     ub=1,
                     name="b_abs_h({h})".format(h=h)) for h in range(n_h)
        ]

        # Auxiliary variable (c_eh AND s_h)
        and_eh = [[
            m.addVar(vtype=milp.GRB.BINARY,
                     name="and_eh({e}, {h})".format(e=e, h=h))
            for h in range(n_h)
        ] for e in range(n_e)]

        # Auxiliary variable (x_eb AND s_b)
        and_eb = [[
            m.addVar(vtype=milp.GRB.BINARY,
                     name="and_eb({e}, {b})".format(e=e, b=b))
            for b in range(n_b)
        ] for e in range(n_e)]

        print()

        # Set objective
        m.setObjective(sum(c_e[e] for e in range(n_e) if data[e][1]),
                       milp.GRB.MAXIMIZE)

        # Add constraint: and_eh <= c_eh
        for e in range(n_e):
            if not data[e][1]:
                for h in range(n_h):
                    name = "and_eh({e}, {h}) <= c_eh({e}, {h})".format(e=e,
                                                                       h=h)
                    m.addConstr(and_eh[e][h] <= c_eh[e][h], name)
                    print(name)
        print()

        # Add constraint: and_eh <= s_h
        for e in range(n_e):
            if not data[e][1]:
                for h in range(n_h):
                    name = "and_eh({e}, {h}) <= s_h({h})".format(e=e, h=h)
                    m.addConstr(and_eh[e][h] <= s_h[h], name)
                    print(name)
        print()

        # Add constraint: and_eh >= c_eh + s_h - 1
        for e in range(n_e):
            if not data[e][1]:
                for h in range(n_h):
                    name = "and_eh({e}, {h}) >= c_eh({e}, {h}) + s_h({h}) - 1".format(
                        e=e, h=h)
                    m.addConstr(and_eh[e][h] >= c_eh[e][h] + s_h[h] - 1, name)
                    print(name)
        print()

        # Add constraint: and_eb <= x_eb
        for e in range(n_e):
            if not data[e][1]:
                for b in range(2 * n_b):
                    name = "and_eb({e}, {b}) <= x_eb({e}, {b})".format(e=e,
                                                                       b=b)
                    m.addConstr(
                        and_eb[e][b] <=
                        (x_eb[e][b] if b < n_b else 1 - x_eb[e][b]), name)
                    print(name)
        print()

        # Add constraint: and_eb <= s_h
        for e in range(n_e):
            if not data[e][1]:
                for b in range(2 * n_b):
                    name = "and_eb({e}, {b}) <= s_b({b})".format(e=e, b=b)
                    m.addConstr(and_eb[e][b] <= s_b[b], name)
                    print(name)
        print()

        # Add constraint: and_eb >= x_eb + s_b - 1
        for e in range(n_e):
            if not data[e][1]:
                for b in range(2 * n_b):
                    name = "and_eb({e}, {b}) >= x_eb({e}, {b}) + s_b({b}) - 1".format(
                        e=e, b=b)
                    m.addConstr(
                        and_eb[e][b] >=
                        (x_eb[e][b] if b < n_b else 1 - x_eb[e][b]) + s_b[b] -
                        1, name)
                    print(name)
        print()

        # Add constraint: SUM_(h = 1..n_h) and_eh - s_h + SUM_(b = 1..2 * n_b) and_eb - s_b <= -1
        for e in range(n_e):
            if not data[e][1]:
                name = "SUM_(h = 1..n_h) and_eh({e}, h) - s_h(h) + SUM_(b = 1..2*n_b) and_eb({e}, b) - s_b(b) <= -1"\
                    .format(e=e)
                m.addConstr(
                    sum(and_eh[e][h] - s_h[h]
                        for h in range(n_h)) + sum(and_eb[e][b] - s_b[b]
                                                   for b in range(2 * n_b)) <=
                    -1, name)
                print(name)

        # Add constraint: c_e <= c_eh + (1 - s_h)
        for e in range(n_e):
            if data[e][1]:
                for h in range(n_h):
                    name = "c_e({e}) <= c_eh({e}, {h}) + (1 - s_h({h}))".format(
                        e=e, h=h)
                    m.addConstr(c_e[e] <= c_eh[e][h] + (1 - s_h[h]), name)
                    print(name)

        # Add constraint: c_e <= x_eb + (1 - s_b)
        for e in range(n_e):
            if data[e][1]:
                for b in range(2 * n_b):
                    name = "c_e({e}) <= x_eb({e}, {b}) + (1 - s_b({b}))".format(
                        e=e, b=b)
                    m.addConstr(c_e[e] <= x_eb[e][b] + (1 - s_b[b]), name)
                    print(name)

        # Add constraint: SUM_(r = 1..n_r) a_hr * x_er <= b_h + 2 * (1 - c_eh)
        for e in range(n_e):
            for h in range(n_h):
                name = "SUM_(r = 1..n_r) a_hr({h}, r) * x_er({e}, r) <= b_h({h}) + 2 * (1 - c_eh({e}, {h}))"\
                    .format(e=e, h=h)
                m.addConstr(
                    sum(a_hr[h][r] * x_er[e][r]
                        for r in range(n_r)) <= b_h[h] + 2 * (1 - c_eh[e][h]),
                    name)
                print(name)

        # Add constraint: SUM_(r = 1..n_r) a_hr * x_er >= b_h - mu - 2 * c_eh
        for e in range(n_e):
            for h in range(n_h):
                name = "SUM_(r = 1..n_r) a_hr({h}, r) * x_er({e}, r) >= b_h({h}) - mu - 2 * c_eh({e}, {h})"\
                    .format(e=e, h=h)
                m.addConstr(
                    sum(a_hr[h][r] * x_er[e][r]
                        for r in range(n_r)) >= b_h[h] + mu - 2 * c_eh[e][h],
                    name)
                print(name)

        # Add constraint: SUM_(h = 1..n_h) s_h + SUM_(b = 1..n_b) s_b <= k
        name = "SUM_(h = 1..n_h) s_h(h) + SUM_(b = 1..n_b) s_b(b) <= k"
        m.addConstr(
            sum(s_h[h]
                for h in range(n_h)) + sum(s_b[b]
                                           for b in range(2 * n_b)) <= k, name)
        print(name)

        # Hack example
        # m.addConstr(a[0][0] == 1)
        # m.addConstr(a[0][1] == 0)
        # m.addConstr(b[0] == 0.5)
        #
        # m.addConstr(a[1][0] == 0)
        # m.addConstr(a[1][1] == 1)
        # m.addConstr(b[1] == 0.5)
        #
        # m.addConstr(a[2][0] == -1)
        # m.addConstr(a[2][1] == 0)
        # m.addConstr(b[2] == -0.5)
        #
        # m.addConstr(a[3][0] == 0)
        # m.addConstr(a[3][1] == -1)
        # m.addConstr(b[3] == -0.5)
        #
        # m.addConstr(s_h[0] == 1)
        # m.addConstr(s_h[1] == 1)
        # m.addConstr(s_h[2] == 1)
        # m.addConstr(s_h[3] == 1)

        # m.addConstr(z_h[0][0] == 1)
        # m.addConstr(z_h[1][0] == 1)
        # m.addConstr(z_h[2][0] == 0)
        # m.addConstr(z_h[3][0] == 0)
        # m.addConstr(z_h[0][1] == 0)
        # m.addConstr(z_h[1][1] == 0)
        # m.addConstr(z_h[2][1] == 1)
        # m.addConstr(z_h[3][1] == 1)

        # m.addConstr(z_ih[0][0] == 1)
        # m.addConstr(z_ih[1][0] == 0)
        # m.addConstr(z_ih[2][0] == 1)
        # m.addConstr(z_ih[3][0] == 0)
        # m.addConstr(z_ih[0][1] == 1)
        # m.addConstr(z_ih[1][1] == 0)
        # m.addConstr(z_ih[2][1] == 0)
        # m.addConstr(z_ih[3][1] == 1)
        # m.addConstr(z_ih[0][2] == 0)
        # m.addConstr(z_ih[1][2] == 1)
        # m.addConstr(z_ih[2][2] == 0)
        # m.addConstr(z_ih[3][2] == 1)
        # m.addConstr(z_ih[0][3] == 0)
        # m.addConstr(z_ih[1][3] == 1)
        # m.addConstr(z_ih[2][3] == 1)
        # m.addConstr(z_ih[3][3] == 0)

        # m.addConstr(z_d[0][0] == 1)
        # m.addConstr(z_d[1][0] == 0)
        # m.addConstr(z_d[2][0] == 0)
        # m.addConstr(z_d[3][0] == 0)
        # m.addConstr(z_d[0][1] == 0)
        # m.addConstr(z_d[1][1] == 0)
        # m.addConstr(z_d[2][1] == 1)
        # m.addConstr(z_d[3][1] == 0)

        # Wrong solution
        # m.addConstr(a[0][0] == 1)
        # m.addConstr(a[0][1] == 0)
        # m.addConstr(b[0] == 0.5)
        #
        # m.addConstr(a[1][0] == 0)
        # m.addConstr(a[1][1] == 1)
        # m.addConstr(b[1] == 0.5)
        #
        # m.addConstr(a[2][0] == -1)
        # m.addConstr(a[2][1] == 0)
        # m.addConstr(b[2] == -0.6)
        #
        # m.addConstr(a[3][0] == 0)
        # m.addConstr(a[3][1] == -1)
        # m.addConstr(b[3] == -0.6)
        #
        # m.addConstr(s_h[0] == 1)
        # m.addConstr(s_h[1] == 1)
        # m.addConstr(s_h[2] == 1)
        # m.addConstr(s_h[3] == 1)

        # m.addConstr(s_h[0] == 1)
        # m.addConstr(s_h[1] == 1)
        # m.addConstr(s_h[2] == 0)
        # m.addConstr(s_h[3] == 0)
        #
        # m.addConstr(a_hr[0][0] == -1)
        # m.addConstr(a_hr[0][1] == -0.5)
        # m.addConstr(b_h[0] == -0.2)
        #
        # m.addConstr(a_hr[1][0] == 1)
        # m.addConstr(a_hr[1][1] == 0)
        # m.addConstr(b_h[1] == 0.75)

        m.optimize()

        for v in m.getVars():
            print(v.varName, v.x)

        print('Obj:', m.objVal)

        print()

        # Lets extract the rule formulation
        rule = []
        from pysmt.shortcuts import Real, LE, Plus, Times, Not

        for h in range(n_h):
            if int(s_h[h].x) == 1:
                coefficients = [Real(float(a_hr[h][r].x)) for r in range(n_r)]
                constant = Real(float(b_h[h].x))
                linear_sum = Plus([
                    Times(c, domain.get_symbol(v))
                    for c, v in zip(coefficients, domain.real_vars)
                ])
                rule.append(LE(linear_sum, constant))

        for b in range(2 * n_b):
            if int(s_b[b].x) == 1:
                var = domain.get_symbol(domain.bool_vars[b if b < n_b else b -
                                                         n_b])
                rule.append(var if b < n_b else Not(var))

        print("Features", x_er[4][0], x_er[4][1])
        print(sum(a_hr[1][r].x * x_er[4][r] for r in range(n_r)), "<=",
              b_h[1].x + 2 * (1 - c_eh[4][1].x))
        print(sum(a_hr[1][r].x * x_er[4][r] for r in range(n_r)), ">=",
              b_h[1].x + mu - 2 * c_eh[4][1].x)

        return rule
예제 #3
0
    def SolveStoModel(self, STOMODELCONFIGURE):
        def GetResults(self, I, Z, Transshipment_X, N):
            plants = range(self.supplier)
            items = range(self.lower_demand.shape[0])

            objVal_holding = sum([
                I[k, i].x * self.holding_cost[k, i] for k in items
                for i in plants
            ])
            objVal_fixed = sum([Z[i].x * self.fixed_cost[i] for i in plants])

            resultsdict = {}
            plants = range(self.supplier)
            resultsdict['# of Open DC'] = sum([Z[i].x for i in plants])
            resultsdict['Open DC'] = [Z[i].x for i in plants]
            resultsdict['Total Inventory'] = [
                sum([I[k, i].x for i in plants]) for k in items
            ]
            resultsdict['Inventory'] = [[I[k, i].x for i in plants]
                                        for k in items]
            resultsdict['Fixed Cost'] = objVal_fixed
            resultsdict['Holding Cost'] = [
                sum([I[k, i].x * self.holding_cost[k, i] for i in plants])
                for k in items
            ]
            return resultsdict

        N = STOMODELCONFIGURE['#']
        demandScenario = STOMODELCONFIGURE['demandScenario']

        StoModel = grb.Model('StoModel')
        StoModel.setParam('OutputFlag', 0)
        StoModel.modelSense = grb.GRB.MINIMIZE

        items = range(demandScenario.shape[0])
        plants = range(self.supplier)
        demand = range(self.retailer)

        I = StoModel.addVars(items, plants, vtype=grb.GRB.CONTINUOUS, name='I')
        Z = StoModel.addVars(plants, vtype=grb.GRB.BINARY, name='Z')
        Transshipment_X = StoModel.addVars(items,
                                           range(N),
                                           plants,
                                           demand,
                                           vtype=grb.GRB.CONTINUOUS,
                                           name='Transshipment_X')

        objFunc_holding = grb.quicksum(
            [I[k, i] * self.holding_cost[k, i] for k in items for i in plants])
        objFunc_fixed = grb.quicksum(
            [Z[i] * self.fixed_cost[i] for i in plants])
        objFunc_penalty = grb.quicksum([
            grb.quicksum([
                self.penalty_cost[k, j] *
                (demandScenario[k, scenario, j] - grb.quicksum(
                    [Transshipment_X[k, scenario, i, j] for i in plants]))
                for k in items for j in demand
            ]) for scenario in range(N)
        ])
        objFunc_trans = grb.quicksum([
            Transshipment_X[k, scenario, i, j] *
            self.transportation_cost[k, i, j] for scenario in range(N)
            for k in items for i in plants for j in demand
        ])  #N个Scenario的transportation cost总和
        objFunc = objFunc_holding + objFunc_fixed + (objFunc_penalty +
                                                     objFunc_trans) / N

        StoModel.setObjective(objFunc)
        '''
        TODO
        '''
        #约束1
        for i in plants:
            for k in items:
                StoModel.addConstrs((grb.quicksum(
                    [Transshipment_X[k, scenario, i, j]
                     for j in demand]) <= I[k, i] for scenario in range(N)))

        #约束2
        for j in demand:
            for k in items:
                StoModel.addConstrs((grb.quicksum(
                    [Transshipment_X[k, scenario, i, j]
                     for i in plants]) <= demandScenario[k, scenario, j]
                                     for scenario in range(N)))

        #约束3
        for i in plants:
            for j in demand:
                for k in items:
                    if round(self.graph[i, j]) == 0:
                        StoModel.addConstrs(
                            (Transshipment_X[k, scenario, i, j] <= 0
                             for scenario in range(N)))

        #约束4 I_i<=M*Z_i
        for i in plants:
            for k in items:
                StoModel.addConstr(I[k, i] <= 100000 * Z[i])

        #求解评估模型
        StoModel.optimize()
        return GetResults(self, I, Z, Transshipment_X, N)
    b = np.asarray([[
        0, 0, -SCENARIOS[n][0], SCENARIOS[n][0] * 0.8, -SCENARIOS[n][1],
        SCENARIOS[n][1] * 0.8
    ] for n in range(k)])
    '''
    Step 1:
        1.0. establish the master problem
        1.1. add initial constraints
        1.2. solve master problem
        1.3. get solutions(x,\ita) for the subproblem
    '''
    # --- 1.0. establish master Model with scenarios

    #Build Model
    masterProblem = grb.Model('MasterProblem')
    masterProblem.modelSense = grb.GRB.MINIMIZE
    masterProblem.setParam('OutputFlag', 0)

    #Create Variables
    #First-stage Variables
    X = masterProblem.addVars([1, 2],
                              vtype=grb.GRB.CONTINUOUS,
                              lb=[0, 0],
                              obj=[3, 2],
                              name='X')

    #Second-stage recourse value variables
    ITA = masterProblem.addVars(
        range(1, k + 1),
        vtype=grb.GRB.CONTINUOUS,
예제 #5
0
    def Calculate_Upper_bound(self,customer_sequence):
        #TODO check compatibility and correctness
        #Input: List customer_sequence: 每个元素是客户类对象
        #Output: 
        #通过解Paat Lemma1 中的LP得到Upper Bound
        from gurobipy import gurobipy as grb
        customer_sequence = [customer.type for customer in customer_sequence]
        
        #--- 申明问题
        primal_problem = grb.Model() 
        primal_problem.setParam('OutputFlag',0) 
        primal_problem.modelSense = grb.GRB.MAXIMIZE
        
        #--- 申明变量
        num_col = len(customer_sequence)
        num_row = int(len(self.possible_offer_set)/len(self.customer))
        
        Y = primal_problem.addVars(range(num_row),range(1,num_col+1), #行:set集合,index从0开始;  列:时间T,index从1开始
                                   vtype=grb.GRB.CONTINUOUS, lb=0,ub=1, 
                                   name='y')
        
        #--- 设置objective function
        obj = 0
        for t,customer_type in enumerate(customer_sequence):
            t = t+1  #时间变到正常的从1 开始 到 T
            for s,offer_set in enumerate(self.possible_offer_set[:num_row]):
                
                key = json.dumps({
                                'customer_type':customer_type,
                                'offered_set':offer_set
                                })
                item_prob = self.PROBABILITY[key]
                
                for item_id in offer_set: # 不在offer_set里面无收益
                    obj += item_prob[item_id]*self.item[item_id]['price']*Y[s,t]
        
        primal_problem.setObjective(obj)      
                    
                    
        #--- 加入constraints
        
        #capacity 限制
        for item_id in list(self.item.keys())[1:]:
            
            possible_buy_number = 0
            for t,customer_type in enumerate(customer_sequence):
                t = t+1 #时间变到正常的从1 开始 到 T
                
                for s,offer_set in enumerate(self.possible_offer_set[:num_row]):
                    
                    if item_id in offer_set:
                        key = json.dumps({
                                    'customer_type':customer_type,
                                    'offered_set':offer_set
                                    })
                        item_prob = self.PROBABILITY[key]
                        
                        possible_buy_number += item_prob[item_id]*Y[s,t]
            primal_problem.addConstr(possible_buy_number<=self.item[item_id]['initial_inventory']+self.item[item_id]['extra_inventory'])
            
        #possibility 约束
        for t in range(1,len(customer_sequence)+1): #1-->T
            possibility = grb.quicksum([Y[s,t] for s in range(len(self.possible_offer_set[:num_row]))])
            primal_problem.addConstr(possibility==1)
        
        primal_problem.write('11.lp')
        primal_problem.optimize()

        if primal_problem.status == grb.GRB.Status.OPTIMAL:
            print('successfully get hindsight upper bound')
            return primal_problem.ObjVal
        
        elif primal_problem.status == grb.GRB.Status.INFEASIBLE:
            print('upper bound model is infeasible.')
        
        else:
            print('something wrong with solving upper bound problem.')
예제 #6
0
def simulationWithCost_Multi(a,
                             demand,
                             Z,
                             I,
                             num_plants,
                             num_demand,
                             tranposrtation_cost,
                             penalty_cost,
                             cishu=500):
    print('--------Mixed_distribution_simulation----------')
    #lower_demand = demand[0]
    #mean_demand = demand[1]
    #upper_demand = demand[2]

    realized_demand = np.zeros(shape=(cishu, num_demand))
    realized_demand = demand

    items = range(realized_demand.shape[0])
    plants = range(num_plants)
    demand = range(num_demand)

    results = []
    trans_cost_array = np.zeros(shape=(cishu, realized_demand.shape[0]))
    penal_cost_array = np.zeros(shape=(cishu, realized_demand.shape[0]))

    for n in range(cishu):
        oneDemandScenario = realized_demand[:, n, :]

        #申明Fillrate中Z(w)值的那个模型
        evaluation_problem = grb.Model('evaluation_problem')
        evaluation_problem.setParam('OutputFlag', 0)
        evaluation_problem.modelSense = grb.GRB.MINIMIZE

        evaluation_X = evaluation_problem.addVars(items,
                                                  plants,
                                                  demand,
                                                  vtype=grb.GRB.CONTINUOUS,
                                                  name='evaluation_X')

        objFunc_penal = grb.quicksum([
            penalty_cost[k, j] *
            (oneDemandScenario[k, j] -
             grb.quicksum([evaluation_X[k, i, j] for i in plants]))
            for k in items for j in demand
        ])
        objFunc_trans = grb.quicksum(
            evaluation_X[k, i, j] * tranposrtation_cost[k, i, j] for k in items
            for i in plants for j in demand)
        evaluation_problem.setObjective(objFunc_penal + objFunc_trans)

        #添加评估模型的约束
        #约束1
        for k in items:
            for i in plants:
                evaluation_problem.addConstr(
                    grb.quicksum([evaluation_X[k, i, j]
                                  for j in demand]) <= I[k, i])

        #约束2
        for k in items:
            for j in demand:
                evaluation_problem.addConstr(
                    grb.quicksum([evaluation_X[k, i, j]
                                  for i in plants]) <= oneDemandScenario[k, j])

        #约束3 其实是paper中的4,gurobi自带正数约束
        for i in plants:
            for j in demand:
                if round(a[i, j] * Z[i]) == 0:
                    for k in items:
                        evaluation_problem.addConstr(
                            evaluation_X[k, i, j] <= 0)

        #求解评估模型,并求出fillrate 还要输出
        evaluation_problem.optimize()

        #transportation
        trans = np.zeros(shape=(realized_demand.shape[0], num_plants,
                                num_demand))
        for k in items:
            for i in plants:
                for j in demand:
                    trans[k, i, j] = evaluation_X[k, i, j].x

        type1ServiceLevel = (np.abs(trans.sum(axis=1) - oneDemandScenario) <=
                             0.0005).sum() / (num_demand *
                                              realized_demand.shape[0])
        type2ServiceLevel = trans.sum() / oneDemandScenario.sum()
        trans_cost = (trans * tranposrtation_cost).sum(axis=1).sum(axis=1)
        penal_cost = ((oneDemandScenario - trans.sum(axis=1)) *
                      penalty_cost).sum(axis=1)
        results.append([
            type1ServiceLevel, type2ServiceLevel,
            trans_cost.sum(),
            penal_cost.sum()
        ])
        trans_cost_array[n, :] = trans_cost
        penal_cost_array[n, :] = penal_cost

    type1ServiceLevel_mean, type2ServiceLevel_mean, trans_cost_mean, penal_cost_mean = np.mean(
        np.asarray(results), axis=0)
    trans_cost_mean = [cost for cost in np.mean(trans_cost_array, axis=0)]
    penal_cost_mean = [cost for cost in np.mean(penal_cost_array, axis=0)]
    type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_best, penal_cost_best = np.amin(
        np.asarray(results), axis=0)
    return type1ServiceLevel_mean, type2ServiceLevel_mean, type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_mean, penal_cost_mean
예제 #7
0
def triangular_simulation(a,
                          demand,
                          Z,
                          I,
                          mode,
                          num_plants,
                          num_demand,
                          cishu=500):
    print('--------triangular_simulation----------')
    lower_demand = demand[0]
    mean_demand = demand[1]
    upper_demand = demand[2]

    total_CC = 0
    total_fillrate = 0
    total_arcs = 0
    plants = range(num_plants)
    demand = range(num_demand)

    for n in range(cishu):

        realized_demand = [0] * len(lower_demand)
        for k in range(len(realized_demand)):
            realized_demand[k] = round(
                random.triangular(lower_demand[k], upper_demand[k],
                                  mean_demand[k] * mode))

        #申明Fillrate中Z(w)值的那个模型
        evaluation_problem = grb.Model('evaluation_problem')
        evaluation_problem.setParam('OutputFlag', 0)
        evaluation_problem.modelSense = grb.GRB.MAXIMIZE

        #申明评估模型的变量
        evaluation_X = evaluation_problem.addVars(plants,
                                                  demand,
                                                  obj=[[1 for j in demand]
                                                       for i in plants],
                                                  vtype=grb.GRB.INTEGER,
                                                  name='evaluation_X')

        #添加评估模型的约束
        #约束1
        for i in plants:
            expr = 0
            for j in demand:
                expr = expr + evaluation_X[i, j]
            evaluation_problem.addConstr(expr <= I[i])
            del expr

        #约束2
        for j in demand:
            expr = 0
            for i in plants:
                expr = expr + evaluation_X[i, j]
            evaluation_problem.addConstr(expr <= realized_demand[j])
            del expr

        #约束3 其实是paper中的4,gurobi自带正数约束
        for i in plants:
            for j in demand:
                if round(a[i, j] * Z[i]) == 0:
                    evaluation_problem.addConstr(evaluation_X[i, j] <= 0)

        #求解评估模型,并求出fillrate 还要输出
        evaluation_problem.optimize()

        #########################运输完成了
        #########################计算用上的道路arcs
        arcs = 0
        for i in plants:
            for j in demand:
                arcs = (round(evaluation_X[i, j].x) > 0.1) + arcs

        ########################CC的值##########################
        ##################来看是否满足cutting plane的LP
        #申明CC问题
        CC_problem = grb.Model('CC_problem')
        CC_problem.setParam('OutputFlag', 0)

        #申明CC问题的变量
        CC_x = CC_problem.addVars(demand, vtype=grb.GRB.BINARY, name='CC_x')
        CC_y = CC_problem.addVars(plants, vtype=grb.GRB.BINARY, name='CC_y')

        #设置目标函数
        expr1 = 0
        expr2 = 0
        for i in plants:
            expr1 = expr1 + CC_y[i] * I[i]
        for j in demand:
            expr2 = expr2 + realized_demand[j] * CC_x[j]
        CC_problem.setObjective(expr1 - expr2, grb.GRB.MINIMIZE)
        del expr1
        del expr2
        #载入CC问题的约束

        #约束1
        for i in plants:
            for j in demand:
                if round(a[i, j] * round(Z[i])) == 1:
                    CC_problem.addConstr(CC_y[i] >= CC_x[j])

        #解CC问题
        CC_problem.optimize()

        total_CC += (CC_problem.ObjVal >= 0)
        total_fillrate += evaluation_problem.ObjVal / sum(realized_demand)
        total_arcs += arcs
        if n % 100 == 0:
            print(n)

    eva_X = np.zeros(shape=(num_plants, num_demand))
    for i in plants:
        for i in demand:
            eva_X[i, j] = round(evaluation_X[i, j].x)
    return eva_X, total_arcs / cishu, total_CC / cishu, total_fillrate / cishu
예제 #8
0
def uniform_simulation(a, demand, Z, I, num_plants, num_demand, cishu=500):
    print('--------uniform_simulation----------')
    lower_demand = demand[0]
    upper_demand = demand[2]

    plants = range(num_plants)
    demand = range(num_demand)

    results = []

    for n in range(cishu):
        realized_demand = [0] * len(lower_demand)
        for k in range(len(realized_demand)):
            realized_demand[k] = round(
                random.randint(lower_demand[k], upper_demand[k]))

        #申明Fillrate中Z(w)值的那个模型
        evaluation_problem = grb.Model('evaluation_problem')
        evaluation_problem.setParam('OutputFlag', 0)
        evaluation_problem.modelSense = grb.GRB.MAXIMIZE

        evaluation_X = evaluation_problem.addVars(plants,
                                                  demand,
                                                  obj=[[1 for j in demand]
                                                       for i in plants],
                                                  vtype=grb.GRB.INTEGER,
                                                  name='evaluation_X')

        #添加评估模型的约束
        #约束1
        for i in plants:
            expr = 0
            for j in demand:
                expr = expr + evaluation_X[i, j]
            evaluation_problem.addConstr(expr <= I[i])
            del expr

        #约束2
        for j in demand:
            expr = 0
            for i in plants:
                expr = expr + evaluation_X[i, j]
            evaluation_problem.addConstr(expr <= realized_demand[j])
            del expr

        #约束3 其实是paper中的4,gurobi自带正数约束
        for i in plants:
            for j in demand:
                if round(a[i, j] * Z[i]) == 0:
                    evaluation_problem.addConstr(evaluation_X[i, j] <= 0)

        #求解评估模型,并求出fillrate 还要输出
        evaluation_problem.optimize()

        type1ServiceLevel = sum([
            np.abs(
                sum([evaluation_X[i, j].x
                     for i in plants]) - realized_demand[j]) <= 0.005
            for j in demand
        ]) / num_demand
        type2ServiceLevel = sum(
            [sum([evaluation_X[i, j].x for i in plants])
             for j in demand]) / sum(realized_demand)

        results.append([type1ServiceLevel, type2ServiceLevel])
    return np.mean(np.asarray(results), axis=0)
예제 #9
0
def simulationWithCost(a,
                       demand,
                       Z,
                       I,
                       num_plants,
                       num_demand,
                       tranposrtation_cost,
                       penalty_cost,
                       cishu=500):
    print('--------Mixed_distribution_simulation----------')
    #lower_demand = demand[0]
    #mean_demand = demand[1]
    #upper_demand = demand[2]

    realized_demand = np.zeros(shape=(cishu, num_demand))
    realized_demand = demand

    plants = range(num_plants)
    demand = range(num_demand)

    results = []

    for n in range(cishu):
        oneDemandScenario = realized_demand[n]

        #申明Fillrate中Z(w)值的那个模型
        evaluation_problem = grb.Model('evaluation_problem')
        evaluation_problem.setParam('OutputFlag', 0)
        evaluation_problem.modelSense = grb.GRB.MINIMIZE

        evaluation_X = evaluation_problem.addVars(plants,
                                                  demand,
                                                  vtype=grb.GRB.CONTINUOUS,
                                                  name='evaluation_X')

        objFunc_penal = grb.quicksum([
            penalty_cost[j] *
            (oneDemandScenario[j] -
             grb.quicksum([evaluation_X[i, j] for i in plants]))
            for j in demand
        ])
        objFunc_trans = grb.quicksum(evaluation_X[i, j] *
                                     tranposrtation_cost[i, j] for i in plants
                                     for j in demand)
        evaluation_problem.setObjective(objFunc_penal + objFunc_trans)

        #添加评估模型的约束
        #约束1
        for i in plants:
            expr = 0
            for j in demand:
                expr = expr + evaluation_X[i, j]
            evaluation_problem.addConstr(expr <= I[i])
            del expr

        #约束2
        for j in demand:
            expr = 0
            for i in plants:
                expr = expr + evaluation_X[i, j]
            evaluation_problem.addConstr(expr <= oneDemandScenario[j])
            del expr

        #约束3 其实是paper中的4,gurobi自带正数约束
        for i in plants:
            for j in demand:
                if round(a[i, j] * Z[i]) == 0:
                    evaluation_problem.addConstr(evaluation_X[i, j] <= 0)

        #求解评估模型,并求出fillrate 还要输出
        evaluation_problem.optimize()

        #transportation
        trans = np.zeros(shape=(num_plants, num_demand))
        for i in plants:
            for j in demand:
                trans[i, j] = evaluation_X[i, j].x

        type1ServiceLevel = sum(
            np.abs(trans.sum(axis=0) -
                   oneDemandScenario) <= 0.0005) / num_demand
        type2ServiceLevel = trans.sum() / sum(oneDemandScenario)
        trans_cost = (trans * tranposrtation_cost).sum()
        penal_cost = sum(
            (oneDemandScenario - trans.sum(axis=0)) * penalty_cost)
        results.append(
            [type1ServiceLevel, type2ServiceLevel, trans_cost, penal_cost])

    type1ServiceLevel_mean, type2ServiceLevel_mean, trans_cost_mean, penal_cost_mean = np.mean(
        np.asarray(results), axis=0)
    type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_best, penal_cost_best = np.amin(
        np.asarray(results), axis=0)
    return type1ServiceLevel_mean, type2ServiceLevel_mean, type1ServiceLevel_worst, type2ServiceLevel_worst, trans_cost_mean, penal_cost_mean
num_demand = []

# length that every buyer need
L = []

for amount, l in zip(demand['Amount'].values, demand['Length'].values):
    num_demand.append(int(amount))
    L.append(l)
#
buyer = range(len(num_demand))
max_material = range(sum(num_demand))

#General model

#estabilish model
m = grb.Model('model1')
m.modelSense = grb.GRB.MINIMIZE
m.setParam('OutputFlag', 0)

# addvars
X = m.addVars(max_material, buyer, vtype=grb.GRB.INTEGER, ub=1, lb=0, obj=0)
Y = m.addVars(max_material, vtype=grb.GRB.INTEGER, ub=1, lb=0, obj=1)

#add constraints

#1rt : aggregated cutted length should less than total length
for i in max_material:
    expr = 0
    for j in buyer:
        expr = X[i, j] * L[j] + expr
    m.addConstr(expr <= Y[i] * length)
예제 #11
0
def hoeffding_design(cost,
                     demand,
                     a,
                     num_plants,
                     num_demand,
                     service_level=0.1):

    fixed_cost = cost[0]
    holding_cost = cost[1]

    lower_demand = demand[0]
    mean_demand = demand[1]
    upper_demand = demand[2]

    plants = range(num_plants)
    demand = range(num_demand)
    inventory = range(num_plants)

    #记录每次加入的约束是Case1 or Case2 or Others0
    constraintType = []

    #记录每次迭代时候的objvalue
    iterValue = []
    SNum = []

    #------------申明主问题-----------#
    #申明主模型
    master_problem = grb.Model('master_problem')
    master_problem.setParam('OutputFlag', 0)
    master_problem.modelSense = grb.GRB.MINIMIZE

    #申明决策变量 obj=***就表明了该组变量在目标函数中的系数
    ####这一块参考gurobi给的例子:facility.py
    I = master_problem.addVars(inventory,
                               vtype=grb.GRB.INTEGER,
                               obj=holding_cost,
                               name='I')

    Z = master_problem.addVars(plants,
                               vtype=grb.GRB.BINARY,
                               obj=fixed_cost,
                               name='Z')

    #----------载入各种约束-----------#

    #利用hoeffding inequality计算总库存水平
    temp_sum = sum((upper_demand - lower_demand)**2)
    TI = math.ceil(mean_demand.sum() +
                   math.sqrt(-math.log(service_level) * temp_sum / 2))
    del temp_sum

    #载入chance constraints
    #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧)
    for j in demand:
        expr = sum(a[:, j] * I.values())
        master_problem.addQConstr(
            expr >= min(upper_demand[j], TI -
                        (lower_demand.sum() - lower_demand[j])))
        del expr
        #记录加入的约束的类型
        SNum.append(1)
        if upper_demand[j] < TI - (lower_demand.sum() - lower_demand[j]):
            constraintType.append(1)
        if upper_demand[j] > TI - (lower_demand.sum() - lower_demand[j]):
            constraintType.append(2)
        if upper_demand[j] == TI - (lower_demand.sum() - lower_demand[j]):
            constraintType.append(3)

    #载入约束3-----Ii<=M*Zi
    M = upper_demand.sum()
    master_problem.addConstrs(I[i] <= M * Z[i] for i in plants)
    for i in plants:  #记录加入的约束的类型
        constraintType.append(0)
        SNum.append(0)

    #total inventory的约束
    master_problem.addConstr(sum(I.values()) == TI)
    constraintType.append(0)  #记录加入的约束的类型
    SNum.append(0)

    #------------------开始迭代主问题------------------------------------#
    #-------------------------------------------------------------------#
    add_constraints_time = 0

    time_start = time.clock()

    while True:
        #解主问题
        master_problem.optimize()
        #确定主问题解的状态
        if master_problem.status == 3:
            break

        elif master_problem.status == 2:
            print('Master_Val:', master_problem.ObjVal)
            iterValue.append(master_problem.ObjVal)
            #-------------开始子问题---------------#
            #申明子问题
            sub_problem = grb.Model('sub_problem')
            sub_problem.setParam('OutputFlag', 0)

            #申明子问题的变量
            x = sub_problem.addVars(demand, vtype=grb.GRB.BINARY, name='x')
            y = sub_problem.addVars(plants, vtype=grb.GRB.BINARY, name='y')
            z = sub_problem.addVar(vtype=grb.GRB.CONTINUOUS, name='z')

            #设置目标函数
            expr1 = grb.quicksum([y[i] * I[i].x for i in plants])
            expr2 = grb.quicksum([upper_demand[j] * x[j] for j in demand])
            sub_problem.setObjective(expr1 - expr2 + z, grb.GRB.MINIMIZE)
            del expr1
            del expr2
            #载入子问题的约束
            #z>0约束
            sub_problem.addConstr(z >= 0)

            #子问题约束1
            expr1 = sum(upper_demand * x.values())
            expr2 = grb.quicksum(
                [lower_demand[j] * (1 - x[j]) for j in demand])
            sub_problem.addConstr(z >= expr1 - TI + expr2)
            del expr1
            del expr2

            #子问题约束2
            for i in plants:
                for j in demand:
                    if round(a[i, j]) == 1:
                        sub_problem.addConstr(y[i] >= x[j])

        #解子问题
            sub_problem.optimize()

            #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中
            if sub_problem.ObjVal >= -0.001:
                break
            else:
                print(sub_problem.ObjVal)
                expr1 = grb.quicksum([I[i] * y[i].x for i in plants])
                expr2 = sum([upper_demand[j] * x[j].x for j in demand])
                expr3 = sum([lower_demand[j] * (1 - x[j].x) for j in demand])
                temp_expr = (expr1 >= min(expr2, TI - expr3))
                master_problem.addConstr(temp_expr)  #加新的约束到主问题中

                #记录加入的约束的类型
                if expr2 < TI - expr3:
                    constraintType.append(1)
                if expr2 > TI - expr3:
                    constraintType.append(2)
                if expr2 == TI - expr3:
                    constraintType.append(3)
                SNum.append(sum([x[j].x for j in demand]))

                del expr1
                del expr2
                del expr3
                del temp_expr
                add_constraints_time += 1

    time_end = time.clock()

    ################################到这里图就设计好了###################################
    ################################到这里图就设计好了###################################
    #输出一些图的参数(仓库数,道路数,总库存=TI)

    if master_problem.status == 2:

        I_return = []
        Z_return = []
        open_DC = 0
        for i in plants:
            I_return.append(I[i].x)
            Z_return.append(Z[i].x)
            open_DC = Z[i].x + open_DC
        p = TI

        return master_problem, constraintType, iterValue, SNum, [
            'hoeffding', open_DC, I_return, Z_return, p, p / TI,
            master_problem.ObjVal, time_end - time_start, add_constraints_time,
            'optimal'
        ]

    elif master_problem.status == 3:
        return master_problem, constraintType, iterValue, SNum, [
            '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible'
        ]
예제 #12
0
def small_big_design_multiitem(cost,
                               demand,
                               a,
                               num_plants,
                               num_demand,
                               s,
                               S,
                               weight,
                               service_level=0.1,
                               mode='set'):

    add_constraints_time = 0

    fixed_cost = cost[0]
    holding_cost = cost[1]

    lower_demand = demand[0]
    mean_demand = demand[1]
    upper_demand = demand[2]

    items = range(lower_demand.shape[0])
    plants = range(num_plants)
    demand = range(num_demand)

    constraintType = []
    iterValue = []
    iterValue_small = []
    iterValue_big = []

    # ---- 申明主问题
    #申明主模型
    master_problem = grb.Model('master_problem')
    master_problem.setParam('OutputFlag', 0)
    master_problem.modelSense = grb.GRB.MINIMIZE

    #申明决策变量 obj=***就表明了该组变量在目标函数中的系数
    ####这一块参考gurobi给的例子:facility.py
    I = master_problem.addVars(items,
                               plants,
                               vtype=grb.GRB.CONTINUOUS,
                               obj=holding_cost,
                               name='I')

    Z = master_problem.addVars(plants,
                               vtype=grb.GRB.BINARY,
                               obj=fixed_cost,
                               name='Z')

    # ---- 载入各种约束

    #额外算的值
    TI = np.zeros(shape=lower_demand.shape[0])
    for k in items:
        temp_sum = sum((upper_demand[k] - lower_demand[k])**2)
        TI[k] = math.ceil(mean_demand[k].sum() +
                          math.sqrt(-math.log(service_level) * temp_sum / 2))
    del temp_sum

    #载入chance constraints
    #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧)
    #这里是small set的约束
    for k in items:
        for j in demand:
            expr = sum(a[:, j] * I.values()[13 * k:13 * (k + 1)])
            master_problem.addConstr(expr >= upper_demand[k, j])
            del expr
            constraintType.append('small')

    #这里是big set的约束
    #要求|S|>25 (某数),最直观的的是取30时候,此时不属于这个集合的点是空集
    #所以没有约束。
    #第二个的约束去子问题中迭代加入
    expr = 0
    del expr

    #载入约束3-----Ii<=M*Zi
    M = upper_demand.sum()
    master_problem.addConstrs(I[k, i] <= M * Z[i] for k in items
                              for i in plants)
    for i in plants:
        constraintType.append('others')

    # ---- 开始迭代主问题
    time_start = time.clock()

    while True:
        #解主问题
        master_problem.optimize()

        #确定主问题解的状态
        if master_problem.status == 3:
            iterValue.append(master_problem.ObjVal)
            break

        elif master_problem.status == 2:
            print('master_Value:', master_problem.ObjVal)
            iterValue.append(master_problem.ObjVal)

            # ---- 开始子问题
            IterSubObjVal = np.zeros(shape=(lower_demand.shape[0], 2))
            IterX = np.zeros(shape=(lower_demand.shape[0],
                                    lower_demand.shape[1], 2))
            IterY = np.zeros(shape=(lower_demand.shape[0],
                                    lower_demand.shape[1], 2))

            # K-th item:
            for k in items:

                #申明small set的子问题----sub_problem1
                sub_problem1 = grb.Model('sub_problem1')
                sub_problem1.setParam('OutputFlag', 0)

                #申明子问题的变量
                x1 = sub_problem1.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x1')
                y1 = sub_problem1.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y1')

                #设置目标函数
                expr1 = grb.quicksum([y1[i] * I[k, i].x for i in plants])
                expr2 = sum(upper_demand[k] * x1.values())
                #for j in demand:
                #    expr2 = expr2 + upper_demand[j] * x1[j]
                sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                expr = sum(x1.values())
                sub_problem1.addConstr(expr <= s)
                del expr

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem1.addConstr(y1[i] >= x1[j])

            #解子问题
                sub_problem1.optimize()

                #申明big set的子问题----sub_problem2  -----------
                #big set
                #big set
                #big set
                sub_problem2 = grb.Model('sub_problem1')
                sub_problem2.setParam('OutputFlag', 0)

                #申明子问题的变量
                x2 = sub_problem2.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x2')
                y2 = sub_problem2.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y2')

                #设置目标函数
                expr1 = grb.quicksum([(1 - y2[i]) * I[k, i].x for i in plants])
                expr2 = grb.quicksum(
                    [lower_demand[k, j] * (1 - x2[j]) for j in demand])
                sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                expr = grb.quicksum(x2.values())
                sub_problem2.addConstr(expr >= S)
                del expr

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem2.addConstr(y2[i] >= x2[j])

            #解子问题
                sub_problem2.optimize()

                IterSubObjVal[k, 0] = sub_problem1.ObjVal
                IterSubObjVal[k, 1] = sub_problem2.ObjVal
                for j in demand:
                    IterX[k, j, 0] = x1[j].x
                    IterX[k, j, 1] = x2[j].x
                for i in plants:
                    IterY[k, i, 0] = y1[i].x
                    IterY[k, i, 1] = y2[i].x

            #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中
            if all(IterSubObjVal.reshape(6) >= -0.01):
                iterValue_small.append(IterSubObjVal[k, 0] for k in items)
                iterValue_big.append(IterSubObjVal[k, 1] for k in items)
                break

            else:
                for k in items:

                    if IterSubObjVal[k, 0] < -0.001:
                        print('small_set:', IterSubObjVal[k, 0])
                        iterValue_small.append(IterSubObjVal[k, 0])
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = IterX[k, j, 0] * a[:, j] + a_temp
                            expr2 = upper_demand[k, j] * IterX[k, j, 0] + expr2
                        for i in plants:
                            if round(a_temp[i]) != 0:
                                expr1 = expr1 + round(a_temp[i]) / round(
                                    a_temp[i]) * I[k, i]
                        temp_expr = expr1 >= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        constraintType.append('small')
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1
                    else:
                        iterValue_small.append(np.nan)

                    if IterSubObjVal[k, 1] < -0.001:
                        print('big_set:', IterSubObjVal[k, 1])
                        iterValue_big.append(IterSubObjVal[k, 1])
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = IterX[k, j, 1] * a[:, j] + a_temp
                            expr2 = lower_demand[k, j] * (
                                int(not IterX[k, j, 1])) + expr2
                        for i in plants:
                            expr1 = expr1 + int(not a_temp[i]) * I[k, i]
                        temp_expr = expr1 <= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        constraintType.append('big')
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1
                    else:
                        iterValue_big.append(np.nan)

    time_end = time.clock()

    if master_problem.status == 2:

        open_DC = sum([Z[i].x for i in plants])
        I_return = [[I[k, i].x for i in plants] for k in items]
        Z_return = [Z[i].x for i in plants]
        p = [sum(I[k, i].x for i in plants) for k in items]

        return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [
            s, open_DC, I_return, Z_return, p, p / TI, master_problem.ObjVal,
            time_end - time_start, add_constraints_time, 'optimal'
        ]

    elif master_problem.status == 3:
        return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [
            '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible'
        ]
예제 #13
0
def small_big_fulldesign(cost,
                         demand,
                         a,
                         num_plants,
                         num_demand,
                         s,
                         S,
                         weight,
                         service_level=0.1):
    '''
    把exponential多的约束全部加入到模型中,解一个大模型
    '''
    fixed_cost = np.asarray(cost[0])
    holding_cost = np.asarray(cost[1])

    lower_demand = demand[0]
    mean_demand = demand[1]
    upper_demand = demand[2]

    inventory = range(num_plants)
    plants = range(num_plants)
    demand = range(num_demand)

    #------------申明主问题-----------#
    #申明主模型
    master_problem = grb.Model('master_problem')
    master_problem.setParam('OutputFlag', 0)
    master_problem.modelSense = grb.GRB.MINIMIZE

    #申明决策变量 obj=***就表明了该组变量在目标函数中的系数
    ####这一块参考gurobi给的例子:facility.py
    I = master_problem.addVars(inventory,
                               vtype=grb.GRB.CONTINUOUS,
                               obj=holding_cost,
                               name='I')

    Z = master_problem.addVars(plants,
                               vtype=grb.GRB.BINARY,
                               obj=fixed_cost,
                               name='Z')

    #----------载入各种约束-----------#

    #额外算的值
    temp_sum = sum((upper_demand - lower_demand)**2)
    TI = math.ceil(mean_demand.sum() +
                   math.sqrt(-math.log(service_level) * temp_sum / 2))
    del temp_sum

    #载入chance constraints
    #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧)
    #这里是small set的约束
    for k in range(1, s + 1):
        for nodeSet in itertools.combinations(range(num_demand), k):
            expr = sum((a[:, nodeSet].sum(axis=1) >= 1) * I.values())
            master_problem.addConstr(expr >= sum(upper_demand[j]
                                                 for j in nodeSet))
            del expr
        print('Small=={},约束添加完成'.format(k))

    #这里是big set的约束

    for k in range(S + 1, num_demand + 1):
        for nodeSet in itertools.combinations(range(num_demand), k):

            nonNodeSet = [j for j in range(num_demand) if j not in nodeSet]
            nonAdjacentNodeSet = np.where(a[:, nodeSet].sum(axis=1) == 0)[0]
            expr_I = sum(I[i] for i in nonAdjacentNodeSet)
            expr_DL = sum(lower_demand[j] for j in nonNodeSet)

            if nonAdjacentNodeSet.size != 0:  #if nonAdjacentNodeSet.size==0, expr_i==0,下面的等式始终成立
                master_problem.addConstr(expr_I <= expr_DL)
            del expr_I, expr_DL

        print('Big=={},约束添加完成'.format(k))

    #载入约束3-----Ii<=M*Zi
    M = upper_demand.sum()
    master_problem.addConstrs(I[i] <= M * Z[i] for i in plants)

    #求解
    master_problem.optimize()

    return master_problem, {
        '# of Open DC': sum(Z.values()),
        'FSC': sum(Z.values() * fixed_cost) + sum(I.values() * holding_cost),
        'Inventory': I.values(),
        'Total Inventory': sum(I.values())
    }
예제 #14
0
def small_big_design(cost,
                     demand,
                     a,
                     num_plants,
                     num_demand,
                     s,
                     S,
                     weight,
                     service_level=0.1,
                     mode='set'):

    if mode == 'set':
        add_constraints_time = 0

        fixed_cost = cost[0]
        holding_cost = cost[1]

        lower_demand = demand[0]
        mean_demand = demand[1]
        upper_demand = demand[2]

        inventory = range(num_plants)
        plants = range(num_plants)
        demand = range(num_demand)

        constraintType = []
        iterValue = []
        iterValue_small = []
        iterValue_big = []
        #------------申明主问题-----------#
        #申明主模型
        master_problem = grb.Model('master_problem')
        master_problem.setParam('OutputFlag', 0)
        master_problem.modelSense = grb.GRB.MINIMIZE

        #申明决策变量 obj=***就表明了该组变量在目标函数中的系数
        ####这一块参考gurobi给的例子:facility.py
        I = master_problem.addVars(inventory,
                                   vtype=grb.GRB.CONTINUOUS,
                                   obj=holding_cost,
                                   name='I')

        Z = master_problem.addVars(plants,
                                   vtype=grb.GRB.BINARY,
                                   obj=fixed_cost,
                                   name='Z')

        #----------载入各种约束-----------#

        #额外算的值
        temp_sum = sum((upper_demand - lower_demand)**2)
        TI = math.ceil(mean_demand.sum() +
                       math.sqrt(-math.log(service_level) * temp_sum / 2))
        del temp_sum

        #载入chance constraints
        #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧)
        #这里是small set的约束
        for j in demand:
            expr = sum(a[:, j] * I.values())
            master_problem.addConstr(expr >= upper_demand[j])
            del expr
            constraintType.append('small')

        #这里是big set的约束
        #要求|S|>25 (某数),最直观的的是取30时候,此时不属于这个集合的点是空集
        #所以没有约束。
        #第二个的约束去子问题中迭代加入
        expr = 0
        del expr

        #载入约束3-----Ii<=M*Zi
        M = upper_demand.sum()
        master_problem.addConstrs(I[i] <= M * Z[i] for i in plants)
        for i in plants:
            constraintType.append('others')
        #------------------开始迭代主问题------------------------------------#
        #-------------------------------------------------------------------#
        time_start = time.clock()

        while True:
            #解主问题
            master_problem.optimize()

            #确定主问题解的状态
            if master_problem.status == 3:
                iterValue.append(master_problem.ObjVal)
                break

            elif master_problem.status == 2:
                print('master_Value:', master_problem.ObjVal)
                iterValue.append(master_problem.ObjVal)

                #-------------开始子问题---------------#
                #申明small set的子问题----sub_problem1
                sub_problem1 = grb.Model('sub_problem1')
                sub_problem1.setParam('OutputFlag', 0)

                #申明子问题的变量
                x1 = sub_problem1.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x1')
                y1 = sub_problem1.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y1')

                #设置目标函数
                expr1 = grb.quicksum([y1[i] * I[i].x for i in plants])
                expr2 = sum(upper_demand * x1.values())
                #for j in demand:
                #    expr2 = expr2 + upper_demand[j] * x1[j]
                sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                expr = sum(x1.values())
                sub_problem1.addConstr(expr <= s)
                del expr

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem1.addConstr(y1[i] >= x1[j])

            #解子问题
                sub_problem1.optimize()

                #申明big set的子问题----sub_problem2  -----------
                #big set
                #big set
                #big set
                sub_problem2 = grb.Model('sub_problem1')
                sub_problem2.setParam('OutputFlag', 0)

                #申明子问题的变量
                x2 = sub_problem2.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x2')
                y2 = sub_problem2.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y2')

                #设置目标函数
                expr1 = grb.quicksum([(1 - y2[i]) * I[i].x for i in plants])
                expr2 = grb.quicksum(
                    [lower_demand[j] * (1 - x2[j]) for j in demand])
                sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                expr = grb.quicksum(x2.values())
                sub_problem2.addConstr(expr >= S)
                del expr

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem2.addConstr(y2[i] >= x2[j])

            #解子问题
                sub_problem2.optimize()

                #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中
                if sub_problem1.ObjVal >= -0.01 and sub_problem2.ObjVal >= -0.01:
                    iterValue_small.append(sub_problem1.ObjVal)
                    iterValue_big.append(sub_problem2.ObjVal)
                    break
                else:
                    if sub_problem1.ObjVal < -0.001:
                        print('small_set:', sub_problem1.ObjVal)
                        iterValue_small.append(sub_problem1.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x1[j].x * a[:, j] + a_temp
                            expr2 = upper_demand[j] * x1[j].x + expr2
                        for i in plants:
                            if round(a_temp[i]) != 0:
                                expr1 = expr1 + round(a_temp[i]) / round(
                                    a_temp[i]) * I[i]
                        temp_expr = expr1 >= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        constraintType.append('small')
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1
                    else:
                        iterValue_small.append(np.nan)

                    if sub_problem2.ObjVal < -0.001:
                        print('big_set:', sub_problem2.ObjVal)
                        iterValue_big.append(sub_problem2.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x2[j].x * a[:, j] + a_temp
                            expr2 = lower_demand[j] * (
                                int(not x2[j].x)) + expr2
                        for i in plants:
                            expr1 = expr1 + int(not a_temp[i]) * I[i]
                        temp_expr = expr1 <= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        constraintType.append('big')
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1
                    else:
                        iterValue_big.append(np.nan)

        time_end = time.clock()

        if master_problem.status == 2:

            I_return = []
            Z_return = []
            p = 0
            open_DC = 0
            for i in plants:
                open_DC = open_DC + Z[i].x
                p = p + I[i].x
                I_return.append(I[i].x)
                Z_return.append(Z[i].x)

            return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [
                s, open_DC, I_return, Z_return, p, p / TI,
                master_problem.ObjVal, time_end - time_start,
                add_constraints_time, 'optimal'
            ]

        elif master_problem.status == 3:
            return master_problem, constraintType, iterValue, iterValue_small, iterValue_big, [
                '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible'
            ]

    if mode == 'weight':
        add_constraints_time = 0

        fixed_cost = cost[0]
        holding_cost = cost[1]

        lower_demand = demand[0]
        mean_demand = demand[1]
        upper_demand = demand[2]

        inventory = range(num_plants)
        plants = range(num_plants)
        demand = range(num_demand)

        #------------申明主问题-----------#
        #申明主模型
        master_problem = grb.Model('master_problem')
        master_problem.setParam('OutputFlag', 0)
        master_problem.modelSense = grb.GRB.MINIMIZE

        #申明决策变量 obj=***就表明了该组变量在目标函数中的系数
        ####这一块参考gurobi给的例子:facility.py
        I = master_problem.addVars(inventory,
                                   vtype=grb.GRB.INTEGER,
                                   obj=holding_cost,
                                   name='I')

        Z = master_problem.addVars(plants,
                                   vtype=grb.GRB.BINARY,
                                   obj=fixed_cost,
                                   name='Z')

        #----------载入各种约束-----------#

        #额外算的值
        temp_sum = 0
        for j in demand:
            temp_sum += (upper_demand[j] -
                         lower_demand[j]) * (upper_demand[j] - lower_demand[j])

        TI = math.ceil(mean_demand.sum() +
                       math.sqrt(-math.log(service_level) * temp_sum / 2))
        del temp_sum

        #载入chance constraints

        #没有约束。
        #第二个的约束去子问题中迭代加入
        expr = 0

        del expr

        #载入约束3-----Ii<=M*Zi
        M = upper_demand.sum()
        master_problem.addConstrs(I[i] <= M * Z[i] for i in plants)

        #------------------开始迭代主问题------------------------------------#
        #-------------------------------------------------------------------#
        time_start = time.clock()

        while True:
            #解主问题
            master_problem.optimize()

            #确定主问题解的状态
            if master_problem.status == 3:
                break

            elif master_problem.status == 2:

                #-------------开始子问题---------------#
                #申明small set的子问题----sub_problem1
                sub_problem1 = grb.Model('sub_problem1')
                sub_problem1.setParam('OutputFlag', 0)

                #申明子问题的变量
                x1 = sub_problem1.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x1')
                y1 = sub_problem1.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y1')

                #设置目标函数
                expr1 = 0
                expr2 = 0
                for i in plants:
                    expr1 = expr1 + y1[i] * I[i].x
                for j in demand:
                    expr2 = expr2 + upper_demand[j] * x1[j]
                sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                sub_problem1.addConstr(
                    grb.quicksum(x1[j] * upper_demand[j]
                                 for j in demand) <= weight * M)

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem1.addConstr(y1[i] >= x1[j])

            #解子问题
                sub_problem1.optimize()

                #申明big set的子问题----sub_problem2  -----------
                #big set
                #big set
                #big set
                sub_problem2 = grb.Model('sub_problem1')
                sub_problem2.setParam('OutputFlag', 0)

                #申明子问题的变量
                x2 = sub_problem2.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x2')
                y2 = sub_problem2.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y2')

                #设置目标函数
                expr1 = 0
                expr2 = 0
                for i in plants:
                    expr1 = expr1 + (1 - y2[i]) * I[i].x
                for j in demand:
                    expr2 = expr2 + lower_demand[j] * (1 - x2[j])
                sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                sub_problem2.addConstr(
                    grb.quicksum(x1[j] * lower_demand[j]
                                 for j in demand) >= (1 - weight) * M)

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem2.addConstr(y2[i] >= x2[j])

            #解子问题
                sub_problem2.optimize()

                #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中
                if sub_problem1.ObjVal >= 0 and sub_problem2.ObjVal >= 0:
                    break
                else:
                    if sub_problem1.ObjVal < -0.0001:
                        print('small_set:', sub_problem1.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x1[j].x * a[:, j] + a_temp
                            expr2 = upper_demand[j] * x1[j].x + expr2
                        for i in plants:
                            if round(a_temp[i]) != 0:
                                expr1 = expr1 + round(a_temp[i]) / round(
                                    a_temp[i]) * I[i]
                        temp_expr = expr1 >= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1

                    if sub_problem2.ObjVal < -0.0001:
                        print('big_set:', sub_problem2.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x2[j].x * a[:, j] + a_temp
                            expr2 = lower_demand[j] * (
                                int(not x2[j].x)) + expr2
                        for i in plants:
                            expr1 = expr1 + int(not a_temp[i]) * I[i]
                        temp_expr = expr1 <= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1

        time_end = time.clock()

        if master_problem.status == 2:

            I_return = []
            Z_return = []
            p = 0
            open_DC = 0
            for i in plants:
                open_DC = open_DC + Z[i].x
                p = p + I[i].x
                I_return.append(I[i].x)
                Z_return.append(Z[i].x)

            return s, open_DC, I_return, Z_return, p, p / TI, master_problem.ObjVal, time_end - time_start, add_constraints_time, 'optimal'

        elif master_problem.status == 3:
            return '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible'

    if mode == 'both':
        add_constraints_time = 0

        fixed_cost = cost[0]
        holding_cost = cost[1]

        lower_demand = demand[0]
        mean_demand = demand[1]
        upper_demand = demand[2]

        inventory = range(num_plants)
        plants = range(num_plants)
        demand = range(num_demand)

        #------------申明主问题-----------#
        #申明主模型
        master_problem = grb.Model('master_problem')
        master_problem.setParam('OutputFlag', 0)
        master_problem.modelSense = grb.GRB.MINIMIZE

        #申明决策变量 obj=***就表明了该组变量在目标函数中的系数
        ####这一块参考gurobi给的例子:facility.py
        I = master_problem.addVars(inventory,
                                   vtype=grb.GRB.INTEGER,
                                   obj=holding_cost,
                                   name='I')

        Z = master_problem.addVars(plants,
                                   vtype=grb.GRB.BINARY,
                                   obj=fixed_cost,
                                   name='Z')

        #----------载入各种约束-----------#

        #额外算的值
        temp_sum = 0
        for j in demand:
            temp_sum += (upper_demand[j] -
                         lower_demand[j]) * (upper_demand[j] - lower_demand[j])

        TI = math.ceil(mean_demand.sum() +
                       math.sqrt(-math.log(service_level) * temp_sum / 2))
        del temp_sum

        #载入chance constraints
        #至少有 demand个约束(至少每个需求点的需求,都能被和它相连的supplier满足吧)
        #这里是small set的约束
        for j in demand:
            expr = 0
            for i in plants:
                expr = a[i, j] * I[i] + expr
            master_problem.addQConstr(expr >= upper_demand[j])
            del expr

        #这里是big set的约束
        #要求|S|>25 (某数),最直观的的是取30时候,此时不属于这个集合的点是空集
        #所以没有约束。
        #第二个的约束去子问题中迭代加入
        expr = 0

        del expr

        #载入约束3-----Ii<=M*Zi
        M = upper_demand.sum()
        master_problem.addConstrs(I[i] <= M * Z[i] for i in plants)

        #------------------开始迭代主问题------------------------------------#
        #-------------------------------------------------------------------#
        time_start = time.clock()

        while True:
            #解主问题
            master_problem.optimize()

            #确定主问题解的状态
            if master_problem.status == 3:
                break

            elif master_problem.status == 2:

                #-------------开始子问题---------------#
                '''
                2个和set大小有关的子问题
                '''
                #申明small set的子问题----sub_problem1
                sub_problem1 = grb.Model('sub_problem1')
                sub_problem1.setParam('OutputFlag', 0)

                #申明子问题的变量
                x1 = sub_problem1.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x1')
                y1 = sub_problem1.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y1')

                #设置目标函数
                expr1 = 0
                expr2 = 0
                for i in plants:
                    expr1 = expr1 + y1[i] * I[i].x
                for j in demand:
                    expr2 = expr2 + upper_demand[j] * x1[j]
                sub_problem1.setObjective(expr1 - expr2, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                expr = 0
                for j in demand:
                    expr = x1[j] + expr
                sub_problem1.addConstr(expr <= s)
                del expr

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem1.addConstr(y1[i] >= x1[j])

            #解子问题
                sub_problem1.optimize()

                #申明big set的子问题----sub_problem2  -----------
                #big set
                #big set
                #big set
                sub_problem2 = grb.Model('sub_problem2')
                sub_problem2.setParam('OutputFlag', 0)

                #申明子问题的变量
                x2 = sub_problem2.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x2')
                y2 = sub_problem2.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y2')

                #设置目标函数
                expr1 = 0
                expr2 = 0
                for i in plants:
                    expr1 = expr1 + (1 - y2[i]) * I[i].x
                for j in demand:
                    expr2 = expr2 + lower_demand[j] * (1 - x2[j])
                sub_problem2.setObjective(expr2 - expr1, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                expr = 0
                for j in demand:
                    expr = x2[j] + expr
                sub_problem2.addConstr(expr >= S)
                del expr

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem2.addConstr(y2[i] >= x2[j])

            #解子问题
                sub_problem2.optimize()
                '''
                2个和weight 有关的子问题
                '''

                #申明small set的子问题----sub_problem1
                sub_problem3 = grb.Model('sub_problem3')
                sub_problem3.setParam('OutputFlag', 0)

                #申明子问题的变量
                x3 = sub_problem3.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x3')
                y3 = sub_problem3.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y3')

                #设置目标函数
                expr1 = 0
                expr2 = 0
                for i in plants:
                    expr1 = expr1 + y3[i] * I[i].x
                for j in demand:
                    expr2 = expr2 + upper_demand[j] * x3[j]
                sub_problem3.setObjective(expr1 - expr2, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                sub_problem3.addConstr(
                    grb.quicksum(x3[j] * upper_demand[j]
                                 for j in demand) <= weight * M)

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem3.addConstr(y3[i] >= x3[j])

            #解子问题
                sub_problem3.optimize()

                #申明big weight的子问题----sub_problem2  -----------
                #big set
                #big set
                #big set
                sub_problem4 = grb.Model('sub_problem4')
                sub_problem4.setParam('OutputFlag', 0)

                #申明子问题的变量
                x4 = sub_problem4.addVars(demand,
                                          vtype=grb.GRB.BINARY,
                                          name='x4')
                y4 = sub_problem4.addVars(plants,
                                          vtype=grb.GRB.BINARY,
                                          name='y4')

                #设置目标函数
                expr1 = 0
                expr2 = 0
                for i in plants:
                    expr1 = expr1 + (1 - y4[i]) * I[i].x
                for j in demand:
                    expr2 = expr2 + lower_demand[j] * (1 - x4[j])
                sub_problem4.setObjective(expr2 - expr1, grb.GRB.MINIMIZE)
                del expr1
                del expr2
                #载入子问题的约束

                #子问题约束1
                sub_problem4.addConstr(
                    grb.quicksum(x4[j] * lower_demand[j]
                                 for j in demand) >= (1 - weight) * M)

                #子问题约束2,
                for i in plants:
                    for j in demand:
                        if round(a[i, j]) == 1:
                            sub_problem4.addConstr(y4[i] >= x4[j])

            #解子问题
                sub_problem4.optimize()

                #判断子问题的目标函数值是否为非负数,若是,则主问题得到了最优解,break;否则加入新的约束到主问题中
                if sub_problem1.ObjVal >= 0 and sub_problem2.ObjVal >= 0 and sub_problem3.ObjVal >= 0 and sub_problem4.ObjVal >= 0:
                    break
                else:
                    if sub_problem1.ObjVal < -0.0001:
                        print('small_set:', sub_problem1.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x1[j].x * a[:, j] + a_temp
                            expr2 = upper_demand[j] * x1[j].x + expr2
                        for i in plants:
                            if round(a_temp[i]) != 0:
                                expr1 = expr1 + round(a_temp[i]) / round(
                                    a_temp[i]) * I[i]
                        temp_expr = expr1 >= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1

                    if sub_problem2.ObjVal < -0.0001:
                        print('big_set:', sub_problem2.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x2[j].x * a[:, j] + a_temp
                            expr2 = lower_demand[j] * (
                                int(not x2[j].x)) + expr2
                        for i in plants:
                            expr1 = expr1 + int(not a_temp[i]) * I[i]
                        temp_expr = expr1 <= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1

                    if sub_problem3.ObjVal < -0.0001:
                        print('small_set:', sub_problem3.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x3[j].x * a[:, j] + a_temp
                            expr2 = upper_demand[j] * x3[j].x + expr2
                        for i in plants:
                            if round(a_temp[i]) != 0:
                                expr1 = expr1 + round(a_temp[i]) / round(
                                    a_temp[i]) * I[i]
                        temp_expr = expr1 >= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1

                    if sub_problem4.ObjVal < -0.0001:
                        print('big_set:', sub_problem4.ObjVal)
                        expr1 = 0
                        expr2 = 0
                        a_temp = [0] * num_plants
                        for j in demand:
                            a_temp = x4[j].x * a[:, j] + a_temp
                            expr2 = lower_demand[j] * (
                                int(not x4[j].x)) + expr2
                        for i in plants:
                            expr1 = expr1 + int(not a_temp[i]) * I[i]
                        temp_expr = expr1 <= expr2
                        master_problem.addConstr(temp_expr)  #加新的约束到主问题中
                        del expr1
                        del expr2
                        del temp_expr
                        del a_temp
                        add_constraints_time += 1

        time_end = time.clock()

        if master_problem.status == 2:

            I_return = []
            Z_return = []
            p = 0
            open_DC = 0
            for i in plants:
                open_DC = open_DC + Z[i].x
                p = p + I[i].x
                I_return.append(I[i].x)
                Z_return.append(Z[i].x)

            return master_problem, constraintType, iterValue, [
                s, open_DC, I_return, Z_return, p, p / TI,
                master_problem.ObjVal, time_end - time_start,
                add_constraints_time, 'optimal'
            ]

        elif master_problem.status == 3:
            return master_problem, constraintType, iterValue, [
                '-', '-', '-', '-', '-', '-', '-', '-', '-', 'infeasible'
            ]