Ejemplo n.º 1
0
    def __init__(self, p: AlloyProductionProblem):
        self.p = p
        self.m = Model('APP')

        # Creates the decision variables
        self.materials = list(p.availability.keys())
        chemicals = list(p.max_grade.keys())
        self.x = self.m.addVars(self.materials, name='x')

        # Creates the objective function
        expr = self.x.prod(p.cost)
        self.m.setObjective(expr, sense=GRB.MINIMIZE)

        # Creates the constraints
        # Min content
        self.m.addConstrs(
            quicksum([p.content[(k, m)] * self.x[m]
                      for m in self.materials]) >= p.min_grade[k] *
            self.x.sum('*') for k in chemicals)
        # Max content
        self.m.addConstrs(
            quicksum([p.content[(k, m)] * self.x[m]
                      for m in self.materials]) <= p.max_grade[k] *
            self.x.sum('*') for k in chemicals)
        # Availability
        self.m.addConstrs(self.x[m] <= p.availability[m]
                          for m in self.materials)
        # Demand
        self.m.addConstr(self.x.sum('*') >= p.demand)
Ejemplo n.º 2
0
    def __SBM_super_C(self):
        for k in self.DMUs:
            MODEL = gurobipy.Model()

            fi = MODEL.addVars(self.m1)
            lambdas = MODEL.addVars(self.DMUs)
            fo = MODEL.addVars(self.m2)
            t = MODEL.addVar()

            MODEL.update()

            MODEL.setObjective(
                t + t / self.m1 * quicksum(fi[j] for j in range(self.m1)),
                sense=gurobipy.GRB.MINIMIZE)

            MODEL.addConstrs(
                quicksum(lambdas[i] * self.X[i][j] for i in self.DMUs
                         if i != k) <= (1 + fi[j]) * self.X[k][j]
                for j in range(self.m1))
            MODEL.addConstrs(
                quicksum(lambdas[i] * self.Y[i][j] for i in self.DMUs
                         if i != k) >= (1 - fo[j]) * self.Y[k][j]
                for j in range(self.m2))
            MODEL.addConstr(
                t - t / self.m2 * quicksum(fo[j] for j in range(self.m2)) == 1)

            MODEL.setParam('OutputFlag', 0)
            MODEL.setParam("NonConvex", 2)
            MODEL.optimize()

            self.Result.at[k, ('效益分析', '效率')] = MODEL.objVal
        return self.Result
def addOptimalityCut(masterProblem, subProblem, A, b, n):
    # get dual value
    dualValue = subProblem.Pi

    #add optimality cut \ita
    optimalitycut = ITA[n + 1] - grb.quicksum(
        dualValue[i] * (b[n][i] - grb.quicksum(A[i][j] * X[j + 1]
                                               for j in range(A.shape[1])))
        for i in range(A.shape[0])) >= 0
    masterProblem.addConstr(optimalitycut)
def addFeasibilityCut(masterProblem, subProblem, A, b, n):
    # find the extreme ray
    # !!! FarkasDual gets the reverse-directional extreme ray
    extremeRay = -np.asarray(subProblem.FarkasDual)

    #add feasiblity cut: r^j(b-Ax) <= 0
    feasibilitycut = grb.quicksum(
        extremeRay[i] * (b[n][i] - grb.quicksum(A[i][j] * X[j + 1]
                                                for j in range(A.shape[1])))
        for i in range(A.shape[0])) <= 0
    masterProblem.addConstr(feasibilitycut)
Ejemplo n.º 5
0
    def __init__(self,p:KnapsackProblem):
        self.p = p
        self.m = Model('knapsack')
        # Creates the decision variables
        self.x = self.m.addVars(len(p.rewards),vtype = GRB.BINARY,name = "x")

        # Creates the objective
        self.m.setObjective(quicksum([self.p.rewards[i] * self.x[i] for i in range(len(self.p.rewards))]),sense=GRB.MAXIMIZE)

        # Creates the constraint
        self.m.addConstr(quicksum([self.p.weights[i] * self.x[i] for i in range(len(self.p.weights))]) <= self.p.capacity)
    def solve_restricted_primal(self, demands, demands_next, p):
        self.obj = 0.
        m = Model("multi-unit-auction")
        # self.m.params.LogToConsole = 0
        self.allocation_vars = dict()
        for agent in self.agents:
            for i in range(1, self.supply + 1):
                self.allocation_vars[agent.id, i] = m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS,
                                                                  name='x_%s_%s' % (agent.id, i))
        m.update()
        for agent in self.agents:
            if len(demands[agent.id]) > 0 and len(demands_next[agent.id]) > 0:
                m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)),
                                 GRB.EQUAL, 1, name="u_%s_strict" % agent.id)
            else:
                m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)),
                                 GRB.LESS_EQUAL, 1, name="u_%s" % agent.id)
            for j in range(1, self.supply + 1):
                if j not in [demand.quantity for demand in demands[agent.id]]:
                    m.addConstr(self.allocation_vars[agent.id, j], GRB.EQUAL, 0, name='x_%s_%s_undemanded' % (agent.id, j))

        if p > 0:
            m.addConstr(
                quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents),
                GRB.EQUAL, self.supply, name="price_strict")
        else:
            m.addConstr(
                quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents),
                GRB.LESS_EQUAL, self.supply, name="price")
        obj_expr = LinExpr()
        for agent in self.agents:
            for valuation in agent.valuations:
                obj_expr.addTerms(valuation.quantity, self.allocation_vars[agent.id, valuation.quantity])
        m.setObjective(obj_expr, GRB.MAXIMIZE)
        m.update()
        m.optimize()

        m.write('optimal-lp.lp')

        if m.status == GRB.OPTIMAL:
            m.write('optimal-lp.sol')
            for v in [v for v in m.getVars() if v.x != 0.]:
                print('%s %g' % (v.varName, v.x))

            print ''
            print 'CONSTRAINTS:'

            for l in m.getConstrs():
                if l.Pi > 0:
                    print('%s %g' % (l.constrName, l.Pi))

            print m.getObjective().getValue()

        return m
Ejemplo n.º 7
0
    def __init__(self, p: CuttingStockProblem):
        self.p = p
        self.m = Model('CS1')

        # Decision variables
        n_large_rolls = self.p.get_max_number_of_large_rolls()
        n_small_roll_types = len(self.p.demand)
        print(n_large_rolls, n_small_roll_types)
        y = self.m.addVars([i for i in range(n_large_rolls)],
                           lb=0,
                           ub=1,
                           vtype=GRB.CONTINUOUS,
                           name="y")
        z = self.m.addVars([j for j in range(n_small_roll_types)],
                           [i for i in range(n_large_rolls)],
                           lb=0,
                           ub=GRB.INFINITY,
                           vtype=GRB.CONTINUOUS,
                           name="x")

        # Objective function
        self.m.setObjective(y.sum('*'))

        # Constraints
        # Note that the argument passed to quicksum is a list, and the list is built using comprehension
        self.m.addConstrs(
            quicksum([
                self.p.width_small_rolls[i] * z[i, j]
                for i in range(n_small_roll_types)
            ]) <= self.p.width_large_rolls * y[j]
            for j in range(n_large_rolls))
        self.m.addConstrs(
            z.sum(i, '*') >= self.p.demand[i]
            for i in range(n_small_roll_types))
Ejemplo n.º 8
0
 def add_optimality_cut(self, dualsCC: list, dualsDC: list):
     self.m.addConstr(self.phi - quicksum(
         [dualsCC[i] * self.x[i]
          for i in range(self.fsp.n_facilities)]) >= sum([
              dualsDC[j] * self.fsp.demands[j]
              for j in range(self.fsp.n_customers)
          ]))
     print("Added optimality cut")
Ejemplo n.º 9
0
 def add_feasibility_cut(self, dualsCC: list, dualsDC: list):
     self.m.addConstr(
         quicksum(
             [dualsCC[i] * self.x[i]
              for i in range(self.fsp.n_facilities)]) <= -sum([
                  dualsDC[j] * self.fsp.demands[j]
                  for j in range(self.fsp.n_customers)
              ]))
     print("Added feasibility cut")
    def SolveStoModel(self) -> Model:
        StoModel = Model('StoModel')
        StoModel.setParam('OutputFlag', 0)
        StoModel.modelSense = GRB.MINIMIZE

        m, n = self.m, self.n
        h, f = self.h, self.f
        d_rs = self.d_rs
        d_rs_length = len(d_rs)

        I = StoModel.addVars(m, vtype=GRB.CONTINUOUS, name='I')
        Z = StoModel.addVars(m, vtype=GRB.BINARY, name='Z')
        Transshipment_X = StoModel.addVars(self.roads,
                                           d_rs_length,
                                           vtype=GRB.CONTINUOUS,
                                           name='Transshipment_X')

        objFunc_holding = quicksum(I[i] * h[i] for i in range(m))
        objFunc_fixed = quicksum(Z[i] * f[i] for i in range(m))
        objFunc_penalty = quicksum(d_r[j] - Transshipment_X.sum('*', j, k)
                                   for k, d_r in d_rs.items()
                                   for j in range(n))
        objFunc = objFunc_holding + objFunc_fixed + (objFunc_penalty /
                                                     d_rs_length)
        StoModel.setObjective(objFunc)

        # 约束1
        for k in range(d_rs_length):
            StoModel.addConstrs(
                Transshipment_X.sum(i, '*', k) <= I[i] for i in range(m))

        # 约束2
        for k, d_r in d_rs.items():
            StoModel.addConstrs(
                Transshipment_X.sum('*', j, k) <= d_r[j] for j in range(n))

        # 约束3 I_i<=M*Z_i
        StoModel.addConstrs(I[i] <= 20000 * Z[i] for i in range(m))

        # 求解评估模型
        StoModel.optimize()
        self.model = StoModel
        return StoModel
Ejemplo n.º 11
0
    def __init__(self,p: UraniumMineProblem):
        self.p = p
        self.m = Model('uranium')

        # Decision variables
        self.x = self.m.addVars(self.p.blocks,vtype=GRB.BINARY,name="x")
        # Objective function
        expr = quicksum([(p.values[b] - p.costs[b]) * self.x[b] for b in p.blocks])
        self.m.setObjective(expr,sense=GRB.MAXIMIZE)

        # Constraints
        self.m.addConstrs(self.x[a] - self.x[b] <= 0 for (a,b) in p.precedences)
Ejemplo n.º 12
0
    def _balancing(self, flow_graph, sinks, frontier, demands):
        configure_gurobi()
        model = Model()

        xij = {i: {} for i in frontier}
        for node in frontier:
            congestion = sum(flow_graph[node][neighbor] for neighbor in flow_graph[node])
            for neighbor in flow_graph[node]:
                assert neighbor in sinks
                xij[node][neighbor] = model.addVar(vtype=GRB.CONTINUOUS, name=f"x_{node}_{neighbor}")
                model.addConstr(xij[node][neighbor] >= 0)
            model.addConstr(quicksum(xij[node][neighbor] for neighbor in flow_graph[node]) == congestion)

        sink_predecessors = {i: [] for i in sinks}
        for node in frontier:
            for neighbor in flow_graph[node]:
                sink_predecessors[neighbor].append(node)

        bj = {}
        for node in sinks:
            bj[node] = model.addVar(vtype=GRB.CONTINUOUS, name=f"b_{node}")
            model.addConstr(bj[node] == quicksum(xij[pred][node] for pred in sink_predecessors[node]) + demands[node])

        model.setObjective(quicksum(bj[node] * bj[node] for node in sinks), GRB.MINIMIZE)
        model.optimize()

        any_edge_deleted = False
        for node in frontier:
            to_delete = []
            for neighbor in flow_graph[node]:
                flow = xij[node][neighbor].X
                if flow < EPS:
                    to_delete.append(neighbor)
                    any_edge_deleted = True
                else:
                    flow_graph[node][neighbor] = flow
            for neighbor in to_delete:
                del flow_graph[node][neighbor]

        return any_edge_deleted
    def SolveDetModel(self) -> Model:
        DetModel = Model('StoModel')
        DetModel.setParam('OutputFlag', 0)
        DetModel.modelSense = GRB.MINIMIZE

        m, n = self.m, self.n
        h, f = self.h, self.f
        mu = self.det_param['mu']

        I = DetModel.addVars(m, vtype=GRB.CONTINUOUS, name='I')
        Z = DetModel.addVars(m, vtype=GRB.BINARY, name='Z')
        Transshipment_X = DetModel.addVars(self.roads,
                                           vtype=GRB.CONTINUOUS,
                                           name='Transshipment_X')

        objFunc_holding = quicksum(I[i] * h[i] for i in range(m))
        objFunc_fixed = quicksum(Z[i] * f[i] for i in range(m))
        objFunc_penalty = quicksum(mu[j] - Transshipment_X.sum('*', j)
                                   for j in range(n))
        objFunc = objFunc_holding + objFunc_fixed + objFunc_penalty
        DetModel.setObjective(objFunc)

        # 约束1
        DetModel.addConstrs(
            Transshipment_X.sum(i, '*') <= I[i] for i in range(m))

        # 约束2
        DetModel.addConstrs(
            Transshipment_X.sum('*', j) <= mu[j] for j in range(n))

        # 约束3 I_i<=M*Z_i
        DetModel.addConstrs(I[i] <= 20000 * Z[i] for i in range(m))

        # 求解评估模型
        DetModel.optimize()
        self.model = DetModel
        return DetModel
Ejemplo n.º 14
0
    def __init__(self, p:CuttingStockProblem):
        self.p = p
        self.m = Model('CS1')

        # Decision variables
        n_patterns = len(self.p.get_feasible_patterns())

        x = self.m.addVars(n_patterns,lb= 0, ub= GRB.INFINITY, vtype=GRB.CONTINUOUS,name="x")

        # Objective function
        self.m.setObjective(x.sum('*'))

        # Constraints
        # Note that the argument passed to quicksum is a list, and the list is built using comprehension
        self.m.addConstrs(quicksum([self.p.get_feasible_patterns()[q][i] * x[q] for q in range(n_patterns)]) >= self.p.demand[i]  for i in range(len(p.demand)))
Ejemplo n.º 15
0
    def __init__(self, fsp: FacilitySizingProblem):
        self.fsp = fsp
        self.m = Model()

        # Creates the variables
        self.x = self.m.addVars(fsp.n_facilities,
                                vtype=GRB.CONTINUOUS,
                                name="x")
        self.phi = self.m.addVar(name="phi")

        # Creates the objective
        expr = self.phi + quicksum([
            self.fsp.fixed_costs[i] * self.x[i]
            for i in range(self.fsp.n_facilities)
        ])
        self.m.setObjective(expr, GRB.MINIMIZE)

        # Creates the constraints
        self.m.addConstrs(self.x[i] <= self.fsp.capacity[i]
                          for i in range(fsp.n_facilities))
            subProblem.setParam('OutputFlag', 0)
            subProblem.setParam(
                'InfUnbdInfo', 1
            )  #InfUnbdInfo is the prerequire for getting FarkasProof attribute

            # variables
            Y = subProblem.addVars([1, 2],
                                   vtype=grb.GRB.CONTINUOUS,
                                   lb=[0, 0],
                                   obj=[15, 12],
                                   name='Y')

            # add second-stage recourse constraints

            subProblem.addConstrs(
                grb.quicksum(G[i][j] * Y[j + 1]
                             for j in range(G.shape[1])) >= b[n][i] -
                grb.quicksum(A[i][j] * X[j + 1].x for j in range(A.shape[1]))
                for i in range(G.shape[0]))

            # --- 2.1. solve the k-th subproblem
            subProblem.optimize()

            # --- 2.1.1. subproblem is infeasible, then add a feasibility cut (should find out the extreme rays)
            if subProblem.Status == grb.GRB.INFEASIBLE:
                addFeasibilityCut(masterProblem, subProblem, A, b, n)
                ADDFEASIBILITYCUT_NUM += 1

            # --- 2.1.2. add optimality cut or get optimal solution
            elif subProblem.Status == grb.GRB.OPTIMAL:

                # if subproblem == ita, we now get optimal solution in the master problem
Ejemplo n.º 17
0
def _optimize(
    families: Iterable[Family],
    days: Iterable[Day],
    family_index: Mapping[FamilyID, Family],
    mip_start: Optional[Assignments],
) -> Solution:
    with gurobi.model("santa-19") as model:

        assignment_vars = model.addVars(
            tuplelist((family.id, family_choice) for family in families
                      for family_choice in family.choices),
            name="x",
            vtype=GRB.BINARY,
        )
        occupancy_vars = model.addVars(
            tuplelist((occupancy, day) for day in days
                      for occupancy in _FEASIBLE_OCCUPANCIES),
            name="delta",
            vtype=GRB.BINARY,
        )
        occupancy_pairs = {(o, o_p, d): accounting_cost(o, o_p)
                           for o in _FEASIBLE_OCCUPANCIES
                           for o_p in _FEASIBLE_OCCUPANCIES for d in days}
        occupancy_pair_vars = model.addVars(occupancy_pairs.keys(),
                                            name="phi",
                                            lb=0,
                                            ub=1)
        logger.info("Created variables")

        model.addConstrs(
            (quicksum(assignment_vars[(family_id, family_choice)]
                      for family_choice in family_index[family_id].choices)
             == 1 for family_id in family_index.keys()),
            name="assg",
        )
        model.addConstrs((occupancy_vars.sum("*", day) == 1 for day in days),
                         name="occ_c")
        model.addConstrs(
            (quicksum(
                assignment_vars.get((family.id, day), 0) *
                family.number_of_members for family in families) == quicksum(
                    occupancy_vars[(occupancy, day)] * occupancy
                    for occupancy in _FEASIBLE_OCCUPANCIES) for day in days),
            name="occ",
        )

        n_days = len(list(days))
        model.addConstrs(
            (occupancy_pair_vars.sum(occupancy, "*", d)
             == occupancy_vars[(occupancy, d)]
             for occupancy in _FEASIBLE_OCCUPANCIES for d in days),
            name="occ_l_1",
        )

        model.addConstrs(
            (occupancy_pair_vars.sum("*", occupancy, d + 1)
             == occupancy_vars[(occupancy, d + 1)]
             for occupancy in _FEASIBLE_OCCUPANCIES
             for d in days if d + 1 < n_days),
            name="occ_l_2",
        )

        logger.info("Set constraints")

        pref_cost_expr = quicksum(
            assignment_vars[(family.id, family_choice)] * preference_cost(
                family_choice, family.choice_index, family.number_of_members)
            for family in families for family_choice in family.choices)
        accounting_cost_expr = quicksum(
            occupancy_vars.sum(pair[0], pair[1], "*") * cost
            for pair, cost in occupancy_pairs.items())

        model.setObjective(pref_cost_expr + accounting_cost_expr,
                           sense=GRB.MINIMIZE)
        logger.info("Set objective")

        if mip_start:
            for family_id, assigned_day in mip_start.items():
                v = assignment_vars.get((family_id, assigned_day), None)
                if v:
                    v.start = 1

        model.optimize()

        if model.status == GRB.INFEASIBLE:
            model.computeIIS()
            model.write("conflict.lp")
            raise Exception("Infeasible model.")
        else:
            assignments = {
                k[0]: k[1]
                for k, v in assignment_vars.items() if v.X > 0.5
            }
            model.write("sol.sol")
            return Solution.from_assignments(assignments, days, family_index)
Ejemplo n.º 18
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.')
Ejemplo n.º 19
0
    def Build_LDR_Model(self):
        """
        LDR for location-inventpry problem is only feasible when all affine coefficients equal to 0, which violates from
        what we want.
        For more info about how to design a reasonable prepositioning network,
        see: http://web.hec.ca/pages/erick.delage/LRC_TRO.pdf

        The above paper assume support set is a convex polyhedron characterized by linear constraints.
        """
        m, n = self.m, self.n
        f, h = self.f, self.h
        mu, sigma = self.mu, self.sigma
        roads = self.roads
        INF = float('inf')
        f_ks, K = self.ldr_params['f_k'], len(self.ldr_params['f_k'])

        # declare model
        ldr_model = Model()

        # decision variables
        I = ldr_model.addVars(m, vtype=GRB.CONTINUOUS, lb=0.0, name='I')
        Z = ldr_model.addVars(m, vtype=GRB.BINARY, lb=0.0, name='Z')
        t = ldr_model.addVars(n, vtype=GRB.CONTINUOUS, lb=-INF, name='t')
        gamma = ldr_model.addVar(lb=-INF, vtype=GRB.CONTINUOUS, name='gamma')
        s = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=0.0, name='s')
        phi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=0.0, name='phi')
        psi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=-INF, name='psi')
        xi = ldr_model.addVars(K, vtype=GRB.CONTINUOUS, lb=-INF, name='xi')
        eta = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=0.0, name='eta')
        tau = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=-INF, name='tau')
        theta = ldr_model.addVars(n, K, vtype=GRB.CONTINUOUS, lb=-INF, name='theta')
        w = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=0.0, name='w')
        lambd = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=-INF, name='lambda')
        delta = ldr_model.addVars(m, K, vtype=GRB.CONTINUOUS, lb=-INF, name='delta')
        alpha_0 = ldr_model.addVars(roads, vtype=GRB.CONTINUOUS, lb=-INF, name='alpha_0')
        alpha = ldr_model.addVars(roads, n, vtype=GRB.CONTINUOUS, lb=-INF, name='alpha')
        beta = ldr_model.addVars(roads, K, vtype=GRB.CONTINUOUS, lb=-INF, name='beta')

        # objective function
        obj1 = quicksum([f[i]*Z[i] for i in range(m)])
        obj2 = quicksum([h[i]*I[i] for i in range(m)])
        obj3 = quicksum([mu[i]*t[i] for i in range(m)])
        obj4 = quicksum(s[k]*matmul(matmul(f_k, sigma), f_k) for k, f_k in enumerate(f_ks))
        obj5 = gamma
        ldr_model.setObjective(obj1 + obj2 + obj3 + obj4 + obj5)
        ldr_model.modelSense = GRB.MINIMIZE

        # constraint
        # c1
        ldr_model.addConstr(gamma + alpha_0.sum() >= 1/2*(phi.sum() - psi.sum()),
                            name='c1')

        # c2
        ldr_model.addConstrs((1/2*(phi[k]+psi[k]) == beta.sum('*', '*', k) + s[k]*len(roads) for k in range(K)),
                             name='c2')

        # c3
        a_star_star = [alpha.sum('*', '*', l) for l in range(n)]
        ldr_model.addConstrs((xi[k]*f_ks[k][l] <= t[l]+a_star_star[l]-1 for k in range(K) for l in range(n)),
                             name='c3')

        # c4
        ldr_model.addConstrs((-alpha_0.sum('*', j) >= 1/2*(eta.sum(j, '*')-tau.sum(j, '*')) for j in range(n)),
                             name='c4')

        # c5
        ldr_model.addConstrs((-1/2*(eta[j, k]+tau[j, k]) == beta.sum('*', j, k) for k in range(K) for j in range(n)),
                             name='c5')

        # c6
        for j in range(n):
            a_star_j = [alpha.sum('*', j, l) if l != j else alpha.sum('*', j, l)-1 for l in range(n)]
            for k, f_k in enumerate(f_ks):
                ldr_model.addConstrs(-theta[j, k]*f_k[l] >= a_star_j[l] for l in range(n))

        # c7
        ldr_model.addConstrs((I[i]-alpha_0.sum(i, '*') >= 1/2*(w.sum(i, '*')-lambd.sum(i, '*')) for i in range(m)),
                             name='c7')

        # c8
        ldr_model.addConstrs((-1/2*(w[i, k]+lambd[i, k]) == beta.sum(i, '*', k) for i in range(m) for k in range(K)),
                             name='c8')

        # c9
        for i in range(m):
            a_i_star = [alpha.sum(i, '*', l) for l in range(n)]
            for k, f_k in enumerate(f_ks):
                ldr_model.addConstrs(-delta[i, k]*f_k[l] >= a_i_star[l] for l in range(n))

        # c10 I,Z
        ldr_model.addConstrs(I[i] <= 10000*Z[i] for i in range(m))

        # c11
        ldr_model.addConstrs(phi[k]*phi[k] >= psi[k]*psi[k] + xi[k]*xi[k] for k in range(K))
        ldr_model.addConstrs(eta[i, k]*eta[i, k] >= tau[i, k]*tau[i, k] + theta[i, k]*theta[i, k]
                             for k in range(K) for i in range(m))
        ldr_model.addConstrs(w[i, k]*w[i, k] >= lambd[i, k]*lambd[i, k] + delta[i, k]*delta[i, k]
                             for k in range(K) for i in range(m))

        # update
        ldr_model.update()
        ldr_model.optimize()
        # print(I)
        # print(Z)
        # print(alpha_0)
        # print(alpha)
        # print(beta)
        # print(ldr_model.ObjVal)
        self.model = ldr_model
Ejemplo n.º 20
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)
Ejemplo n.º 21
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
Ejemplo n.º 22
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
    def __init__(self, supply, agents, gap, restriced=False):
        print ''
        print 'Optimal Solver:'

        self.m = Model("multi-unit-auction")
        self.m.params.LogToConsole = 0
        self.allocation_vars = dict()
        for agent in agents:
            for i in range(1, supply + 1):
                self.allocation_vars[agent.id, i] = self.m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS, name='x_%s_%s' % (agent.id, i))

        self.m.update()

        for agent in agents:
            self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1)), GRB.LESS_EQUAL, 1, name="u_%s" % agent.id)
            if restriced:
                for valuation in agent.valuations:
                    if valuation.valuation > 0:
                        self.m.addConstr(self.allocation_vars[agent.id, valuation.quantity] >= epsilon, name="not_zero_%s_%s" % (agent.id, valuation.quantity))


        self.m.addConstr(quicksum(self.allocation_vars[agent.id, i]*i for i in range(1, supply + 1) for agent in agents), GRB.LESS_EQUAL, supply, name="price")

        obj_expr = LinExpr()
        for agent in agents:
            for valuation in agent.valuations:
                obj_expr.addTerms(valuation.valuation, self.allocation_vars[agent.id, valuation.quantity])
        self.m.setObjective(obj_expr, GRB.MAXIMIZE)

        self.m.update()

        self.m.optimize()
        #
        # for agent in agents:
        #     for i in range(1, supply + 1):
        #         self.allocation_vars[agent.id, i] = self.m.addVar(vtype=GRB.CONTINUOUS, lb=0,
        #                                                           name='x_%s_%s' % (agent.id, i))
        #
        # self.m.update()
        #
        # self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1) for agent in agents),
        #                  GRB.LESS_EQUAL, supply / gap, name="price")
        # for agent in agents:
        #     for i in range(1, supply):
        #         self.m.addConstr(self.allocation_vars[agent.id, i + 1] - self.allocation_vars[agent.id, i],
        #                          GRB.LESS_EQUAL, 0, name="chain_%s_%s" % (agent.id, i))
        #         self.m.addConstr(self.allocation_vars[agent.id, i], GRB.LESS_EQUAL, 1. / gap,
        #                          name="p_%s_%s" % (agent.id, i))
        #     self.m.addConstr(self.allocation_vars[agent.id, supply], GRB.GREATER_EQUAL, 0, name="greater_%s" % agent.id)
        #     self.m.addConstr(self.allocation_vars[agent.id, 1], GRB.LESS_EQUAL, 1. / gap, name="u_%s" % agent.id)
        #
        # # m.addConstr(x11 + 2*x12 + 3*x13 + 4*x14 + x21 + 2*x22 + 3*x23 + 4*x24, GRB.LESS_EQUAL, 4, name="p_an")
        #
        # obj_expr = LinExpr()
        # for agent in agents:
        #     prev_val = None
        #     for valuation in agent.valuations:
        #         try:
        #             prev_val = next(val for val in agent.valuations if val.quantity == valuation.quantity - 1)
        #         except StopIteration:
        #             pass
        #         marginal_value = valuation.valuation - (prev_val.valuation if prev_val else 0)
        #         obj_expr.addTerms(marginal_value, self.allocation_vars[agent.id, valuation.quantity])
        # self.m.setObjective(obj_expr, GRB.MAXIMIZE)
        #
        # self.m.optimize()

        for v in [v for v in self.m.getVars() if v.x != 0.]:
            print('%s %g' % (v.varName, v.x))

        print ''
        print 'CONSTRAINTS:'

        for l in self.m.getConstrs():
            if l.Pi > 0:
                print('%s %g' % (l.constrName, l.Pi))

        print self.m.getObjective().getValue()

        # print 'Optimal solution:'
        # for v in self.m.getVars():
        #     print('%s %g' % (v.varName, v.x))
        # for l in self.m.getConstrs():
        #     if l.Pi > 0:
        #         print('%s %g' % (l.constrName, l.Pi))
        print 'OPT social welfare %s | %s/%s=%s' % (
        self.m.getObjective().getValue(), self.m.getObjective().getValue(), gap,
        self.m.getObjective().getValue() / gap)

        self.m.write('optimal-lp.lp')
        self.m.write('optimal-lp.sol')
Ejemplo n.º 24
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'
        ]
Ejemplo n.º 25
0
 def addCover(self, indices: list, rhs: int):
     self.m.addConstr(
         quicksum([self.x[indices[i]] for i in range(len(indices))]) <= rhs)
Ejemplo n.º 26
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'
            ]
Ejemplo n.º 27
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)
Ejemplo n.º 28
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'
        ]