Beispiel #1
0
def test_tsp_mipstart(solver: str):
    """tsp related tests"""
    N = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    n = len(N)
    i0 = N[0]

    A = {
        ('a', 'd'): 56,
        ('d', 'a'): 67,
        ('a', 'b'): 49,
        ('b', 'a'): 50,
        ('d', 'b'): 39,
        ('b', 'd'): 37,
        ('c', 'f'): 35,
        ('f', 'c'): 35,
        ('g', 'b'): 35,
        ('b', 'g'): 25,
        ('a', 'c'): 80,
        ('c', 'a'): 99,
        ('e', 'f'): 20,
        ('f', 'e'): 20,
        ('g', 'e'): 38,
        ('e', 'g'): 49,
        ('g', 'f'): 37,
        ('f', 'g'): 32,
        ('b', 'e'): 21,
        ('e', 'b'): 30,
        ('a', 'g'): 47,
        ('g', 'a'): 68,
        ('d', 'c'): 37,
        ('c', 'd'): 52,
        ('d', 'e'): 15,
        ('e', 'd'): 20
    }

    # input and output arcs per node
    Aout = {n: [a for a in A if a[0] == n] for n in N}
    Ain = {n: [a for a in A if a[1] == n] for n in N}
    m = Model(solver_name=solver)
    m.verbose = 0

    x = {
        a: m.add_var(name='x({},{})'.format(a[0], a[1]), var_type=BINARY)
        for a in A
    }

    m.objective = xsum(c * x[a] for a, c in A.items())

    for i in N:
        m += xsum(x[a] for a in Aout[i]) == 1, 'out({})'.format(i)
        m += xsum(x[a] for a in Ain[i]) == 1, 'in({})'.format(i)

    # continuous variable to prevent subtours: each
    # city will have a different "identifier" in the planned route
    y = {i: m.add_var(name='y({})'.format(i), lb=0.0) for i in N}

    # subtour elimination
    for (i, j) in A:
        if i0 not in [i, j]:
            m.add_constr(y[i] - (n + 1) * x[(i, j)] >= y[j] - n)

    route = ['a', 'g', 'f', 'c', 'd', 'e', 'b', 'a']
    m.start = [(x[route[i - 1], route[i]], 1.0) for i in range(1, len(route))]
    m.optimize()

    assert m.status == OptimizationStatus.OPTIMAL
    assert abs(m.objective_value - 262) <= TOL
Beispiel #2
0
         (38.15, 15.35), (37.51, 15.17), (35.49, 14.32), (39.36, 19.56),
         (38.09, 24.36), (36.09, 23.00), (40.44, 13.57), (40.33, 14.15),
         (40.37, 14.23), (37.57, 22.56)]

# latitude and longitude
coord = [(rad(x), rad(y)) for (x, y) in coord]

# distances in an upper triangular matrix

# number of nodes and list of vertices
n, V = len(coord), set(range(len(coord)))

# distances matrix
c = [[0 if i == j else dist(coord[i], coord[j]) for j in V] for i in V]

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = [[model.add_var(var_type=BINARY) for j in V] for i in V]

# objective function: minimize the distance
model.objective = minimize(xsum(c[i][j] * x[i][j] for i in V for j in V))

# constraint : leave each city only once
for i in V:
    model += xsum(x[i][j] for j in V - {i}) == 1

# constraint : enter each city only once
for i in V:
    model += xsum(x[j][i] for j in V - {i}) == 1
Beispiel #3
0
def fl_mip_solver(input_data):
    # Modify this code to run your optimization algorithm

    # parse the input
    lines = input_data.split('\n')

    parts = lines[0].split()
    facility_count = int(parts[0])
    customer_count = int(parts[1])
    
    facilities = []
    for i in range(1, facility_count+1):
        parts = lines[i].split()
        facilities.append(Facility(i-1, float(parts[0]), int(parts[1]), Point(float(parts[2]), float(parts[3])) ))

    customers = []
    for i in range(facility_count+1, facility_count+1+customer_count):
        parts = lines[i].split()
        customers.append(Customer(i-1-facility_count, int(parts[0]), Point(float(parts[1]), float(parts[2]))))
    
    print('F count:',facility_count)
    print('C count:',customer_count)
    
    # instantiates setup cost vector
    set_cost = [f.setup_cost for f in facilities]
    
    # instantiates proportional capacity matrix such that Cap[i,j] represents the demand of 
    # customer 'j' as a fraction of the total capacity of facility 'i'
    Cap = [[c.demand/f.capacity  for c in customers] for f in facilities]
    
    # instantiates distance matrix in such a way that "sum_{j \in M} D[i,j]*at[i,j]" is the total
    # distance cost for facility 'i'
    D = [[length(c.location, f.location)  for c in customers] for f in facilities]
    
    # declares MIP model
    #m = Model(solver_name=CBC)
    m = Model(solver_name='GRB')
    print('-Model instatiated!',datetime.datetime.now())
    
    # states search emphasis
    #     - '0' (default) balanced approach
    #     - '1' (feasibility) aggressively searches for feasible solutions
    #     - '2' (optimality) explores search space to tighten dual gap
    m.emphasis = 2
    
    # whenever the distance of the lower and upper bounds is less or 
    # equal max_gap*100%, the search can be finished
    m.max_gap = 0.05
    
    # specifies number of used threads
    # 0 uses solver default configuration, 
    # -1 uses the number of available processing cores 
    # ≥1 uses the specified number of threads. 
    # An increased number of threads may improve the solution time but also increases 
    # the memory consumption. Each thread needs to store a different model instance!
    m.threads = -1
    
    
    # controls the generation of cutting planes
    # cutting planes usually improve the LP relaxation bound but also make the solution time of the LP relaxation larger
    # -1 means automatic
    #  0 disables completely
    #  1 (default) generates cutting planes in a moderate way
    #  2 generates cutting planes aggressively
    #  3 generates even more cutting planes
    m.cuts=-1

    m.preprocess=1
    m.pump_passes=10
    m.sol_pool_size=1

    # instantiates open facilities variables
    op = [m.add_var(name="op{}".format(i),var_type='B') for i in range(facility_count)]
    
    # instantiates matrix of atribution variables 
    # (line 'i' is an atribution vector for facility 'i')
    # e.g.: At[3][4] returns whether customer 4 is assigned to facility 3
    At = [[m.add_var(name="At{},{}".format(i,j) ,var_type='B') for j in range(customer_count)] 
          for i in range(facility_count)]
    
    print('-Variables declared!',datetime.datetime.now())
    
    # instantiates objective function
    # m.objective = minimize("setup costs" + "distance costs")
    # Form example:
    # m.objective = minimize(
    # xsum(dist[i, j] * x[i, j] for (i, j) in product(F, C)) + xsum(y[i] for i in F) )
    
    m.objective = minimize(
        xsum(set_cost[i]*op[i] for i in range(facility_count)) +
        xsum(sum(D[i][j]*At[i][j] for j in range(customer_count)) for i in range(facility_count)) 
            )
    
    print('-Objective declared!',datetime.datetime.now())
    
    # instatiates capacity constraints
    #     -can be expressed as "sum_{j \in M} Cap[i,j]*At[i,j] <= op[i]" for all facilities 'i'
    #     -if a facility is closed (op[i]=0), its effective capacity is 0
    for i in range(facility_count):
        m.add_lazy_constr( xsum(Cap[i][j]*At[i][j] for j in range(customer_count)) <= op[i] )
    
    # instantiates assignment constraints (maximum of 1 facility per customer)
    #     -can be expressed as: "sum of elements over of each column of 'At' == 1"     
    for i in range(customer_count):
        m += xsum(At[j][i] for j in range(facility_count)) == 1 
    
    print('-Contraints processed!',datetime.datetime.now())
    
    #Maximum time in seconds that the search can go on if a feasible solution 
    #is available and it is not being improved
    mssi = 1000 #default = inf
    # specifies maximum number of nodes to be explored in the search tree (default = inf)
    mn = 40000 #default = 1073741824
    # optimize model m within a processing time limit of 'ms' seconds
    ms = 3000 #default = inf
    
    print('-Optimizer start.',datetime.datetime.now())
    # executes the optimization
    #status = m.optimize(max_seconds = ms,max_seconds_same_incumbent = mssi,max_nodes = mn)
    status = m.optimize(max_seconds = ms , max_seconds_same_incumbent = mssi)
    final_obj = m.objective_value

    print('Opt. Status:',status)
    print('MIP Sol. Obj.:',final_obj)
    print('Dual Bound:',m.objective_bound)
    print('Dual gap:',m.gap)
    
    
    used=[i for i in range(facility_count) if m.vars[i].x==1]

    solution=[None] * customer_count
    for i in range(facility_count):
        for j in range(customer_count):
            if round(m.vars[i*customer_count + j + facility_count].x) == 1:
                solution[j]=i
    # parse output varibles and convert to conventional solution output format
    
    # calculate the cost of the solution
    obj = sum([facilities[f].setup_cost for f in used])
    
    for customer in customers:
        obj += length(customer.location, facilities[solution[customer.index]].location)

    if status == OptimizationStatus.OPTIMAL:
    	# prepare the solution in the specified output format
    	output_data = '%.2f' % obj + ' ' + str(1) + '\n'
    	output_data += ' '.join(map(str, solution))
    elif status == OptimizationStatus.FEASIBLE:
    	output_data = '%.2f' % obj + ' ' + str(0) + '\n'
    	output_data += ' '.join(map(str, solution))
    
    return output_data
Beispiel #4
0
class AP:
    """
    指派问题求解。

    """
    ap_model = None  # 模型
    dec_vars = None  # decision variable 决策变量
    is_init = False  # 是否初始化
    opt_status = None  # 求解状态

    def __init__(self, profit_matrix: List[int]):
        """
        初始化
        """
        self.profit_matrix = profit_matrix

    def init_model(self):
        # 1. 选择求解器初始化
        self.ap_model = Model(sense=MINIMIZE, solver_name=CBC)
        # 2. 定义决策变量
        self.dec_vars = [[
            self.ap_model.add_var(var_type=BINARY)
            for i in range(len(self.profit_matrix))
        ] for j in range(len(self.profit_matrix))]
        # 3. 定义目标函数
        self.ap_model.objective = minimize(
            xsum(self.dec_vars[i][j] * self.profit_matrix[i][j]
                 for i in range(len(self.profit_matrix))
                 for j in range(len(self.profit_matrix))))
        # 4. 定义约束条件
        for i in range(len(self.profit_matrix)):  # 每行只能有一个1
            self.ap_model.add_constr(
                xsum(self.dec_vars[i][j]
                     for j in range(len(self.profit_matrix))) == 1)
        for j in range(len(self.profit_matrix)):  # 每列只能有一个1
            self.ap_model.add_constr(
                xsum(self.dec_vars[i][j]
                     for i in range(len(self.profit_matrix))) == 1)
        self.is_init = True

    def solve(self, max_seconds: int = 10):
        """
        设定约束时间开始求解
        :param max_seconds:
        :return:
        """
        if not self.is_init:
            self.init_model()
        self.opt_status = self.ap_model.optimize(max_seconds=max_seconds)
        return self.opt_status

    def get_optimum_val(self):
        """
        获取最优解值
        :return:
        """
        if self.opt_status and self.opt_status == OptimizationStatus.OPTIMAL:
            return self.ap_model.objective_value
        else:
            raise Exception('未求得解')

    def get_optimum_sol(self):
        """
        获取最优解变量
        :return:
        """
        if self.opt_status and self.opt_status == OptimizationStatus.OPTIMAL:
            return self.dec_vars
        else:
            raise Exception('未求得解')
Beispiel #5
0
                        return
        for cut in cp.cuts:
            model += cut


n = 30  # number of points
V = set(range(n))
seed(0)
p = [(randint(1, 100), randint(1, 100)) for i in V]  # coordinates
Arcs = [(i, j) for (i, j) in product(V, V) if i != j]

# distance matrix
c = [[round(sqrt((p[i][0] - p[j][0])**2 + (p[i][1] - p[j][1])**2)) for j in V]
     for i in V]

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = [[model.add_var(var_type=BINARY) for j in V] for i in V]

# continuous variable to prevent subtours: each city will have a
# different sequential id in the planned route except the first one
y = [model.add_var() for i in V]

# objective function: minimize the distance
model.objective = minimize(xsum(c[i][j] * x[i][j] for (i, j) in Arcs))

# constraint : leave each city only once
for i in V:
    model += xsum(x[i][j] for j in V - {i}) == 1
Beispiel #6
0
class LP_RCPSP(MilpSolver):
    def __init__(self, rcpsp_model: SingleModeRCPSPModel,
                 lp_solver=LP_RCPSP_Solver.CBC,
                 params_objective_function: ParamsObjectiveFunction=None, **kwargs):
        self.rcpsp_model = rcpsp_model
        self.model: Model = None
        self.lp_solver = CBC
        if lp_solver == LP_RCPSP_Solver.GRB:
            self.lp_solver = GRB
        elif lp_solver == LP_RCPSP_Solver.CBC:
            self.lp_solver = CBC
        self.variable_decision = {}
        self.constraints_dict = {}
        self.constraints_dict["lns"] = []
        self.aggreg_from_sol, self.aggreg_dict, self.params_objective_function = \
            build_aggreg_function_and_params_objective(problem=self.rcpsp_model,
                                                       params_objective_function=
                                                       params_objective_function)
        # self.description_variable_description = {}
        # self.description_constraint = {}

    def init_model(self,  **args):
        greedy_start = args.get("greedy_start", True)
        start_solution = args.get("start_solution", None)
        verbose = args.get("verbose", False)
        if start_solution is None:
            if greedy_start:
                if verbose:
                    print("Computing greedy solution")
                greedy_solver = PileSolverRCPSP(self.rcpsp_model)
                store_solution = greedy_solver.solve(greedy_choice=GreedyChoice.MOST_SUCCESSORS)
                self.start_solution = store_solution.get_best_solution_fit()[0]
                makespan = self.rcpsp_model.evaluate(self.start_solution)["makespan"]
            else:
                if verbose:
                    print("Get dummy solution")
                solution = self.rcpsp_model.get_dummy_solution()
                self.start_solution = solution
                makespan = self.rcpsp_model.evaluate(solution)["makespan"]
        else:
            self.start_solution = start_solution
            makespan = self.rcpsp_model.evaluate(start_solution)["makespan"]
        # p = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0]
        sorted_tasks = sorted(self.rcpsp_model.mode_details.keys())
        print(sorted_tasks)
        p = [int(self.rcpsp_model.mode_details[key][1]['duration'])
             for key in sorted_tasks]
        # print('p:', p)

        # u = [[0, 0], [5, 1], [0, 4], [1, 4], [1, 3], [3, 2], [3, 1], [2, 4],
        #      [4, 0], [5, 2], [2, 5], [0, 0]]
        u = []
        for task in sorted_tasks:
            tmp = []
            for r in self.rcpsp_model.resources.keys():
                tmp.append(self.rcpsp_model.mode_details[task][1][r])
            u.append(tmp)
        # print('u: ', u)

        # c = [6, 8]
        c = [x for x in self.rcpsp_model.resources.values()]
        # print('c: ', c)

        # S = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6],
        #      [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11], [10, 11]]
        S = []
        print('successors: ', self.rcpsp_model.successors)
        for task in sorted_tasks:
            for suc in self.rcpsp_model.successors[task]:
                S.append([task-1, suc-1])
        # print('S: ', S)
        (R, self.J, self.T) = (range(len(c)), range(len(p)), range(sum(p)))
        # we have a better self.T to limit the number of variables :
        self.T = range(int(makespan+1))
        # model = Model()
        self.model = Model(sense=MINIMIZE,
                           solver_name=self.lp_solver)

        self.x: List[List[Var]] = [[self.model.add_var(name="x({},{})".format(j, t),
                                                       var_type=BINARY) for t in self.T]
                                   for j in self.J]

        self.model.objective = xsum(self.x[len(self.J) - 1][t] * t for t in self.T)

        for j in self.J:
            self.model += xsum(self.x[j][t] for t in self.T) == 1

        for (r, t) in product(R, self.T):
            self.model += (
                    xsum(u[j][r] * self.x[j][t2] for j in self.J for t2 in range(max(0, t - p[j] + 1), t + 1))
                    <= c[r])

        for (j, s) in S:
            self.model += xsum(t * self.x[s][t] - t * self.x[j][t] for t in self.T) >= p[j]
        start = []
        for j in self.J:
            for t in self.T:
                if self.start_solution.rcpsp_schedule[j+1]["start_time"] == t:
                    start += [(self.x[j][t], 1)]
                else:
                    start += [(self.x[j][t], 0)]

        self.model.start = start
        p_s: Union[PartialSolution, None] = args.get("partial_solution", None)
        self.constraints_partial_solutions = []
        if p_s is not None:
            constraints = []
            if p_s.start_times is not None:
                for task in p_s.start_times:
                    constraints += [self.model.add_constr(xsum([j*self.x[task-1][j]
                                                                for j in range(len(self.x[task-1]))]) == p_s.start_times[task])]
                    constraints += [self.model.add_constr(self.x[task-1][p_s.start_times[task]] == 1)]

            if p_s.partial_permutation is not None:
                for t1, t2 in zip(p_s.partial_permutation[:-1], p_s.partial_permutation[1:]):
                    constraints += [self.model.add_constr(xsum([t * self.x[t1-1][t]-t*self.x[t2-1][t]
                                                                for t in self.T]) <= 0)]
            if p_s.list_partial_order is not None:
                for l in p_s.list_partial_order:
                    for t1, t2 in zip(l[:-1], l[1:]):
                        constraints += [self.model.add_constr(xsum([t * self.x[t1-1][t]-t*self.x[t2-1][t]
                                                                   for t in self.T]) <= 0)]
            self.starts = {}
            for j in range(len(self.x)):
                self.starts[j] = self.model.add_var(name="start_" + str(j),
                                                    lb=0, ub=makespan)
                self.model.add_constr(xsum(t * self.x[j][t] for t in self.T) == self.starts[j])
            if p_s.start_at_end is not None:
                for i, j in p_s.start_at_end:
                    constraints += [self.model.add_constr(self.starts[j-1] == self.starts[i-1]+p[i-1])]
            if p_s.start_together is not None:
                for i, j in p_s.start_together:
                    constraints += [self.model.add_constr(self.starts[j-1] == self.starts[i-1])]
            if p_s.start_after_nunit is not None:
                for t1, t2, delta in p_s.start_after_nunit:
                    constraints += [self.model.add_constr(self.starts[t2-1] >= self.starts[t1-1]+delta)]
            if p_s.start_at_end_plus_offset is not None:
                for t1, t2, delta in p_s.start_at_end_plus_offset:
                    constraints += [self.model.add_constr(self.starts[t2-1] >= self.starts[t1-1]+delta+p[t1-1])]
            self.constraints_partial_solutions = constraints

    def retrieve_solutions(self, parameters_milp: ParametersMilp) -> ResultStorage:
        retrieve_all_solution = parameters_milp.retrieve_all_solution
        nb_solutions_max = parameters_milp.n_solutions_max
        nb_solution = min(nb_solutions_max, self.model.num_solutions)
        if not retrieve_all_solution:
            nb_solution = 1
        list_solution_fits = []
        print(nb_solution, " solutions found")
        for s in range(nb_solution):
            rcpsp_schedule = {}
            objective = self.model.objective_values[s]
            for (j, t) in product(self.J, self.T):
                value = self.x[j][t].xi(s)
                if value >= 0.5:
                    rcpsp_schedule[j + 1] = {'start_time': t,
                                             'end_time': t + self.rcpsp_model.mode_details[j + 1][1]['duration']}
            print("Size schedule : ", len(rcpsp_schedule.keys()))
            try:
                solution = RCPSPSolution(problem=self.rcpsp_model,
                                         rcpsp_schedule=rcpsp_schedule,
                                         rcpsp_schedule_feasible=True)
                fit = self.aggreg_from_sol(solution)
                list_solution_fits += [(solution, fit)]
            except:
                print("Problem =", rcpsp_schedule, len(rcpsp_schedule))
                pass
        return ResultStorage(list_solution_fits=list_solution_fits,
                             best_solution=min(list_solution_fits,
                                               key=lambda x: x[1])[0],
                             mode_optim=self.params_objective_function.sense_function)

    def solve(self, parameters_milp: ParametersMilp=ParametersMilp.default(), **kwargs)->ResultStorage:
        if self.model is None:
            self.init_model()
        limit_time_s = parameters_milp.TimeLimit
        self.model.sol_pool_size = parameters_milp.PoolSolutions
        self.model.max_mip_gap_abs = parameters_milp.MIPGapAbs
        self.model.max_mip_gap = parameters_milp.MIPGap
        self.model.optimize(max_seconds=limit_time_s,
                            max_solutions=parameters_milp.n_solutions_max)
        return self.retrieve_solutions(parameters_milp)
Beispiel #7
0
#Spyder (Python) - Code C023
""" MIP package """
from mip import Model, MINIMIZE

model = Model("dual", MINIMIZE)
x1 = model.add_var()
x2 = model.add_var()
x3 = model.add_var()
model += 5 * x1 + x2 + 4 * x3
model += x1 + x2 >= 1
model += x1 - x2 + x3 >= 2
model += x1 >= 0
model += x2 >= 0
model += x3 >= 0
model.optimize()
print("x1 = {x1.x}, x2= {x2.x}, x3= {x3.x}".format(**locals()))
Beispiel #8
0
         [123, 77, 81, 71, 91, 72, 64, 24, 62, 63],
         [51, 114, 72, 54, 69, 139, 105, 155, 62],
         [70, 25, 22, 52, 90, 56, 105, 16], [45, 61, 111, 36, 61, 57, 70],
         [23, 71, 67, 48, 85, 29], [74, 89, 69, 107, 36], [117, 65, 125, 43],
         [54, 22, 84], [60, 44], [97], []]

# number of nodes and list of vertices
n, V = len(dists), range(len(dists))

# distances matrix
c = [[
    0 if i == j else dists[i][j - i - 1] if j > i else dists[j][i - j - 1]
    for j in V
] for i in V]

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = [[model.add_var(var_type=BINARY) for j in V] for i in V]

# continuous variable to prevent subtours: each city will have a
# different sequential id in the planned route except the first one
y = [model.add_var() for i in V]

# objective function: minimize the distance
model.objective = minimize(xsum(c[i][j] * x[i][j] for i in V for j in V))

# constraint : leave each city only once
for i in V:
    model += xsum(x[i][j] for j in set(V) - {i}) == 1
Beispiel #9
0
def test_mip_file(solver: str, instance: str):
    """Tests optimization of MIP models stored in .mps or .lp files"""
    m = Model(solver_name=solver)

    # optional file for optimal LP basis
    bas_file = ""

    iname = ""
    for ext in EXTS:
        if instance.endswith(ext):
            bas_file = instance.replace(ext, ".bas")
            if not exists(bas_file):
                bas_file = ""
            iname = basename(instance.replace(ext, ""))
            break
    assert iname in BOUNDS.keys()

    lb = BOUNDS[iname][0]
    ub = BOUNDS[iname][1]
    assert lb <= ub + TOL
    has_opt = abs(ub - lb) <= TOL

    max_dif = max(max(abs(ub), abs(lb)) * 0.01, TOL)

    m.read(instance)
    if bas_file:
        m.verbose = True
        m.read(bas_file)
        m.optimize(relax=True)
        print("Basis loaded!!! Obj value: %f" % m.objective_value)
    m.optimize(max_nodes=MAX_NODES)
    if m.status in [OptimizationStatus.OPTIMAL, OptimizationStatus.FEASIBLE]:
        assert m.num_solutions >= 1
        m.check_optimization_results()
        assert m.objective_value >= lb - max_dif
        if has_opt and m.status == OptimizationStatus.OPTIMAL:
            assert abs(m.objective_value - ub) <= max_dif

    elif m.status == OptimizationStatus.NO_SOLUTION_FOUND:
        assert m.objective_bound <= ub + max_dif
    else:
        assert m.status not in [
            OptimizationStatus.INFEASIBLE,
            OptimizationStatus.INT_INFEASIBLE,
            OptimizationStatus.UNBOUNDED,
            OptimizationStatus.ERROR,
            OptimizationStatus.CUTOFF,
        ]
    assert m.objective_bound <= ub + max_dif
Beispiel #10
0
def mip_solver(input_data):
    # Modify this code to run your optimization algorithm

    # parse the input
    lines = input_data.split('\n')

    firstLine = lines[0].split()
    item_count = int(firstLine[0])
    capacity = int(firstLine[1])

    items = []

    for i in range(1, item_count+1):
        line = lines[i]
        parts = line.split()
        items.append(Item(i-1, int(parts[0]), int(parts[1])))

    # a trivial algorithm for filling the knapsack
    # it takes items in-order until the knapsack is full
    value = 0
    weight = 0
    taken = [0]*len(items)
    
    # declare value vector
    val_vec = [item.value for item in items]
    
    # declare weight vector scaled by capacity
    wgt_vec = [item.weight/capacity for item in items]
    
    # start MIP solver
    m = Model(solver_name='GRB')
    print('-Model instatiated!',datetime.datetime.now())
    
    # states search emphasis
    #     - '0' (default) balanced approach
    #     - '1' (feasibility) aggressively searches for feasible solutions
    #     - '2' (optimality) explores search space to tighten dual gap
    m.emphasis = 2
    
    # whenever the distance of the lower and upper bounds is less or 
    # equal max_gap*100%, the search can be finished
    m.max_gap = 0.05
    
    # specifies number of used threads
    # 0 uses solver default configuration, 
    # -1 uses the number of available processing cores 
    # ≥1 uses the specified number of threads. 
    # An increased number of threads may improve the solution time but also increases 
    # the memory consumption. Each thread needs to store a different model instance!
    m.threads = -1
    
    
    # controls the generation of cutting planes
    # cutting planes usually improve the LP relaxation bound but also make the solution time of the LP relaxation larger
    # -1 means automatic
    #  0 disables completely
    #  1 (default) generates cutting planes in a moderate way
    #  2 generates cutting planes aggressively
    #  3 generates even more cutting planes
    m.cuts=-1

    m.preprocess=1
    m.pump_passes=10
    m.sol_pool_size=1
    
    # instantiates taken items variable vector
    taken = [m.add_var(name="it{}".format(i),var_type='B') for i in range(item_count)]
    print('-Variables declared!',datetime.datetime.now())
    
    # instantiates objective function
    m.objective = maximize( xsum( val_vec[i]*taken[i] for i in range(item_count) ) )
    print('-Objective declared!',datetime.datetime.now())
    
    m.add_constr( xsum( wgt_vec[i]*taken[i] for i in range(item_count)) <=1 )
    print('-Contraints processed!',datetime.datetime.now())
    
    #Maximum time in seconds that the search can go on if a feasible solution 
    #is available and it is not being improved
    mssi = 1000 #default = inf
    # specifies maximum number of nodes to be explored in the search tree (default = inf)
    mn = 40000 #default = 1073741824
    # optimize model m within a processing time limit of 'ms' seconds
    ms = 3000 #default = inf
    
    print('-Optimizer start.',datetime.datetime.now())
    # executes the optimization
    #status = m.optimize(max_seconds = ms,max_seconds_same_incumbent = mssi,max_nodes = mn)
    status = m.optimize(max_seconds = ms , max_seconds_same_incumbent = mssi)
    final_obj = m.objective_value
    
    print('Opt. Status:',status)
    print('MIP Sol. Obj.:',final_obj)
    print('Dual Bound:',m.objective_bound)
    print('Dual gap:',m.gap)
    
    sol = [round(it.x) for it in taken]
    value = int(final_obj)
    
    taken = sol
    # prepare the solution in the specified output format
    if status == OptimizationStatus.OPTIMAL:
        output_data = str(value) + ' ' + str(1) + '\n'
        output_data += ' '.join(map(str, taken))
    elif status == OptimizationStatus.FEASIBLE:
        output_data = str(value) + ' ' + str(0) + '\n'
        output_data += ' '.join(map(str, taken))


    if item_count == 10000:
        output_data=greedy(input_data)

    return output_data
Beispiel #11
0
"""Example where a binary program is created and the conflict graph
is inspected.
"""
from itertools import product
from sys import stdout as out
from mip import Model, BINARY

m = m = Model(solver_name="cbc")

N = range(1, 7)

x = {i: m.add_var(var_type=BINARY, name="x(%d)" % i) for i in N}

m += -3 * x[1] + 4 * x[2] - 5 * x[3] + 6 * x[4] + 7 * x[5] + 8 * x[6] <= 2
m += x[1] + x[2] + x[4] >= 1

cg = m.conflict_graph

for i, v in product(N, range(2)):
    out.write("conflicts for x[%d] == %g : " % (i, v))
    ca = cg.conflicting_assignments(x[i] == v)
    for j in ca[0]:
        out.write("%s == 1  " % j.name)
    for j in ca[1]:
        out.write("%s == 0  " % j.name)

    out.write("\n")

# sanity checks
confs = {(i, v): cg.conflicting_assignments(x[i] == v)
         for (i, v) in product(N, range(2))}
Beispiel #12
0
from mip import Model, xsum, minimize, INTEGER
from os import path
import pandas as pd

model = Model("Diet")
table = path.join(path.dirname(path.abspath(__file__)), 'table.csv')
df = pd.read_csv(table)

# Variables
X = [model.add_var(name=row['name'], var_type=INTEGER, lb=0, ub=row['max_serv']) for i, row in df.iterrows()]

def constraint_vars(attr):
    return (row[attr] * X[i] for i, row in df.iterrows())

#
# Objective function
#
model.objective = minimize(xsum(constraint_vars('price')))

#
# Constraints
#

# Energy
model += xsum(constraint_vars('energy')) >= 1000

# Protein
model += xsum(constraint_vars('protein')) >= 55

# Calcium
model += xsum(constraint_vars('calcium')) >= 800
Beispiel #13
0
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Simple column generation implementation for a Cutting Stock Problem
"""

from mip import Model, xsum, Column, CONTINUOUS, INTEGER

L = 250  # bar length
m = 4  # number of requests
w = [187, 119, 74, 90]  # size of each item
b = [1, 2, 2, 1]  # demand for each item

# creating master model
master = Model()

# creating an initial set of patterns which cut one item per bar
# to provide the restricted master problem with a feasible solution
lambdas = [master.add_var(obj=1, name='lambda_%d' % (j + 1)) for j in range(m)]

# creating constraints
constraints = []
for i in range(m):
    constraints.append(
        master.add_constr(lambdas[i] >= b[i], name='i_%d' % (i + 1)))

# creating the pricing problem
pricing = Model()

# creating pricing variables
a = [
Beispiel #14
0
def test_cutting_stock(solver: str):
    n = 10  # maximum number of bars
    L = 250  # bar length
    m = 4  # number of requests
    w = [187, 119, 74, 90]  # size of each item
    b = [1, 2, 2, 1]  # demand for each item

    # creating the model
    model = Model(solver_name=solver)
    x = {(i, j): model.add_var(obj=0,
                               var_type=INTEGER,
                               name="x[%d,%d]" % (i, j))
         for i in range(m) for j in range(n)}
    y = {
        j: model.add_var(obj=1, var_type=BINARY, name="y[%d]" % j)
        for j in range(n)
    }

    # constraints
    for i in range(m):
        model.add_constr(xsum(x[i, j] for j in range(n)) >= b[i])
    for j in range(n):
        model.add_constr(xsum(w[i] * x[i, j] for i in range(m)) <= L * y[j])

    # additional constraints to reduce symmetry
    for j in range(1, n):
        model.add_constr(y[j - 1] >= y[j])

    # optimizing the model
    model.optimize()

    # sanity tests
    assert model.status == OptimizationStatus.OPTIMAL
    assert abs(model.objective_value - 3) <= 1e-4
    assert sum(x.x for x in model.vars) >= 5
Beispiel #15
0
class LP_MRCPSP(MilpSolver):
    def __init__(self,
                 rcpsp_model: MultiModeRCPSPModel,
                 lp_solver=LP_RCPSP_Solver.CBC,
                 params_objective_function: ParamsObjectiveFunction=None, **kwargs):
        self.rcpsp_model = rcpsp_model
        self.model: Model = None
        self.lp_solver = CBC
        if lp_solver == LP_RCPSP_Solver.GRB:
            self.lp_solver = GRB
        elif lp_solver == LP_RCPSP_Solver.CBC:
            self.lp_solver = CBC
        self.variable_decision = {}
        self.constraints_dict = {}
        self.constraints_dict["lns"] = []
        self.aggreg_from_sol, self.aggreg_dict, self.params_objective_function = \
            build_aggreg_function_and_params_objective(problem=self.rcpsp_model,
                                                       params_objective_function=
                                                       params_objective_function)
        # self.description_variable_description = {}
        # self.description_constraint = {}

    def init_model(self,  **args):
        greedy_start = args.get("greedy_start", True)
        start_solution = args.get("start_solution", None)
        verbose = args.get("verbose", False)
        if start_solution is None:
            if greedy_start:
                if verbose:
                    print("Computing greedy solution")
                greedy_solver = PileSolverRCPSP(self.rcpsp_model)
                store_solution = greedy_solver.solve(greedy_choice=GreedyChoice.MOST_SUCCESSORS)
                self.start_solution = store_solution.get_best_solution_fit()[0]
                makespan = self.rcpsp_model.evaluate(self.start_solution)["makespan"]
            else:
                if verbose:
                    print("Get dummy solution")
                solution = self.rcpsp_model.get_dummy_solution()
                self.start_solution = solution
                makespan = self.rcpsp_model.evaluate(solution)["makespan"]
        else:
            self.start_solution = start_solution
            makespan = self.rcpsp_model.evaluate(start_solution)["makespan"]

        # p = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0]
        sorted_tasks = sorted(self.rcpsp_model.mode_details.keys())
        p = [int(max([self.rcpsp_model.mode_details[key][mode]['duration']
                      for mode in self.rcpsp_model.mode_details[key]]))
             for key in sorted_tasks]
        # c = [6, 8]
        c = [x for x in self.rcpsp_model.resources.values()]
        renewable = {r: self.rcpsp_model.resources[r] for r in self.rcpsp_model.resources
                     if r not in self.rcpsp_model.non_renewable_resources}
        non_renewable = {r: self.rcpsp_model.resources[r] for r in self.rcpsp_model.non_renewable_resources}
        # print('c: ', c)
        # S = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6],
        #      [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11], [10, 11]]
        S = []
        print('successors: ', self.rcpsp_model.successors)
        for task in sorted_tasks:
           for suc in self.rcpsp_model.successors[task]:
               S.append([task, suc])
        # print('S: ', S)
        (R, self.J, self.T) = (range(len(c)), range(len(p)), range(sum(p)))
        # we have a better self.T to limit the number of variables :
        if self.start_solution.rcpsp_schedule_feasible:
            self.T = range(int(makespan+1))
        # model = Model()
        self.model = Model(sense=MINIMIZE,
                           solver_name=self.lp_solver)
        self.x: Dict[Var] = {}
        last_task = max(self.rcpsp_model.mode_details.keys())
        variable_per_task = {}
        for task in sorted_tasks:
            if task not in variable_per_task:
                variable_per_task[task] = []
            for mode in self.rcpsp_model.mode_details[task]:
                for t in self.T:
                    self.x[(task, mode, t)] = self.model.add_var(name="x({},{}, {})".format(task, mode, t),
                                                                 var_type=BINARY)
                    variable_per_task[task] += [(task, mode, t)]
        self.model.objective = xsum(self.x[key] * key[2] for key in variable_per_task[last_task])
        for j in variable_per_task:
            self.model += xsum(self.x[key] for key in variable_per_task[j]) == 1

        if isinstance(self.rcpsp_model, RCPSPModelCalendar):
            renewable_quantity = {r: renewable[r] for r in renewable}
        else:
            renewable_quantity = {r: [renewable[r]]*len(self.T) for r in renewable}

        if isinstance(self.rcpsp_model, RCPSPModelCalendar):
            non_renewable_quantity = {r: non_renewable[r] for r in non_renewable}
        else:
            non_renewable_quantity = {r: [non_renewable[r]]*len(self.T) for r in non_renewable}

        for (r, t) in product(renewable, self.T):
            self.model.add_constr(xsum(int(self.rcpsp_model.mode_details[key[0]][key[1]][r]) * self.x[key]
                                  for key in self.x
                                  if key[2] <= t < key[2]+int(self.rcpsp_model.mode_details[key[0]][key[1]]["duration"]))
                                   <= renewable_quantity[r][t])
            print(r, t)
        for r in non_renewable:
            self.model.add_constr(xsum(int(self.rcpsp_model.mode_details[key[0]][key[1]][r]) * self.x[key]
                                       for key in self.x) <= non_renewable_quantity[r][0])
        durations = {j: self.model.add_var(name="duration_"+str(j),
                                           var_type=INTEGER)
                     for j in variable_per_task}
        self.durations = durations
        self.variable_per_task = variable_per_task
        for j in variable_per_task:
            self.model.add_constr(xsum(self.rcpsp_model.mode_details[key[0]][key[1]]["duration"]*self.x[key]
                                       for key in variable_per_task[j]) == durations[j])
        for (j, s) in S:
            self.model.add_constr(xsum([key[2] * self.x[key] for key in variable_per_task[s]]
                                        + [- key[2] * self.x[key]
                                           for key in variable_per_task[j]]) >=
                                       durations[j])

        start = []
        for j in self.start_solution.rcpsp_schedule:
            start_time_j = self.start_solution.rcpsp_schedule[j]["start_time"]
            mode_j = 1 if j == 1 or j == self.rcpsp_model.n_jobs + 2 else self.start_solution.rcpsp_modes[j - 2]
            start += [(self.durations[j], self.rcpsp_model.mode_details[j][mode_j]["duration"])]
            for k in self.variable_per_task[j]:
                task, mode, time = k
                if start_time_j == time and mode == mode_j:
                    start += [(self.x[k], 1)]
                else:
                    start += [(self.x[k], 0)]
        self.model.start = start
        p_s: Union[PartialSolution, None] = args.get("partial_solution", None)
        self.constraints_partial_solutions = []
        if p_s is not None:
            constraints = []
            if p_s.start_times is not None:
                for task in p_s.start_times:
                    constraints += [self.model.add_constr(xsum([self.x[k] for k in self.variable_per_task[task]
                                                                if k[2] == p_s.start_times[task]]) == 1)]
            if p_s.partial_permutation is not None:
                for t1, t2 in zip(p_s.partial_permutation[:-1], p_s.partial_permutation[1:]):
                    constraints += [self.model.add_constr(xsum([key[2] * self.x[key] for key in variable_per_task[t1]]
                                                               + [- key[2] * self.x[key]
                                                                  for key in variable_per_task[t2]]) <= 0)]
            if p_s.list_partial_order is not None:
                for l in p_s.list_partial_order:
                    for t1, t2 in zip(l[:-1], l[1:]):
                        constraints += [self.model.add_constr(xsum([key[2] * self.x[key] for key in variable_per_task[t1]]
                                                               + [- key[2] * self.x[key]
                                                                  for key in variable_per_task[t2]]) <= 0)]
            self.constraints_partial_solutions = constraints
            print('Partial solution constraints : ', self.constraints_partial_solutions)

    def retrieve_solutions(self, parameters_milp: ParametersMilp) -> ResultStorage:
        retrieve_all_solution = parameters_milp.retrieve_all_solution
        nb_solutions_max = parameters_milp.n_solutions_max
        nb_solution = min(nb_solutions_max, self.model.num_solutions)
        if not retrieve_all_solution:
            nb_solution = 1
        list_solution_fits = []
        print(nb_solution, " solutions found")
        for s in range(nb_solution):
            rcpsp_schedule = {}
            modes = {}
            objective = self.model.objective_values[s]
            for (task, mode, t) in self.x:
                value = self.x[(task, mode, t)].xi(s)
                if value >= 0.5:
                    rcpsp_schedule[task] = {'start_time': t,
                                            'end_time': t + self.rcpsp_model.mode_details[task][mode]['duration']}
                    modes[task] = mode
            print("Size schedule : ", len(rcpsp_schedule.keys()))
            try:
                modes.pop(1)
                modes.pop(self.rcpsp_model.n_jobs+2)
                modes_vec = [modes[k] for k in sorted(modes)]
                solution = RCPSPSolution(problem=self.rcpsp_model,
                                         rcpsp_schedule=rcpsp_schedule,
                                         rcpsp_modes=modes_vec,
                                         rcpsp_schedule_feasible=True)
                fit = self.aggreg_from_sol(solution)
                list_solution_fits += [(solution, fit)]
            except:
                pass
        return ResultStorage(list_solution_fits=list_solution_fits,
                             best_solution=min(list_solution_fits,
                                               key=lambda x: x[1])[0],
                             mode_optim=self.params_objective_function.sense_function)

    def solve(self, parameters_milp: ParametersMilp=ParametersMilp.default(), **kwargs)->ResultStorage:
        if self.model is None:
            self.init_model(greedy_start=False, **kwargs)
        limit_time_s = parameters_milp.TimeLimit
        self.model.sol_pool_size = parameters_milp.PoolSolutions
        self.model.max_mip_gap_abs = parameters_milp.MIPGapAbs
        self.model.max_mip_gap = parameters_milp.MIPGap
        self.model.optimize(max_seconds=limit_time_s,
                            max_solutions=parameters_milp.n_solutions_max)
        return self.retrieve_solutions(parameters_milp)
Beispiel #16
0
timeLimit = int(argv[2])
threads = int(argv[3])
useCuts = int(argv[4])
useLazy = int(argv[5])
useHeur = int(argv[6])

start = time()

inst = tsplib95.load_problem(argv[1])
V = [n - 1 for n in inst.get_nodes()]
n, c = len(V), [[0.0 for j in V] for i in V]
for (i, j) in product(V, V):
    if i != j:
        c[i][j] = inst.wfunc(i + 1, j + 1)

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = [[model.add_var(var_type=BINARY, name='x(%d,%d)' % (i, j)) for j in V]
     for i in V]

# continuous variable to prevent subtours: each city will have a
# different sequential id in the planned route except the first one
y = [model.add_var(name='y(%d)' % i) for i in V]

# objective function: minimize the distance
model.objective = minimize(xsum(c[i][j] * x[i][j] for i in V for j in V))

# constraint : leave each city only once
for i in V:
    model += xsum(x[i][j] for j in set(V) - {i}) == 1
Beispiel #17
0
    def init_model(self,  **args):
        greedy_start = args.get("greedy_start", True)
        start_solution = args.get("start_solution", None)
        verbose = args.get("verbose", False)
        if start_solution is None:
            if greedy_start:
                if verbose:
                    print("Computing greedy solution")
                greedy_solver = PileSolverRCPSP(self.rcpsp_model)
                store_solution = greedy_solver.solve(greedy_choice=GreedyChoice.MOST_SUCCESSORS)
                self.start_solution = store_solution.get_best_solution_fit()[0]
                makespan = self.rcpsp_model.evaluate(self.start_solution)["makespan"]
            else:
                if verbose:
                    print("Get dummy solution")
                solution = self.rcpsp_model.get_dummy_solution()
                self.start_solution = solution
                makespan = self.rcpsp_model.evaluate(solution)["makespan"]
        else:
            self.start_solution = start_solution
            makespan = self.rcpsp_model.evaluate(start_solution)["makespan"]

        # p = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0]
        sorted_tasks = sorted(self.rcpsp_model.mode_details.keys())
        p = [int(max([self.rcpsp_model.mode_details[key][mode]['duration']
                      for mode in self.rcpsp_model.mode_details[key]]))
             for key in sorted_tasks]
        # c = [6, 8]
        c = [x for x in self.rcpsp_model.resources.values()]
        renewable = {r: self.rcpsp_model.resources[r] for r in self.rcpsp_model.resources
                     if r not in self.rcpsp_model.non_renewable_resources}
        non_renewable = {r: self.rcpsp_model.resources[r] for r in self.rcpsp_model.non_renewable_resources}
        # print('c: ', c)
        # S = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6],
        #      [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11], [10, 11]]
        S = []
        print('successors: ', self.rcpsp_model.successors)
        for task in sorted_tasks:
           for suc in self.rcpsp_model.successors[task]:
               S.append([task, suc])
        # print('S: ', S)
        (R, self.J, self.T) = (range(len(c)), range(len(p)), range(sum(p)))
        # we have a better self.T to limit the number of variables :
        if self.start_solution.rcpsp_schedule_feasible:
            self.T = range(int(makespan+1))
        # model = Model()
        self.model = Model(sense=MINIMIZE,
                           solver_name=self.lp_solver)
        self.x: Dict[Var] = {}
        last_task = max(self.rcpsp_model.mode_details.keys())
        variable_per_task = {}
        for task in sorted_tasks:
            if task not in variable_per_task:
                variable_per_task[task] = []
            for mode in self.rcpsp_model.mode_details[task]:
                for t in self.T:
                    self.x[(task, mode, t)] = self.model.add_var(name="x({},{}, {})".format(task, mode, t),
                                                                 var_type=BINARY)
                    variable_per_task[task] += [(task, mode, t)]
        self.model.objective = xsum(self.x[key] * key[2] for key in variable_per_task[last_task])
        for j in variable_per_task:
            self.model += xsum(self.x[key] for key in variable_per_task[j]) == 1

        if isinstance(self.rcpsp_model, RCPSPModelCalendar):
            renewable_quantity = {r: renewable[r] for r in renewable}
        else:
            renewable_quantity = {r: [renewable[r]]*len(self.T) for r in renewable}

        if isinstance(self.rcpsp_model, RCPSPModelCalendar):
            non_renewable_quantity = {r: non_renewable[r] for r in non_renewable}
        else:
            non_renewable_quantity = {r: [non_renewable[r]]*len(self.T) for r in non_renewable}

        for (r, t) in product(renewable, self.T):
            self.model.add_constr(xsum(int(self.rcpsp_model.mode_details[key[0]][key[1]][r]) * self.x[key]
                                  for key in self.x
                                  if key[2] <= t < key[2]+int(self.rcpsp_model.mode_details[key[0]][key[1]]["duration"]))
                                   <= renewable_quantity[r][t])
            print(r, t)
        for r in non_renewable:
            self.model.add_constr(xsum(int(self.rcpsp_model.mode_details[key[0]][key[1]][r]) * self.x[key]
                                       for key in self.x) <= non_renewable_quantity[r][0])
        durations = {j: self.model.add_var(name="duration_"+str(j),
                                           var_type=INTEGER)
                     for j in variable_per_task}
        self.durations = durations
        self.variable_per_task = variable_per_task
        for j in variable_per_task:
            self.model.add_constr(xsum(self.rcpsp_model.mode_details[key[0]][key[1]]["duration"]*self.x[key]
                                       for key in variable_per_task[j]) == durations[j])
        for (j, s) in S:
            self.model.add_constr(xsum([key[2] * self.x[key] for key in variable_per_task[s]]
                                        + [- key[2] * self.x[key]
                                           for key in variable_per_task[j]]) >=
                                       durations[j])

        start = []
        for j in self.start_solution.rcpsp_schedule:
            start_time_j = self.start_solution.rcpsp_schedule[j]["start_time"]
            mode_j = 1 if j == 1 or j == self.rcpsp_model.n_jobs + 2 else self.start_solution.rcpsp_modes[j - 2]
            start += [(self.durations[j], self.rcpsp_model.mode_details[j][mode_j]["duration"])]
            for k in self.variable_per_task[j]:
                task, mode, time = k
                if start_time_j == time and mode == mode_j:
                    start += [(self.x[k], 1)]
                else:
                    start += [(self.x[k], 0)]
        self.model.start = start
        p_s: Union[PartialSolution, None] = args.get("partial_solution", None)
        self.constraints_partial_solutions = []
        if p_s is not None:
            constraints = []
            if p_s.start_times is not None:
                for task in p_s.start_times:
                    constraints += [self.model.add_constr(xsum([self.x[k] for k in self.variable_per_task[task]
                                                                if k[2] == p_s.start_times[task]]) == 1)]
            if p_s.partial_permutation is not None:
                for t1, t2 in zip(p_s.partial_permutation[:-1], p_s.partial_permutation[1:]):
                    constraints += [self.model.add_constr(xsum([key[2] * self.x[key] for key in variable_per_task[t1]]
                                                               + [- key[2] * self.x[key]
                                                                  for key in variable_per_task[t2]]) <= 0)]
            if p_s.list_partial_order is not None:
                for l in p_s.list_partial_order:
                    for t1, t2 in zip(l[:-1], l[1:]):
                        constraints += [self.model.add_constr(xsum([key[2] * self.x[key] for key in variable_per_task[t1]]
                                                               + [- key[2] * self.x[key]
                                                                  for key in variable_per_task[t2]]) <= 0)]
            self.constraints_partial_solutions = constraints
            print('Partial solution constraints : ', self.constraints_partial_solutions)
def create_model(graph: DepGraph_sat.DepGraph, obj_parameter_list):

    model = Model()
    for k in graph.depItemDict:
        item = graph.depItemDict[k]
        item.var = model.add_var(var_type=BINARY, name=item.varName)

    for k in graph.depItemDict:
        item = graph.depItemDict[k]
        if item.packageName == 'ROOT':
            model += item.var == 1
        for group in item.depGroups:
            model += xsum(x.var for x in group.items) >= item.var

    packageDict = {}
    for k in graph.depItemDict:
        item = graph.depItemDict[k]
        if item.packageName not in packageDict:
            packageDict[item.packageName] = []
        packageDict[item.packageName].append(item)
    for packageName in packageDict:
        model += xsum(x.var for x in packageDict[packageName]) <= 1

    # 减少直接依赖跨越大版本 developers prefer fewer dependency upgrades/downgrades crossing their major versions
    obj1_item_var_list = []
    for g in graph.depItemDict['ROOT'].depGroups:
        for item in g.items[1:]:
            if major_version(g.items[0].version, item.version) == True:
                obj1_item_var_list.append(item.var)

    ROOT_items_name_lists = ['ROOT']
    for g in graph.depItemDict['ROOT'].depGroups:
        ROOT_items_name_lists.append(g.packageName)

    for k in graph.depItemDict:
        item_k = graph.depItemDict[k]
        if item_k.packageName not in ROOT_items_name_lists:
            model += xsum(
                graph.depItemDict[j].var *
                is_lower_limit(graph.depItemDict[j].depGroups, item_k)
                for j in graph.depItemDict) >= item_k.var

    # 直接依赖相同大版本的个数
    obj1 = xsum(k for k in obj1_item_var_list)

    # 是否为直接依赖及原有版本 Encourage to keep direct dependencies’ versions unchanged
    # # 直接依赖原有版本的个数
    # obj2 = xsum(g.items[0].var for g in graph.depItemDict['ROOT'].depGroups)

    # 直接依赖升级版本的个数
    obj2 = xsum(g_items.var *
                update_version_status(g_items.version, g.items[0].version)
                for g in graph.depItemDict['ROOT'].depGroups
                for g_items in g.items)

    # 直接依赖降级版本的个数
    obj3 = xsum(g_items.var *
                download_version_status(g_items.version, g.items[0].version)
                for g in graph.depItemDict['ROOT'].depGroups
                for g_items in g.items)

    # 减少引入的依赖包 developers prefer to introduce fewer packages in project’s dependency graph
    # 引入包的总个数
    obj4 = xsum(graph.depItemDict[k].var for k in graph.depItemDict)

    new_obj1 = obj_parameter_list[0] * obj1
    new_obj2 = obj_parameter_list[1] * obj2
    new_obj3 = obj_parameter_list[2] * obj3
    new_obj4 = obj_parameter_list[3] * obj4
    model.objective = maximize(new_obj1 - new_obj2 - new_obj3 - new_obj4)
    # model.objective = minimize(new_obj1 - new_obj2 - new_obj3 - new_obj4)

    return model
Beispiel #19
0
    def init_model(self,  **args):
        greedy_start = args.get("greedy_start", True)
        start_solution = args.get("start_solution", None)
        verbose = args.get("verbose", False)
        if start_solution is None:
            if greedy_start:
                if verbose:
                    print("Computing greedy solution")
                greedy_solver = PileSolverRCPSP(self.rcpsp_model)
                store_solution = greedy_solver.solve(greedy_choice=GreedyChoice.MOST_SUCCESSORS)
                self.start_solution = store_solution.get_best_solution_fit()[0]
                makespan = self.rcpsp_model.evaluate(self.start_solution)["makespan"]
            else:
                if verbose:
                    print("Get dummy solution")
                solution = self.rcpsp_model.get_dummy_solution()
                self.start_solution = solution
                makespan = self.rcpsp_model.evaluate(solution)["makespan"]
        else:
            self.start_solution = start_solution
            makespan = self.rcpsp_model.evaluate(start_solution)["makespan"]
        # p = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0]
        sorted_tasks = sorted(self.rcpsp_model.mode_details.keys())
        print(sorted_tasks)
        p = [int(self.rcpsp_model.mode_details[key][1]['duration'])
             for key in sorted_tasks]
        # print('p:', p)

        # u = [[0, 0], [5, 1], [0, 4], [1, 4], [1, 3], [3, 2], [3, 1], [2, 4],
        #      [4, 0], [5, 2], [2, 5], [0, 0]]
        u = []
        for task in sorted_tasks:
            tmp = []
            for r in self.rcpsp_model.resources.keys():
                tmp.append(self.rcpsp_model.mode_details[task][1][r])
            u.append(tmp)
        # print('u: ', u)

        # c = [6, 8]
        c = [x for x in self.rcpsp_model.resources.values()]
        # print('c: ', c)

        # S = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6],
        #      [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11], [10, 11]]
        S = []
        print('successors: ', self.rcpsp_model.successors)
        for task in sorted_tasks:
            for suc in self.rcpsp_model.successors[task]:
                S.append([task-1, suc-1])
        # print('S: ', S)
        (R, self.J, self.T) = (range(len(c)), range(len(p)), range(sum(p)))
        # we have a better self.T to limit the number of variables :
        self.T = range(int(makespan+1))
        # model = Model()
        self.model = Model(sense=MINIMIZE,
                           solver_name=self.lp_solver)

        self.x: List[List[Var]] = [[self.model.add_var(name="x({},{})".format(j, t),
                                                       var_type=BINARY) for t in self.T]
                                   for j in self.J]

        self.model.objective = xsum(self.x[len(self.J) - 1][t] * t for t in self.T)

        for j in self.J:
            self.model += xsum(self.x[j][t] for t in self.T) == 1

        for (r, t) in product(R, self.T):
            self.model += (
                    xsum(u[j][r] * self.x[j][t2] for j in self.J for t2 in range(max(0, t - p[j] + 1), t + 1))
                    <= c[r])

        for (j, s) in S:
            self.model += xsum(t * self.x[s][t] - t * self.x[j][t] for t in self.T) >= p[j]
        start = []
        for j in self.J:
            for t in self.T:
                if self.start_solution.rcpsp_schedule[j+1]["start_time"] == t:
                    start += [(self.x[j][t], 1)]
                else:
                    start += [(self.x[j][t], 0)]

        self.model.start = start
        p_s: Union[PartialSolution, None] = args.get("partial_solution", None)
        self.constraints_partial_solutions = []
        if p_s is not None:
            constraints = []
            if p_s.start_times is not None:
                for task in p_s.start_times:
                    constraints += [self.model.add_constr(xsum([j*self.x[task-1][j]
                                                                for j in range(len(self.x[task-1]))]) == p_s.start_times[task])]
                    constraints += [self.model.add_constr(self.x[task-1][p_s.start_times[task]] == 1)]

            if p_s.partial_permutation is not None:
                for t1, t2 in zip(p_s.partial_permutation[:-1], p_s.partial_permutation[1:]):
                    constraints += [self.model.add_constr(xsum([t * self.x[t1-1][t]-t*self.x[t2-1][t]
                                                                for t in self.T]) <= 0)]
            if p_s.list_partial_order is not None:
                for l in p_s.list_partial_order:
                    for t1, t2 in zip(l[:-1], l[1:]):
                        constraints += [self.model.add_constr(xsum([t * self.x[t1-1][t]-t*self.x[t2-1][t]
                                                                   for t in self.T]) <= 0)]
            self.starts = {}
            for j in range(len(self.x)):
                self.starts[j] = self.model.add_var(name="start_" + str(j),
                                                    lb=0, ub=makespan)
                self.model.add_constr(xsum(t * self.x[j][t] for t in self.T) == self.starts[j])
            if p_s.start_at_end is not None:
                for i, j in p_s.start_at_end:
                    constraints += [self.model.add_constr(self.starts[j-1] == self.starts[i-1]+p[i-1])]
            if p_s.start_together is not None:
                for i, j in p_s.start_together:
                    constraints += [self.model.add_constr(self.starts[j-1] == self.starts[i-1])]
            if p_s.start_after_nunit is not None:
                for t1, t2, delta in p_s.start_after_nunit:
                    constraints += [self.model.add_constr(self.starts[t2-1] >= self.starts[t1-1]+delta)]
            if p_s.start_at_end_plus_offset is not None:
                for t1, t2, delta in p_s.start_at_end_plus_offset:
                    constraints += [self.model.add_constr(self.starts[t2-1] >= self.starts[t1-1]+delta+p[t1-1])]
            self.constraints_partial_solutions = constraints
Beispiel #20
0
places = [([i+1 for i in range(29)])]

# distances in an upper triangular matrix
e = ExampleMatrix()
dists = e.getTriangularMatrix()

# number of nodes and list of vertices
n, V = len(dists), set(range(len(dists)))

# distances matrix
c = [[0 if i == j
      else dists[i][j-i-1] if j > i
      else dists[j][i-j-1]
      for j in V] for i in V]

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = [[model.add_var(var_type=BINARY) for j in V] for i in V]

# continuous variable to prevent subtours: each city will have a
# different sequential id in the planned route except the first one
y = [model.add_var() for i in V]

# objective function: minimize the distance
model.objective = minimize(xsum(c[i][j]*x[i][j] for i in V for j in V))

# constraint : leave each city only once
for i in V:
    model += xsum(x[i][j] for j in V - {i}) == 1
    def optimize_operation_HWHS(self,
                                number=96,
                                tank_size=3000,
                                ele_capacity=14,
                                save=False,
                                linearization=False,
                                objective=0,
                                *args,
                                **kwargs):
        '''Operational optimization with regard to different objective function.

        :param file:
        :param linearization: True or false
        :param number: determine the time interval
        :param tank_size: kg
        :param ele_capacity: MW
        :param save: save excel or not? Bool
        :param objective: 0 for maximal profits
        :param args: reserved
        :param kwargs: a dictionary containing random variables.
        :return:
        '''
        p_w_t = kwargs['wind_power']
        pi_t = kwargs['price']
        p_l_t = kwargs['power_load']
        m_l_h2_t = kwargs['hydrogen_load']

        # marginal cost
        C_m_ele = 20.5 / 2 * 18 * 0.063 * 0.13  # Euros/MWh 1MWh electricity->20.5kg H2 ->
        # 20.5/2 kmol H2 -> 20.5/2 kmol H2O -> 20.5/2*18 kg H2O -> 0.063DKK/kg H2O
        C_m_comp = 3600 / 3.221 * 0.004

        h2_price = 2
        '''
        In fact, we need to do linearization every time when we start a new optimization, which means a new supper limit.
        However, it is very time-consuming, so I decide to do it at only one point to accelerate calculation.
        '''
        if linearization == True:
            self.ele_breaks[-1] = 20
            self.ele_f_breaks[-1] = self.k3_e * 20 + self.b3_e

            self.con_breaks[-1] = 20
            self.con_f_breaks[-1] = self.k3_c * 20 + self.b3_c
        '''
        According to "Hydrogen Station Compression, Storage, and Dispensing Technical Status and Costs: Systems Integration", 
        compressor that impoves hydrogen pressure to 350bar gives an additional cost to hydrogen as $0.14/kg, provided the
        electricity cost is 1.6kWh/kg and power price is $0.085/kWh. Thus it can be infered that the addtional cost without
        electricity payment is 0.14-0.085*1.6 = 0.004$/kg

        '''
        # define MILP model
        if objective == 0 or objective == 1:
            GLS_milp_model = Model('GLS', sense=MAXIMIZE)
        else:
            GLS_milp_model = Model('GLS', sense=MINIMIZE)

        # ------------------------------------------ADD VARIABLES--------------------------------------

        power_utility = [
            GLS_milp_model.add_var(lb=-100, ub=100, var_type='C')
            for i in range(number)
        ]
        hydrogen_level = [
            GLS_milp_model.add_var(lb=0, ub=tank_size, var_type='C')
            for i in range(number)
        ]  # kg
        power_ele = [
            GLS_milp_model.add_var(lb=0, ub=ele_capacity, var_type='C')
            for i in range(number)
        ]
        power_comp = [
            GLS_milp_model.add_var(lb=0, ub=100, var_type='C')
            for i in range(number)
        ]
        power_converter = [
            GLS_milp_model.add_var(lb=0, ub=100, var_type='C')
            for i in range(number)
        ]

        # variables that are only used in objective one. We need a new variable to indicate green hydrogen
        power_ele_g = [
            GLS_milp_model.add_var(lb=0, ub=ele_capacity, var_type='C')
            for _ in range(number)
        ]

        if linearization == True:
            # Indicating which piece the electrolyser power falls in
            ele_z = []
            for i in range(3):
                ele_z.append([
                    GLS_milp_model.add_var(var_type='B') for _ in range(number)
                ])

            # weight
            ele_w = []
            for i in range(4):
                ele_w.append([
                    GLS_milp_model.add_var(lb=0, var_type='C')
                    for _ in range(number)
                ])

            # Indicating which piece the converter input power falls in
            con_z = []
            for i in range(3):
                con_z.append([
                    GLS_milp_model.add_var(var_type='B') for _ in range(number)
                ])

            # weight
            con_w = []
            for i in range(4):
                con_w.append([
                    GLS_milp_model.add_var(lb=0, var_type='C')
                    for _ in range(number)
                ])

        # ------------------------------------OBJECTIVE FUNCTION-----------------------------------

        Mh2_ini = 1000  # initial amount of hydrogen stored in the tank

        if objective == 0:  # Maxmize the profits
            GLS_milp_model.objective = xsum(
                (power_utility[i] * pi_t[i] + p_l_t[i] * pi_t[i] +
                 m_l_h2_t[i] * h2_price - power_ele[i] * C_m_ele -
                 power_comp[i] * C_m_comp) * self.time_span
                for i in range(number))
        elif objective == 1:  # Maxmize percentage of green hydrogen

            GLS_milp_model.objective = xsum(
                power_ele_g[i] * 20.5 for i in range(number)) / sum(m_l_h2_t)

        elif objective == 2:  # Maxmize efficiency
            GLS_milp_model.objective = xsum(
                power_ele[i] * self.time_span * 3600
                for i in range(number)) / (sum(m_l_h2_t) * self.time_span *
                                           142)
            # HHV of H2 is 142MJ/kg
            # In this situation, the hydrogen production efficiency remains unchanged
            # and we can claim that a relationship between h2 production rate and electrolyser power is imperative.
            pass

        # --------------------------------------CONSTRAINS------------------------------------------
        # electrolyser power
        if linearization == True:
            for t in range(number):
                GLS_milp_model += power_ele[t] == xsum(
                    ele_w[i][t] * self.ele_breaks[i] for i in range(4))

                GLS_milp_model += xsum(ele_z[i][t] for i in range(3)) == 1
                GLS_milp_model += xsum(ele_w[i][t] for i in range(4)) == 1

                GLS_milp_model += ele_w[0][t] <= ele_z[0][t]
                GLS_milp_model += ele_w[1][t] <= ele_z[0][t] + ele_z[1][t]
                GLS_milp_model += ele_w[2][t] <= ele_z[1][t] + ele_z[2][t]
                GLS_milp_model += ele_w[3][t] <= ele_z[2][t]

                GLS_milp_model += power_converter[t] == xsum(
                    con_w[i][t] * self.con_breaks[i] for i in range(4))

                GLS_milp_model += xsum(con_z[i][t] for i in range(3)) == 1
                GLS_milp_model += xsum(con_w[i][t] for i in range(4)) == 1

                GLS_milp_model += con_w[0][t] <= con_z[0][t]
                GLS_milp_model += con_w[1][t] <= con_z[0][t] + con_z[1][t]
                GLS_milp_model += con_w[2][t] <= con_z[1][t] + con_z[2][t]
                GLS_milp_model += con_w[3][t] <= con_z[2][t]

                # The constrain between electrolyser power and converter power
                GLS_milp_model += power_ele[t] == xsum(
                    con_w[i][t] * self.con_f_breaks[i] for i in range(4))

        # Green hydrogen are those produced by wind energy
        for t in range(number):
            GLS_milp_model += power_ele_g[t] <= power_ele[t]
            GLS_milp_model += power_ele_g[t] <= p_w_t[t]

        # energy conservation
        if linearization:
            for t in range(number):
                GLS_milp_model += p_w_t[t] - power_utility[t] - p_l_t[
                    t] - power_comp[t] - power_converter[t] == 0
                pass
        else:
            for t in range(number):
                GLS_milp_model += p_w_t[t] - power_utility[t] - p_l_t[
                    t] - power_comp[t] - power_converter[t] == 0
                pass

        # electrolyser ramping rate limit
        RLU = 10
        RLD = 10
        for t in range(number):
            if t == 0:
                GLS_milp_model += power_ele[t] - 0 <= RLU
                GLS_milp_model += power_ele[t] - 0 >= -RLD
            else:
                GLS_milp_model += power_ele[t] - power_ele[t - 1] <= RLU
                GLS_milp_model += power_ele[t] - power_ele[t - 1] >= -RLD

        # relation between compressor power and electrolyser power
        for t in range(number):
            power_comp[t] = power_ele[
                t] * 20.5 / 3600 * 1e3 * 3221 / 1e6  # MW, unit conversion

        # regrading hydrogen tank
        if linearization == True:
            for t in range(number):
                if t == 0:
                    GLS_milp_model += hydrogen_level[t] - Mh2_ini == (
                        xsum(self.ele_f_breaks[i] * ele_w[i][t]
                             for i in range(4)) - m_l_h2_t[t]) * self.time_span
                else:
                    GLS_milp_model += hydrogen_level[t] - hydrogen_level[
                        t - 1] == (xsum(self.ele_f_breaks[i] * ele_w[i][t]
                                        for i in range(4)) -
                                   m_l_h2_t[t]) * self.time_span

        else:  # Assuming conversion rate of electrolyser is constant, 20.5kg/MWh
            for t in range(number):
                if t == 0:
                    GLS_milp_model += hydrogen_level[t] - Mh2_ini == (
                        power_ele[t] * 20.5 - m_l_h2_t[t]) * self.time_span
                else:
                    GLS_milp_model += hydrogen_level[t] - hydrogen_level[
                        t - 1] == (power_ele[t] * 20.5 -
                                   m_l_h2_t[t]) * self.time_span

        GLS_milp_model += hydrogen_level[-1] == Mh2_ini
        # ---------------------------------------End constrains------------------------------------

        # optimize
        GLS_milp_model.optimize()

        # ---------------------------------------SAVE RESULTS---------------------------------------
        if GLS_milp_model.status.name != 'INFEASIBLE':
            res_dict = {
                'Time': [i * self.time_span for i in range(number)],
                'Price':
                pi_t,
                'Power to utility grid':
                [round(power_utility[i].x, 2) for i in range(number)],
                'Converter power':
                [round(power_converter[i].x) for i in range(number)],
                'Electrolyser power':
                [round(power_ele[i].x, 2) for i in range(number)],
                'Compressor power':
                [round(power_comp[i].x, 2) for i in range(number)],
                'Wind power':
                p_w_t.round(2),
                'Hydrogen level':
                [round(hydrogen_level[i].x) for i in range(number)],
                'Green Electrolyser(only valid in object 1)':
                [round(power_ele_g[i].x, 2) for i in range(number)]
            }
            if linearization == True:
                res_dict['mh2'] = [
                    xsum(self.ele_f_breaks[i] * ele_w[i][t]
                         for i in range(4)).x for t in range(number)
                ]
            else:
                res_dict['mh2'] = [
                    round(power_ele[t].x, 2) * 20.5 for t in range(number)
                ]

            # -------------------------------------Daily profits---------------------------------------

            DP = np.sum([
                (res_dict['Power to utility grid'][i] * res_dict['Price'][i] +
                 res_dict['mh2'][i] * h2_price +
                 p_l_t[i] * res_dict['Price'][i] -
                 res_dict['Electrolyser power'][i] * C_m_ele -
                 res_dict['Compressor power'][i] * C_m_comp) * self.time_span
                for i in range(number)
            ])
            DP = round(DP, 2)
            # Green hydrogen proportion
            GH2P = np.sum([min(res_dict['Electrolyser power'][i], res_dict['Wind power'][i]) for i in range(number)]) \
                   / np.sum(res_dict['Electrolyser power'])
            GH2P = round(GH2P, 2)
            #
            CR = sum(m_l_h2_t) * 142 / (
                np.sum(res_dict['Electrolyser power']) * 3600)
            CR = round(CR, 4)
        else:
            DP = 0
            GH2P = 0
            CR = 0

        if save == True:
            assert GLS_milp_model.status.name != 'INFEASIBLE', 'INFEASIBLE'
            save_choice = {
                0: 'Maximal profits_operation_',
                1: 'Maximal green hydrogen_operation_',
                2: 'Maximal electrolyser efficiency_operation_'
            }
            save_choice2 = 'Linearization' if linearization else 'No_linearization'
            file = save_choice[objective] + save_choice2

            Saving_path = Path(Path().absolute() / 'Data' / (file + '.xlsx'))
            res = pd.DataFrame(res_dict)

            try:
                res.to_excel(Saving_path, float_format='%.3f', index=False)
                print('Successfully saved')
            except PermissionError:
                print('File already exists')

            wb = load_workbook(Saving_path)
            ws = wb.active
            ws['R1'].value = 'Total amount of hydrogen/kg'
            ws['S1'].value = sum(res_dict['mh2']) * self.time_span
            ws['R2'].value = 'Total electricity consumed/MWh'
            ws['S2'].value = sum(
                res_dict['Electrolyser power']) * self.time_span
            ws['R3'].value = 'Conversion rate of eletrolyser/(kg/MWh)'
            ws['S3'].value = sum(res_dict['mh2']) / sum(
                res_dict['Electrolyser power'])
            wb.save(Saving_path)

        objective_value = GLS_milp_model.objective.x if GLS_milp_model.status.name != 'INFEASIBLE' else -1e7
        print(f'Status:{GLS_milp_model.status.name}')
        print(f'Optimal value for objective {objective}: {objective_value}')
        print(f'Daily profits: {DP}')
        print(f'Green hydrongen proportion: {GH2P}')
        print(f'Average efficiency of electrolyser:{CR}')

        self.status = GLS_milp_model.status.name
        self.objective_value = objective_value
        self.DP = DP
        self.GH2P = GH2P
        self.CR = CR

        return GLS_milp_model.status.name, objective_value, DP
from mip import Model, xsum, maximize, BINARY

p = [10, 13, 18, 31, 7, 15]
w = [11, 15, 20, 35, 10, 33]
c, I = 47, range(len(w))

m = Model("knapsack")

x = [m.add_var(var_type=BINARY) for i in I]

m.objective = maximize(xsum(p[i] * x[i] for i in I))

m += xsum(w[i] * x[i] for i in I) <= c

m.optimize()

selected = [i for i in I if x[i].x >= 0.99]
print("selected items: {}".format(selected))
# Normalize all the lists to be the same lengths
max_list_length = max(len(QBcost), len(RBcost), len(WRcost), len(TEcost),
                      len(DEFcost))

for i in [QBcost, RBcost, WRcost, TEcost, DEFcost]:
    for j in range(max_list_length - len(i)):
        i.append(0)
for i in [QBpoints, RBpoints, WRpoints, TEpoints, DEFpoints]:
    for j in range(max_list_length - len(i)):
        i.append(0)

max_list_length = range(max_list_length)

# Initialize the model
m = Model("fanduel")

# Declare decision variables
QB = [m.add_var(var_type=BINARY) for i in max_list_length]
RB1 = [m.add_var(var_type=BINARY) for i in max_list_length]
RB2 = [m.add_var(var_type=BINARY) for i in max_list_length]
WR1 = [m.add_var(var_type=BINARY) for i in max_list_length]
WR2 = [m.add_var(var_type=BINARY) for i in max_list_length]
WR3 = [m.add_var(var_type=BINARY) for i in max_list_length]
TE = [m.add_var(var_type=BINARY) for i in max_list_length]
FLEXRB = [m.add_var(var_type=BINARY) for i in max_list_length]
FLEXWR = [m.add_var(var_type=BINARY) for i in max_list_length]
DEF = [m.add_var(var_type=BINARY) for i in max_list_length]

# Objective is to maximize points
m.objective = maximize(xsum(QB[i]*QBpoints[i] +
Beispiel #24
0
    def select_optimal_lineup(point_key, save_name, df):
        df = df.copy(deep=True)
        #drop those with missing values for points
        df = df[~pd.isnull(df[point_key])]

        #select optimal lineup
        #num rows
        n = range(df.shape[0])
        #use free solver
        m = Model(solver_name=CBC)
        #n binary vars indicating if player is selected or not
        x = [m.add_var(var_type=BINARY) for i in n]
        #objective: maximize predicted points for players selected
        m.objective = maximize(
            xsum(df[point_key].tolist()[i] * x[i] for i in n))
        #salary constraint
        m += xsum(df['Salary'].tolist()[i] * x[i] for i in n) <= 50000
        #position constraints. 1 of each position, 1 extra gaurd, 1 extra forward, 1 utility
        #pg
        m += xsum(df['pg'].tolist()[i] * x[i] for i in n) >= 1
        m += xsum(df['pg'].tolist()[i] * x[i] for i in n) <= 3
        #sg
        m += xsum(df['sg'].tolist()[i] * x[i] for i in n) >= 1
        m += xsum(df['sg'].tolist()[i] * x[i] for i in n) <= 3
        #g
        m += xsum((df['pg'].tolist()[i] + df['sg'].tolist()[i]) * x[i]
                  for i in n) >= 3
        #sf
        m += xsum(df['sf'].tolist()[i] * x[i] for i in n) >= 1
        m += xsum(df['sf'].tolist()[i] * x[i] for i in n) <= 3
        #pf
        m += xsum(df['pf'].tolist()[i] * x[i] for i in n) >= 1
        m += xsum(df['pf'].tolist()[i] * x[i] for i in n) <= 3
        #f
        m += xsum((df['sf'].tolist()[i] + df['pf'].tolist()[i]) * x[i]
                  for i in n) >= 3
        #c
        m += xsum(df['c'].tolist()[i] * x[i] for i in n) >= 1
        m += xsum(df['c'].tolist()[i] * x[i] for i in n) <= 2
        #total
        m += xsum(x[i] for i in n) == 8
        #player constraints - players appear only once
        for player in player_var_list:
            m += xsum(df[player].tolist()[i] * x[i]
                      for i in n) <= 1, '{}'.format(player)
        #optimize
        m.optimize()

        #save copy of optimal lineup as record
        names = [df['Name'].to_list()[i] for i in n if x[i].x >= 0.99]
        points = [df[point_key].to_list()[i] for i in n if x[i].x >= 0.99]
        with open(
                "export/lineups/lineup_{}_{}.csv".format(
                    save_name, date.today()), "w") as f:
            f.write("name,points\n")
            for i in range(len(names)):
                f.write("{},{}\n".format(names[i], points[i]))
            f.close()

        #order list of ids to conform with DK template
        #PG,SG,SF,PF,C,G,F,UTIL
        final_pos_list = [0 for i in range(8)]
        for pos in ["pg", "sg", "sf", "pf", "c"]:
            position_list = [
                df['ID'].to_list()[i] for i in n
                if x[i].x >= 0.99 and df[pos].to_list()[i] == 1
            ]
            if pos == "pg":
                final_pos_list[0] = position_list[0]
            elif pos == "sg":
                final_pos_list[1] = position_list[0]
            elif pos == "sf":
                final_pos_list[2] = position_list[0]
            elif pos == "pf":
                final_pos_list[3] = position_list[0]
            elif pos == "c":
                final_pos_list[4] = position_list[0]
            if len(position_list) >= 2:
                if (pos in ["pg", "sg"]) and final_pos_list[5] == 0:
                    final_pos_list[5] = position_list[1]
                elif pos in ["sf", "pf"] and final_pos_list[6] == 0:
                    final_pos_list[6] = position_list[1]
                elif pos == "c":
                    final_pos_list[7] = position_list[1]
                else:
                    final_pos_list[7] = position_list[1]
            if len(position_list) == 3:
                final_pos_list[7] = position_list[2]

        #write template to .csv file
        #PG,SG,SF,PF,C,G,F,UTIL
        with open(
                "export/for_upload/lineup_{}_{}.csv".format(
                    save_name, date.today()), "w") as f:
            f.write("PG,SG,SF,PF,C,G,F,UTIL\n")
            for pos in final_pos_list:
                f.write("{}".format(pos))
                if pos != final_pos_list[len(final_pos_list) - 1]: f.write(",")
            f.close()
from prettytable import PrettyTable
# packages awaiting shipment
priorities = [ 1,   0,   0,   1,   0,   0,  0,   1]
volumes =    [40,  25, 130, 180,  70, 200, 35,  90]
weights =    [60, 120, 210, 240, 100, 320, 90, 150]

# Priority packages
names_p = [i for i in range(len(priorities)) if priorities[i] == 1]
w_p = [weights[i] for i in range(len(priorities)) if priorities[i] == 1]
v_p = [volumes[i] for i in range(len(priorities)) if priorities[i] == 1]

volume_p = 325
weight_p = 750
I = range(len(w_p))

m = Model("priority")

x_p = [m.add_var(var_type=BINARY) for i in I]

m.objective = maximize(xsum(x_p[i] for i in I))

m += xsum(v_p[i] * x_p[i] for i in I) <= volume_p
m += xsum(w_p[i] * x_p[i] for i in I) <= weight_p

m.optimize()

selected_p = [i for i in I if x_p[i].x >= 0.99]
selected_p_names = [names_p[i]+1 for i in selected_p]
print("selected priority packages: {}".format(selected_p_names))

# LEFTOVERS CALCULATION
Beispiel #26
0
def main():
    spreadsheet_file = pd.ExcelFile('../data.xlsx')
    worksheets = spreadsheet_file.sheet_names

    print("all the worksheets ", worksheets)

    # In[4]:

    island_coordinates = []
    storm_coordinates_radius = []
    road_material = {}
    materialToCost = {"Asphalt": 100, "Concrete": 65, "Gravel": 35}
    road_time = {}
    time_matrix = []

    print("extracting data...")

    locationDF = pd.read_excel('data.xlsx',
                               sheet_name="Locations",
                               header=None,
                               skiprows=1)
    for index, row in locationDF.iterrows():
        # print("++" ,type(row[1]))
        island_coordinates.append((row[1], row[2]))

    stormDF = pd.read_excel('data.xlsx',
                            sheet_name="Storms",
                            header=None,
                            skiprows=2)
    for index, row in stormDF.iterrows():
        storm_coordinates_radius.append([row[0], row[1], row[2]])

    roadMaterialDF = pd.read_excel('data.xlsx',
                                   sheet_name="Road Material",
                                   header=None,
                                   skiprows=1)
    for index, row in roadMaterialDF.iterrows():
        key = f'{row[0]} {row[1]}'
        value = row[2]
        road_material[key] = value

    print("extracting data is done.")

    # In[5]:

    print(island_coordinates)
    print(len(island_coordinates))

    # In[6]:

    print(storm_coordinates_radius)
    print(len(storm_coordinates_radius))

    # In[7]:

    print("\npreprocessing...")

    for i in range(len(island_coordinates)):
        time_matrix.append([])
        for j in range(len(island_coordinates)):
            if i == j:
                time_matrix[i].append(0)
            else:
                island1 = island_coordinates[i]
                island2 = island_coordinates[j]
                distance = calculateDistance(island1[0], island1[1],
                                             island2[0], island2[1])
                roadType = road_material[f'{i + 1} {j + 1}']
                time_matrix[i].append(distance / materialToCost[roadType])

    # print(time_matrix)

    dists = []
    for i in range(len(island_coordinates)):
        dists.append([])
        for j in range(i + 1, len(island_coordinates)):
            island1 = island_coordinates[i]
            island2 = island_coordinates[j]
            distance = calculateDistance(island1[0], island1[1], island2[0],
                                         island2[1])
            roadType = road_material[f'{i + 1} {j + 1}']
            dists[i].append(distance / materialToCost[roadType])

    storms = []
    for i in range(len(island_coordinates)):
        storms.append([])
        for j in range(len(island_coordinates)):
            island1 = island_coordinates[i]
            island2 = island_coordinates[j]
            is_stormy = False
            for k in range(len(storm_coordinates_radius)):
                if i == j:
                    storms[i].append(0)
                    break

                else:
                    island1 = island_coordinates[i]
                    island2 = island_coordinates[j]
                    stormInfo = storm_coordinates_radius[k]
                    cx, cy, cradius = stormInfo[0], stormInfo[1], stormInfo[2]
                    if storm_check(island1[0], island1[1], island2[0],
                                   island2[1], cx, cy, cradius):
                        # print("--- Storm #", k + 1, " found between island ", i + 1, " and island ", j + 1)
                        is_stormy = True
                        storms[i].append(0)
                        break

            if i != j and not is_stormy:
                storms[i].append(1)

    for i in range(len(storms)):
        if len(storms) != len(storms[i]):
            print("?")
    print(storms)
    print(storms[29][29])
    print("preprocessing is done.")

    # In[ ]:

    places = [f'island {i}' for i in range(1, 31)]

    n, V = len(dists), set(range(len(dists)))

    model = Model()

    # binary variables indicating if arc (i,j) is used on the route or not
    x = [[model.add_var(var_type=BINARY) for j in V] for i in V]

    # continuous variable to prevent subtours: each city will have a
    # different sequential id in the planned route except the first one
    y = [model.add_var() for i in V]

    # objective function: minimize the distance
    model.objective = minimize(
        xsum(time_matrix[i][j] * x[i][j] for i in V for j in V))

    # constraint : leave each city only once
    for i in V:
        model += xsum(x[i][j] for j in V - {i}) == 1

    # constraint : enter each city only once
    for i in V:
        model += xsum(x[j][i] for j in V - {i}) == 1

    # constraint : storm
    for i in range(n):
        for j in range(n):
            model += (x[i][j] * storms[i][j] == x[i][j])

    # subtour elimination
    for (i, j) in product(V - {0}, V - {0}):
        if i != j:
            model += y[i] - (n + 1) * x[i][j] >= y[j] - n

    # optimizing
    model.optimize()

    # In[ ]:

    print("come on....")
    # checking if a solution was found
    if model.num_solutions:
        print('route with total distance %g found: %s' %
              (model.objective_value, places[0]))
        path = places[0]
        nc = 0
        while True:
            nc = [i for i in V if x[nc][i].x >= 0.99][0]
            print(' -> %s' % places[nc])

            path = path + ' -> %s' % places[nc]

            if nc == 0:
                break
        print('\n')

        arr = np.array(x)
        arr = arr.astype(str)

        file = open("../data.txt", "w")
        file.write(path + "\n")
        file.write(str(model.objective_value) + " - ")
        file.write("\n")

        for i in range(len(arr)):
            line = ""
            for j in range(len(arr[i])):
                line = line + str(x[i][j].x)
                if j != len(arr[i]) - 1:
                    line = line + ","

            file.write(line + "\n")
        file.close()

    else:
        print("no solution")
Beispiel #27
0
         [117, 65, 125, 43],
         [54, 22, 84],
         [60, 44],
         [97],
         []]

# number of nodes and list of vertices
n, V = len(dists), set(range(len(dists)))

# distances matrix
c = [[0 if i == j
      else dists[i][j-i-1] if j > i
      else dists[j][i-j-1]
      for j in V] for i in V]

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = [[model.add_var(var_type=BINARY) for j in V] for i in V]

# continuous variable to prevent subtours: each city will have a
# different sequential id in the planned route except the first one
y = [model.add_var() for i in V]

# objective function: minimize the distance
model.objective = minimize(xsum(c[i][j]*x[i][j] for i in V for j in V))

# constraint : leave each city only once
for i in V:
    model += xsum(x[i][j] for j in V - {i}) == 1
Beispiel #28
0
v_p = [volumes[i] for i in range(len(priorities)) if priorities[i] == 1]
# extracting non-priority packages
names_np = [i for i in range(len(priorities)) if priorities[i] == 0]
w_np = [weights[i] for i in range(len(priorities)) if priorities[i] == 0]
v_np = [volumes[i] for i in range(len(priorities)) if priorities[i] == 0]

# quantitative restrictions
volume_np = 325
weight = 750

# iterators
I_p = range(len(w_p))
I_np = range(len(w_np))

# creating new model
m = Model("packages")

# creating binary variables [0-DO NOT PACK, 1-PACK]
x_p = [m.add_var(var_type=BINARY) for i in I_p]
x_np = [m.add_var(var_type=BINARY) for i in I_np]

# objective function
m.objective = maximize(xsum(x_p[i] for i in I_p) + xsum(x_np[j] for j in I_np))

# limitations
m += xsum(v_np[i] * x_np[i] for i in I_np) <= volume_np
# m += xsum(v_p[i] * x_p[i] for i in I_p) <= volume_np
m += (xsum(w_p[i] * x_p[i] for i in I_p) + xsum(w_np[j] * x_np[j]
                                                for j in I_np)) <= weight

# run the optimization process
Beispiel #29
0
C = 10
# set of curricula
CU = 6
T = len(teachers)


p_CAP = 1
p_STAB = 1
p_DAYS = 1
p_COMP = 1
#
# ma = [[0,1,2],[3,4,5],[6,7,8],[6,7,8]]
# meow = 1 - (xsum(ma[i][j] for i in range(2) for j in range(3)) \
#        + xsum(ma[i][j] for i in range(2,4) for j in range(3)))

m = Model("cbctt")

x_cdpr = [[[[m.add_var('x({},{},{},{})'.format(c,d,p,r),var_type=BINARY)
             for r in range(R)] for p in range(P)] for d in range(D)] for c in range(C)]

print('\nx_cdpr:',x_cdpr[0][0][0][0].x)
print('\nx_cdpr:',x_cdpr[1][1][0][0].x)
print('\nx_cdpr:',x_cdpr[2][2][0][0].x)
print('\nx_cdpr:',x_cdpr[3][3][0][0].x)


v_cupd = [[[m.add_var('v({},{},{})'.format(cu,p,d),var_type=BINARY)
            for d in range(D)] for p in range(P)] for cu in range(CU)]
print('\nv_cupd:',v_cupd)
y_cr = [[m.add_var('y({},{})'.format(c,r),var_type=BINARY)
         for r in range(R)] for c in range(C)]
Beispiel #30
0
def test_tsp_cuts(solver: str):
    """tsp related tests"""
    N = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    n = len(N)
    i0 = N[0]

    A = {
        ('a', 'd'): 56,
        ('d', 'a'): 67,
        ('a', 'b'): 49,
        ('b', 'a'): 50,
        ('d', 'b'): 39,
        ('b', 'd'): 37,
        ('c', 'f'): 35,
        ('f', 'c'): 35,
        ('g', 'b'): 35,
        ('b', 'g'): 25,
        ('a', 'c'): 80,
        ('c', 'a'): 99,
        ('e', 'f'): 20,
        ('f', 'e'): 20,
        ('g', 'e'): 38,
        ('e', 'g'): 49,
        ('g', 'f'): 37,
        ('f', 'g'): 32,
        ('b', 'e'): 21,
        ('e', 'b'): 30,
        ('a', 'g'): 47,
        ('g', 'a'): 68,
        ('d', 'c'): 37,
        ('c', 'd'): 52,
        ('d', 'e'): 15,
        ('e', 'd'): 20
    }

    # input and output arcs per node
    Aout = {n: [a for a in A if a[0] == n] for n in N}
    Ain = {n: [a for a in A if a[1] == n] for n in N}
    m = Model(solver_name=solver)
    m.verbose = 0

    x = {
        a: m.add_var(name='x({},{})'.format(a[0], a[1]), var_type=BINARY)
        for a in A
    }

    m.objective = xsum(c * x[a] for a, c in A.items())

    for i in N:
        m += xsum(x[a] for a in Aout[i]) == 1, 'out({})'.format(i)
        m += xsum(x[a] for a in Ain[i]) == 1, 'in({})'.format(i)

    # continuous variable to prevent subtours: each
    # city will have a different "identifier" in the planned route
    y = {i: m.add_var(name='y({})'.format(i), lb=0.0) for i in N}

    # subtour elimination
    for (i, j) in A:
        if i0 not in [i, j]:
            m.add_constr(y[i] - (n + 1) * x[(i, j)] >= y[j] - n)

    m.cuts_generator = SubTourCutGenerator()

    # tiny model, should be enough to find the optimal
    m.max_seconds = 10
    m.max_nodes = 100
    m.max_solutions = 1000
    m.optimize()

    assert m.status == OptimizationStatus.OPTIMAL  # "mip model status"
    assert abs(m.objective_value - 262) <= TOL  # "mip model objective"