Пример #1
0
    def __init__(self,
                 rounding_digits: int = ROUNDING_DIGITS,
                 max_seconds: int = ILP_SOLVER_MAX_SECONDS) -> None:
        """Create an ILPSolver.

        Args:
            rounding_digits: Number of digits to round the charges to.
            max_seconds: Maximum run-time to spend searching for a \
                    solution
        """
        self._rounding_digits = rounding_digits

        if CPLEX_CMD().available():
            self._solver = CPLEX_CMD(timelimit=max_seconds)
        elif GUROBI_CMD().available():
            self._solver = GUROBI_CMD(options=[('timeLimit', max_seconds)])
        elif PULP_CBC_CMD().available():
            self._solver = PULP_CBC_CMD(maxSeconds=max_seconds)
        elif GLPK_CMD().available():
            self._solver = GLPK_CMD(options=['--tmlim %d' % max_seconds])
        elif COIN_CMD().available():
            self._solver = COIN_CMD(maxSeconds=max_seconds)
        else:
            raise RuntimeError(
                'No solver found, there is something wrong with your pulp library setup.'
            )
Пример #2
0
def disjointness_LP(sets):
    if (len(sets) == 0):
        return
    prob = LpProblem("Disjointness Problem", LpMaximize)
    variables = []
    for i in range(len(sets)):
        variables.append(LpVariable("Include Set " + str(i), 0, 1))

    #objective
    prob += lpSum([1 * variables[i] for i in range(len(sets))])

    #constraints
    for j in range(len(sets[0])):
        #for every qubit, make the sum of actions less than 1
        prob += lpDot([sets[i][j] for i in range(len(sets))],
                      [variables[i] for i in range(len(sets))]) <= 1

    prob.writeLP("Disjointness.lp")

    prob.solve(solver=PULP_CBC_CMD(msg=0))

    representatives = []
    values = []

    for v in prob.variables():
        i = extract_index(v.name)
        if (v.varValue != 0.0):
            representatives.append(i)
            values.append(v.varValue)

    return value(prob.objective), representatives, values
Пример #3
0
def rep(g):
    nbar = {
        u: nx.induced_subgraph(g, [v for v in g if v not in g[u]])
        for u in g
    }

    x = {
        u: {v: LpVariable(f'x{u},{v}', cat='Binary')
            for v in nbar[u]}
        for u in g
    }

    lp = LpProblem()
    lp += lpSum([x[u][u] for u in g])

    for v in g:
        lp += lpSum([x[u][v] for u in nbar[v]]) >= 1

    for u in g:
        for v, w in nbar[u].edges:
            lp += x[u][v] + x[u][w] <= x[u][u]

    lp.writeLP('rep.lp')
    PULP_CBC_CMD(msg=0).solve(lp)

    reps = [u for u in g if x[u][u].varValue > 0]
    cols = [None] * g.order()
    for c, v in enumerate(reps):
        cols[v] = c
    for c, r in enumerate(reps):
        for v in [v for v, xi in x[r].items() if xi.varValue > 0]:
            if v not in reps:
                cols[v] = c
    return cols
Пример #4
0
def pop(g, H=10):
    h = list(range(H))
    y = {i: {v: LpVariable(f'y{i},{v}', cat='Binary') for v in g} for i in h}
    z = {v: {i: LpVariable(f'z{v},{i}', cat='Binary') for i in h} for v in g}

    lp = LpProblem()
    q = 0  # arbitrary fix vertex, then q = 0
    lp += 1 + lpSum([y[i][q] for i in h])  # 15

    for v in g:
        lp += z[v][1] == 0  # 16
        lp += y[h[-1]][v] == 0  # 17
    for v in g:
        for i in h[:-2]:
            lp += y[i][v] - y[i + 1][v] >= 0  # 18
            lp += y[i][v] + z[v][i + 1] == 1  # 19
            lp += y[i][q] - y[i][v] >= 0  # 21
    for u, v in g.edges:
        for i in h:
            lp += y[i][u] + z[u][i] + y[i][v] + z[v][i] >= 1  # 20
    PULP_CBC_CMD(msg=0).solve(lp)
    return [
        next(i for i in h
             if y[i][v].varValue == 0.0 and z[v][i].varValue == 0.0) for v in g
    ]
Пример #5
0
    def optimize(self, time_limit, solver, presolve=2):

        # The solver value shall one of the available
        # solver corresponding pulp command

        if 'gurobi' in solver.lower():
            # ignore SIGINT while solver is running
            # => SIGINT is still delivered to the solver, which is what we want
            signal.signal(signal.SIGINT, signal.SIG_IGN)
            self.model.solve(
                GUROBI_CMD(keepFiles=1,
                           msg=True,
                           options=[("TimeLimit", time_limit),
                                    ("Presolve", presolve),
                                    ("MIPGapAbs", 0.2)]))
        else:
            # TODO Use the solver parameter to get
            # the target class by reflection
            self.model.solve(
                PULP_CBC_CMD(keepFiles=1,
                             msg=True,
                             presolve=presolve,
                             maxSeconds=time_limit))
        status = self.model.status
        print(LpStatus[status])
        if status == LpStatusOptimal or (not (solver.lower() == 'gurobi')
                                         and status == LpStatusNotSolved):
            return self.get_obj_coeffs()

        else:
            print('lpfile has been saved in FlOpTT-pulp.lp')
            return None
Пример #6
0
    def optimize_pulp(self):
        from pulp import LpVariable,LpProblem,LpMaximize,LpBinary,PULP_CBC_CMD

        p = LpProblem("knapsackP",LpMaximize)
        x = LpVariable.dict("x",indexs=(range(self.num)),lowBound=0,upBound=1,cat=LpBinary)

        #価値最大化
        #p += sum(x[i]*self.p[i].get_value() for i in range(self.num))
        #p += lpDot(x,[self.p[i].get_value() for i in range(self.num)])
        p += lpSum(x[i]*self.p[i].get_value() for i in range(self.num))

        #重量を制限以内
        p += lpSum(x[i]*self.p[i].get_weight() for i in range(self.num)) <= self.limit_weight

        #解く
        solver=PULP_CBC_CMD(msg=0,threads=10)
        p.solve(solver)

        if p.status == 1:
            print("## Pulp Optimized Result")
            self.print([int(x[i].value()) for i in range(self.num)])
            ret = sum([x[i].value()*self.p[i].get_value() for i in range(self.num)])
            del x,p
            gc.collect()
            return ret
        else:
            print("## Pulp Optimizing Failed")
class PuLPSolver(Solver):
    LP_SOLVER = PULP_CBC_CMD(verbose=False, msg=False)

    def __init__(self):
        self.prob = LpProblem('Daily Fantasy Sports', LpMaximize)

    def setup_solver(self):
        pass

    def add_variable(self, name, min_value=None, max_value=None):
        if any([min_value, max_value]):
            return LpVariable(name,
                              lowBound=min_value,
                              upBound=max_value,
                              cat=LpInteger)
        return LpVariable(name, cat=LpBinary)

    def set_objective(self, variables, coefficients):
        self.prob += lpSum([
            variable * coefficient
            for variable, coefficient in zip(variables, coefficients)
        ])

    def add_constraint(self, variables, coefficients, sign, rhs):
        if coefficients:
            lhs = [
                variable * coefficient
                for variable, coefficient in zip(variables, coefficients)
            ]
        else:
            lhs = variables
        if sign == SolverSign.EQ:
            self.prob += lpSum(lhs) == rhs
        elif sign == SolverSign.NOT_EQ:
            self.prob += lpSum(lhs) != rhs
        elif sign == SolverSign.GTE:
            self.prob += lpSum(lhs) >= rhs
        elif sign == SolverSign.LTE:
            self.prob += lpSum(lhs) <= rhs
        else:
            raise SolverException('Incorrect constraint sign')

    def copy(self):
        new_solver = type(self)()
        new_solver.prob = self.prob.copy()
        return new_solver

    def solve(self):
        self.prob.solve(self.LP_SOLVER)
        if self.prob.status == LpStatusOptimal:
            result = []
            for variable in self.prob.variables():
                val = variable.value()
                if val is not None and round(val) >= 1.0:
                    result.append(variable)
            return result
        else:
            raise SolverException('Unable to solve')
Пример #8
0
 def run(self):
     self.problem = LpProblem('FML', LpMaximize)
     self.create_vars()
     self.problem += self.get_objective_function(solved=False)
     for constraint in self.get_constraints():
         self.problem += constraint
     status = self.problem.solve(PULP_CBC_CMD(msg=3))
     solved = status == 1
     return solved
Пример #9
0
 def _formulate_and_solve(
     self, env_tick: int, init_inventory: np.ndarray, demand: np.ndarray, supply: np.ndarray
 ):
     problem = LpProblem(
         name=f"Citi_Bike_Repositioning_from_tick_{env_tick}",
         sense=LpMaximize,
     )
     self._init_variables(init_inventory=init_inventory)
     self._add_constraints(problem=problem, demand=demand, supply=supply)
     self._set_objective(problem=problem)
     problem.solve(PULP_CBC_CMD(msg=0))
Пример #10
0
 def solve(self, print_status=True, print_cost_achieved=True):
   status = self.problem.solve(PULP_CBC_CMD(msg=0))
   self.problem_solved = True
   print_blank_line = False
   if print_status:
     print(f"Status: {LpStatus[status]}")
     print_blank_line = True
   if print_cost_achieved:
     print(f"Cost: {value(self.problem.objective)}")
     print_blank_line = True
   if print_blank_line:
     print()
Пример #11
0
    def solve_exact(self):
        '''
            整数計画法を用いて厳密解を得る

        parameters
        -----
            なし
        returns
        -----
            なし
        '''
        from pulp import LpProblem, LpVariable, lpSum, LpStatus, PULP_CBC_CMD

        n_city = self.size
        #Pulpで解く
        p = LpProblem("TSP")
        x = LpVariable.dicts(name="x",
                             indexs=(range(n_city), range(n_city)),
                             cat='Binary')

        p += lpSum(
            self.dist(i, j) * x[i][j]
            for i, j in product(range(n_city), range(n_city)))

        for i in range(n_city):
            p += lpSum(x[i][j] for j in range(n_city)) == 1

        for i in range(n_city):
            p += lpSum(x[j][i] for j in range(n_city)) == 1

        V = set(range(n_city))
        for s_len in range(1, n_city - 1):
            for S_list in combinations(range(n_city), s_len):
                S = set(S_list)
                _V = V - S
                tmp = 0
                for i, j in product(S, _V):
                    tmp += x[i][j]
                p += tmp >= 1

        solver = PULP_CBC_CMD(threads=15)
        status = p.solve(solver)
        print(LpStatus[status])

        self.exact_route = [0]
        for i in range(n_city - 1):
            for j in range(n_city):
                if x[self.exact_route[i]][j].value() == 1.0:
                    self.exact_route.append(j)
                    break

        self.exact_dist = self.route_len(self.exact_route)
Пример #12
0
    def _solve(self):
        logger.info("Searching for a cover for {}...".format(self.root_object))
        time_start = time()

        if GUROBI_CMD(msg=0).available():
            logger.info("Gurobi installed on system and set as solver")
            solver = GUROBI_CMD(msg=0)
        elif PULP_CBC_CMD(msg=0).available():
            logger.warning("Gurobi not installed on system, instead "
                           "falling back on PuLP's bundled CBC LP solver")
            solver = PULP_CBC_CMD(msg=0)
        else:
            raise RuntimeError("Unable to load PuLP's bundled CBC LP solver")

        problem = LpProblem("CombCov LP minimization problem", LpMinimize)
        X = LpVariable.dicts("x", list(range(len(self.bitstrings))),
                             cat="Binary")

        for i in range(len(self.elmnts_dict)):  # nr. of equations
            constraint = sum(
                int(self.bitstrings[j][-i]) * X[j]
                for j in range(len(self.bitstrings))
            )  # nr. of variables x_j
            problem += constraint == 1

        # Objective function
        problem += sum(X[j] for j in range(len(self.bitstrings)))

        problem.solve(solver=solver)
        self.solution = [
            self.bitstring_to_rules_dict[self.bitstrings[x]][0]
            for x in X if X[x].varValue and int(X[x].varValue) == 1
        ]

        time_end = time()
        elapsed_time = time_end - time_start

        logger.info("...DONE searching for a cover! "
                    "(Running time: {:.2f} sec)".format(elapsed_time))
Пример #13
0
    def solve(self) -> ModelSolution:
        """
        Method to solve the optimization model.
        For other optimization frameworks, a similar logic can be applied.

        ** Gurobi

        for constraint in self.constraints:
            self.solver.addConstr(constraint)

        self.solver.setObjective(self.objective, self.sense)
        self.solver.optimize()

        if self.engine_model.status == GRB.OPTIMAL:
            solution = np.vectorize(self._var_sol)(self.variable_set)
        else:
            solution = np.array([])

        ** Google or-tools

        for constraint in self.constraints:
            self.solver.Add(constraint)

        if self.sense == Sense.MINIMIZATION:
            self.solver.Minimize(self.objective)
        else:
            self.solver.Maximize(self.objective)

        status = self.solver.Solve()

        if status == Solver.OPTIMAL:
            solution = np.vectorize(self.var_sol)(self.variable_set)
        else:
            solution = np.array([])
        """
        for constraint in self.constraints:
            self.solver += constraint

        self.solver += self.objective

        status = self.solver.solve(PULP_CBC_CMD(msg=False))

        if status == LpStatusOptimal:
            solution = np.vectorize(self._var_sol)(self.variable_set)
        else:
            solution = np.array([])

        return ModelSolution(variable_set=solution,
                             objective=self.solver.objective.value())
    def get_solution(self):
        """Set a number of constrains for the model and then solve the ILP."""
        self.update_model_with_decision_variables()
        self.add_constraints_to_model()

        size_string_list = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"]
        size_dict_list = [self.one, self.two, self.three, self.four, self.five, self.six, self.seven, self.eight]

        self.update_all_models(size_string_list, size_dict_list)
        self.determine_biggest_sum(size_string_list, size_dict_list)

        # Add the objective function to the model
        self.model += lpSum(self.x)

        # Solve the problem
        self.model.solve(PULP_CBC_CMD(timeLimit=600, msg=False, gapRel=0))
Пример #15
0
def ass(g, h=10):
    c = list(range(h))
    w = [LpVariable(f'w{j}', cat='Binary') for j in c]
    x = {i: [LpVariable(f'x{i},{j}', cat='Binary') for j in c] for i in g}
    lp = LpProblem()
    lp += lpSum(w)
    for i in g:
        lp += lpSum(x[i]) == 1
    for u, v in g.edges:
        for j in c:
            lp += x[u][j] + x[v][j] <= w[j]
    for j in c:
        lp += w[j] <= lpSum([x[i][j] for i in g])
    for j in c[1:]:
        lp += w[j] <= w[j - 1]
    PULP_CBC_CMD(msg=0).solve(lp)
    return [[xi.varValue for xi in x[i]].index(1.0) for i in g]
Пример #16
0
def ipla(g):
    n, k, h = g.order(), max(deg for _, deg in g.degree), g.to_directed()

    lp = LpProblem()
    lp += (w := LpVariable('w'))

    for u in h.nodes:
        h.nodes[u]['v'] = [
            LpVariable(f'y{u},{i}', 1, n, 'Integer') for i in range(k)
        ]
    for u, v in g.edges:
        h[u][v]['v'] = [
            LpVariable(f'x{u},{v},{i}', cat='Binary') for i in range(k)
        ]
        h[v][u]['v'] = [
            LpVariable(f'x{v},{u},{i}', cat='Binary') for i in range(k)
        ]
        lp += lpSum(h[u][v]['v']) + lpSum(h[v][u]['v']) == 1
        lp += w >= lpSum((i + 1) * h[u][v]['v'][i] + (i + 1) * h[v][u]['v'][i]
                         for i in range(k))
        for i in range(k):
            lp += (h.nodes[u]['v'][i] - h.nodes[v]['v'][i] +
                   (n - 1) * h[u][v]['v'][i] <= n - 2)
            lp += (h.nodes[v]['v'][i] - h.nodes[u]['v'][i] +
                   (n - 1) * h[v][u]['v'][i] <= n - 2)
    for u in h.nodes:
        for i in range(k):
            lp += lpSum(h[u][v]['v'][i] for v in h.successors(u)) <= 1
            lp += lpSum(h[v][u]['v'][i] for v in h.predecessors(u)) <= 1

    PULP_CBC_CMD(msg=0).solve(lp)
    # print(w.varValue)
    # from pprint import pprint
    # for v in g:
    #     pprint([x.varValue for x in h.nodes[v]['v']])
    # for u, v in h.edges:
    #     pprint([x.varValue for x in h[u][v]['v']])
    ep = {}
    for u, v in g.edges:
        if sum((res := [h[u][v]['v'][i].varValue for i in range(k)])) != 0:
            ep[(u, v)] = res.index(1.0)
        else:
            ep[(u, v)] = [h[v][u]['v'][i].varValue
                          for i in range(k)].index(1.0)
Пример #17
0
    def __init__(self, config: DottableDict, pm_capacity: List[IlpPmCapacity],
                 logger: Logger, log_path: str):
        self._logger = logger
        self._log_path = log_path

        self._pm_capacity = pm_capacity
        self._pm_num = len(self._pm_capacity)

        # LP solver.
        msg = 1 if config.log.stdout_solver_message else 0
        if config.solver == "GLPK":
            self._solver = GLPK(msg=msg)
        elif config.solver == "CBC":
            self._solver = PULP_CBC_CMD(msg=msg)
        else:
            print(
                f"Solver {config.solver} not added in ILP, choose from [GLPK, CBC]"
            )
            exit(0)

        # For formulation and action application.
        self.plan_window_size = config.plan_window_size
        self.apply_buffer_size = config.apply_buffer_size

        # For performance.
        self.core_upper_ratio = 1 - config.performance.core_safety_remaining_ratio
        self.mem_upper_ratio = 1 - config.performance.mem_safety_remaining_ratio

        # For objective.
        self.successful_allocation_decay = config.objective.successful_allocation_decay
        self.allocation_multiple_core_num = config.objective.allocation_multiple_core_num

        # For logger.
        self.dump_all_solution = config.log.dump_all_solution
        self.dump_infeasible_solution = config.log.dump_infeasible_solution

        # For problem formulation and application
        self.last_solution_env_tick = -1
Пример #18
0
    def solve(self):
        """Method for solving the optimization model"""

        if self.optimizer == 'pulp':
            for constraint in self.constraints:
                self.engine_model += constraint

            self.engine_model += self.objective
            status = self.engine_model.solve(PULP_CBC_CMD(msg=False))
            solution = (np.vectorize(self._var_sol)(self.variable_set)
                        if status == LpStatusOptimal else np.array([]))

        else:
            for constraint in self.constraints:
                self.engine_model.addConstr(constraint)

            self.engine_model.setObjective(self.objective, self.sense)
            self.engine_model.optimize()
            solution = (np.vectorize(self._var_sol)(self.variable_set)
                        if self.engine_model.status == GRB.OPTIMAL else
                        np.array([]))

        return solution
Пример #19
0
    def run(self):
        prob = LpProblem("V_star_Problem", LpMinimize)

        var = []
        state_to_var = {}
        for s in range(self.num_states):
            if s not in self.end:
                state_to_var[f"V{s}"] = s
                var.append(LpVariable(f"V{s}", cat="Continuous"))

        prob += lpSum(var), "minimize_V"
        self.add_constraints(var, prob)

        prob.writeLP("CalculateVStarProblem.lp")
        result = prob.solve(PULP_CBC_CMD(msg=0))
        assert LpStatusOptimal == result

        self.v_star = [0] * self.num_states
        for v in prob.variables():
            if v.name in state_to_var:
                self.v_star[state_to_var[v.name]] = v.varValue

        self.a_star = self.get_action(self.v_star)
Пример #20
0
def apply(c, Aub, bub, Aeq, beq, parameters=None):
    """
    Gets the overall solution of the problem

    Parameters
    ------------
    c
        c parameter of the algorithm
    Aub
        A_ub parameter of the algorithm
    bub
        b_ub parameter of the algorithm
    Aeq
        A_eq parameter of the algorithm
    beq
        b_eq parameter of the algorithm
    parameters
        Possible parameters of the algorithm

    Returns
    -------------
    sol
        Solution of the LP problem by the given algorithm
    """
    if parameters is None:
        parameters = {}

    require_ilp = exec_utils.get_param_value(Parameters.REQUIRE_ILP, parameters, False)

    Aub = np.asmatrix(Aub)
    if type(bub) is list and len(bub) == 1:
        bub = bub[0]
    if Aeq is not None:
        Aeq = np.asmatrix(Aeq)
    if beq is not None and type(beq) is list and len(beq) == 1:
        beq = beq[0]

    prob = LpProblem("", LpMinimize)

    x_list = []
    for i in range(Aub.shape[1]):
        if require_ilp:
            x_list.append(LpVariable("x_" + get_terminal_part_name_num(i), cat='Binary'))
        else:
            x_list.append(LpVariable("x_" + get_terminal_part_name_num(i)))

    eval_str = ""
    expr_count = 0
    for j in range(len(c)):
        if abs(c[j]) > MIN_THRESHOLD:
            if expr_count > 0:
                eval_str = eval_str + " + "
            eval_str = eval_str + str(c[j]) + "*x_list[" + str(j) + "]"
            expr_count = expr_count + 1
    eval_str = eval_str + ", \"objective\""
    prob += eval(eval_str)

    for i in range(Aub.shape[0]):
        expr_count = 0
        eval_str = 0
        eval_str = ""
        for j in range(Aub.shape[1]):
            if abs(Aub[i, j]) > MIN_THRESHOLD:
                if expr_count > 0:
                    eval_str = eval_str + " + "
                eval_str = eval_str + str(Aub[i, j]) + "*x_list[" + str(j) + "]"
                expr_count = expr_count + 1
        eval_str = eval_str + "<=" + str(
            bub[i].reshape(-1, ).tolist()[0][0]) + ", \"vinc_" + get_terminal_part_name_num(i) + "\""

        prob += eval(eval_str)

    if Aeq is not None and beq is not None:
        for i in range(Aeq.shape[0]):
            expr_count = 0
            eval_str = 0
            eval_str = ""
            for j in range(Aeq.shape[1]):
                if abs(Aeq[i, j]) > MIN_THRESHOLD:
                    if expr_count > 0:
                        eval_str = eval_str + " + "
                    eval_str = eval_str + str(Aeq[i, j]) + "*x_list[" + str(j) + "]"
                    expr_count = expr_count + 1
            if eval_str:
                eval_str = eval_str + "==" + str(beq[i].reshape(-1, ).tolist()[0][0]) + ", \"vinceq_" + get_terminal_part_name_num(
                    i + 1 + Aub.shape[0]) + "\""

                prob += eval(eval_str)

    filename = tempfile.NamedTemporaryFile(suffix='.lp').name
    prob.writeLP(filename)
    PULP_CBC_CMD(msg=0).solve(prob)

    return prob
Пример #21
0
#問題定義
p = LpProblem(name="SpreadingPointsProblem", sense=LpMaximize)

#zの最大化問題として定義
p += z

#N個のPointが配置される
tmp_sub = 0
for i, j in product(range(SIZE), range(SIZE)):
    tmp_sub += x[(i, j)]
p += tmp_sub == N

#確認した2点に同時に点が配置されているとしたばあい、その距離はz以上
BIGM = 100.0
for i, j in product(range(SIZE), range(SIZE)):
    for k, l in product(range(SIZE), range(SIZE)):
        if i == k and j == l:
            continue
        #x[(i,j)] x[(k,l)]が両方1のときのみ意味ある不等式となる。
        p += z <= (1 - x[(i, j)]) * BIGM + (1 - x[(k, l)]) * BIGM + dist(
            (i, j), (k, l))

solver = PULP_CBC_CMD(msg=0, mip=True, threads=15)
p.solve(solver)
print(LpStatus[p.status])
print(f"Best Distance@{N}points = {value(p.objective)}")

#結果出力
for j in range(SIZE):
    print(",".join(str(int(x[(j, i)].value())) for i in range(SIZE)))
Пример #22
0
def steiner_tree(g, term):
    lp, x = __get_formulae(g, term)
    lp.writeLP('steiner_tree.lp')
    PULP_CBC_CMD(msg=0).solve(lp)
    return nx.Graph((e for e in x if x[e].varValue > 0))
Пример #23
0
def optimization_setup(distance_df, clump_df, threshold, clump_size_list, clump_ratio_list, group_label, time_limit, top_end_threshold, aisle_indicator):
    tic_o = time.perf_counter()
    print("Deleting the single node loops")
    # removing the single node loops, so that optimization runs easier
    delete_index = []
    for i in range(len(distance_df)):
        if distance_df.orig[i] == distance_df.dest[i]:
            delete_index.append(i)
            ######## checking for feasibility
        if distance_df.dist[i] > top_end_threshold:
            delete_index.append(i)
    distance_df = distance_df.drop(index=delete_index)
    distance_df = distance_df.reset_index(drop=True)
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    # removing the aisle nodes, as indicated by the user
    if aisle_indicator == "no_aisle_seats":
        print("Removing Aisle Seats")
        delete_index = []
        for i in range(len(clump_df)):
            if clump_df.aisle_cluster[i] == 1:
                delete_index.append(i)
        clump_df = clump_df.drop(index=delete_index)
        clump_df = clump_df.reset_index(drop=True)
        toc_o_c = time.perf_counter()
        print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
                
    busy_string = '1-'+group_label
    def cut_variable_strings(variable_list):
        if type(variable_list[0]) is tuple:
            return [tuple([item.replace(busy_string,'').replace('-','') for item in tuple_item]) for tuple_item in variable_list]
        else:
            return [item.replace(busy_string,'').replace('-','') for item in variable_list]
    
    
    # where ratios are of interest, aka 20% 4 seat clusters 80% 2 seat clusters, these individual nodes need to be created
    print("Creating specific nodes for ratios")
    if len(clump_ratio_list) >= 2:
        nodesA = cut_variable_strings(clump_df[clump_df.clump_size == clump_size_list[0]].seatclumpid.tolist())
        nodesB = cut_variable_strings(clump_df[clump_df.clump_size == clump_size_list[1]].seatclumpid.tolist())
        BAratio = clump_ratio_list[1]/clump_ratio_list[0]
    if len(clump_ratio_list) >= 3:
        nodesC = cut_variable_strings(clump_df[clump_df.clump_size == clump_size_list[2]].seatclumpid.tolist())
        CBratio = clump_ratio_list[2]/clump_ratio_list[1]
    if len(clump_ratio_list) >= 4:
        nodesD = cut_variable_strings(clump_df[clump_df.clump_size == clump_size_list[3]].seatclumpid.tolist())
        DCratio = clump_ratio_list[3]/clump_ratio_list[2]
    if len(clump_ratio_list) >= 5:
        print("optimization method only set up for 4 types of seat clumps and even that can be ridiculous to optimize against")
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    print("Creating standard nodes")
    # create the standard list of nodes (seat clumps)
    nodes = clump_df.seatclumpid.tolist()
    nodes = cut_variable_strings(nodes)
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    # TODO for aisles if that's something of interest
    #if aisle_indicator == 'force_aisle_seats':
    #print("Creating the aisles")
    # create the standard node aisle indicators
    #aisles = dict(zip(clump_df.seatclumpid, clump_df.aisle_clump))
    #toc_o_c = time.perf_counter()
    #print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    print("Creating the dictionary for nodes")
    # create a dictionary for those nodes and their value (clump size)
    sizes = dict(zip(nodes, clump_df.clump_size))
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    

    print("Creating standard arcs")
    # create a set of nodes to represent arcs (tuple)
    # turn arc set into list
    arcs = distance_df.arc_set.tolist()
    arcs = cut_variable_strings(arcs)
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    print("Creating the dictionary for arcs")
    # create a dictionary of those sets with distances
    dists = dict(zip(arcs, distance_df.dist))
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    print("Creating the variables for acrcs and nodes")
    # OPTIMIZATION MODEL BEGINS
    # Creates the Variables as Integers
    arcvars = LpVariable.dicts("Arc",arcs,0,1,LpBinary)
    nodevars = LpVariable.dicts("Node",nodes,0,1,LpBinary)

    # creates a heavier optimization problem, but allows the flexibility of 2 vs 3 or 3 vs 4 seat clusters
    print("Creating the variables for specific nodes for ratios")
    if len(clump_ratio_list) >= 2:
        nodeAvars = LpVariable.dicts("NodeA",nodesA,0,1,LpBinary)
        nodeBvars = LpVariable.dicts("NodeB",nodesB,0,1,LpBinary)        
    if len(clump_ratio_list) >= 3:
        nodeCvars = LpVariable.dicts("NodeC",nodesC,0,1,LpBinary)
    if len(clump_ratio_list) >= 4:
        nodeDvars = LpVariable.dicts("NodeD",nodesD,0,1,LpBinary)
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    print("Initializing the MIP")
    # Creates the 'prob' variable to contain the problem data    
    prob = LpProblem("Maximum Capacity Problem", LpMaximize)

    print("Setting up the objective function")
    # Creates the objective function
    # here's where we would implement weighting for specific seats
    prob += lpSum([nodevars[n]* sizes[n] for n in nodes]), "Total Capacity"
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    
    print("Setting up the first set of constraints, arcs = must exist between two nodes that exist")
    # Constraint set #1: insuring that if two nodes exist, the arc between them must exist    
    for j in nodes:    
        for k in nodes:
            if j != k:
                try:
                    prob += 1 + arcvars[(j,k)] >= nodevars[k]+nodevars[j]
                except KeyError:
                    pass
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    
    print("Setting up the second set of constraints, arcs can only exist if they're longer than the threshold")
    # Constraint set #2: each arc used must have a distance greater than the threshold
    for a in arcs:
        prob += arcvars[a]*dists[a] >= threshold*arcvars[a]
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    print("Setting up the third set of constraints, nodes must exist in both the specific listing and the standard listing if specific arc required for ratio")
    # Constraint set #3: only if there are multiple clump sizes required, make sure they correspond to the typical nodes
    if len(clump_ratio_list) >= 2:
        for a in nodesA:
            prob += nodeAvars[a] == nodevars[a]
        for b in nodesB:
            prob += nodeBvars[b] == nodevars[b]
    if len(clump_ratio_list) >= 3:
        for c in nodesC:
            prob += nodeCvars[c] == nodevars[c]
    if len(clump_ratio_list) >= 4:
        for d in nodesD:
            prob += nodeDvars[d] == nodevars[d]
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    if len(clump_ratio_list) >= 2:
        print("Setting up the fourth set of constraints, the number of arcs in a specific set must fall between 10% of the previous node")
    # Constraint set #4: make sure the ratios of clumps align with what's requested, window of 10%ish
    # window reduced to one constraint per option, indicating that if the number of cluster is increasing
    # it will head for that upper bound as it is more efficient
    if len(clump_ratio_list) >= 2:
        prob += lpSum([nodeBvars[n] for n in nodesB]) <= lpSum([nodeAvars[n] for n in nodesA])*1.1*BAratio
        #prob += lpSum([nodeBvars[n] for n in nodesB]) >= lpSum([nodeAvars[n] for n in nodesA])*0.9*BAratio
    if len(clump_ratio_list) >= 3:
        prob += lpSum([nodeCvars[n] for n in nodesC]) <= lpSum([nodeBvars[n] for n in nodesB])*1.1*CBratio
        #prob += lpSum([nodeCvars[n] for n in nodesC]) >= lpSum([nodeBvars[n] for n in nodesB])*0.9*CBratio
    if len(clump_ratio_list) >= 4:
        prob += lpSum([nodeDvars[n] for n in nodesD]) <= lpSum([nodeCvars[n] for n in nodesC])*1.1*DCratio
        #prob += lpSum([nodeDvars[n] for n in nodesD]) >= lpSum([nodeCvars[n] for n in nodesC])*0.9*DCratio
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    # TODO if aisles are indicated as a point of interest
    #if aisle_indicator == 'no_aisle_seats':
    #print("Setting up the fifth set of constraints, inclusion or exclusion of aisle seats")
    # Constraint set #4: make sure the ratios of clumps align with what's requested, window of 10%ish
    # window reduced to one constraint per option, indicating that if the number of cluster is increasing
    # it will head for that upper bound as it is more efficient
    #for n in nodes:
    #    prob += nodesvars[n]*aisles[n] == 0
    
    #if aisle_indicator == 'force_aisle_seats': not sure this is possible, don't uncomment before finding a reason to move forward here
    #print("Setting up the fifth set of constraints, inclusion or exclusion of aisle seats")
    # Constraint set #4: make sure the ratios of clumps align with what's requested, window of 10%ish
    # window reduced to one constraint per option, indicating that if the number of cluster is increasing
    # it will head for that upper bound as it is more efficient
    #for n in nodes:
    #    prob += nodesvars[n]*aisles[n] ?????
    
    #toc_o_c = time.perf_counter()
    #print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    
    
    
    print("Writing the LP or MPS file now")
    # The problem data is written to an lp or mps file
    # this file can be run on the NEOS server or other optimization servers if you're facing timeout issues or low compute abilities
    prob.writeLP("LP Files/stadium_MCP"+group_label+".lp")
    #prob.writeLP("MPS files/stadium_MCP"+group_label+".mps")
    toc_o_c = time.perf_counter()
    print(f"... {toc_o_c-tic_o:0.4f} seconds have elapsed")
    
    # The problem is solved using PuLP's choice of Solver
    prob.solve(PULP_CBC_CMD(maxSeconds = time_limit, msg = 1, fracGap=0.01))
    # The optimised objective function value is printed to the screen    
    output_val = value(prob.objective)
    print("Total Capacity = ", output_val)
    
    # creates the variables indicating that those clusters were in fact chosen in the optimal list
    TOL = 0.01
    node_ind = []
    for n in nodes:
        if nodevars[n].varValue > TOL:
            node_ind.append(1)
        else:
            node_ind.append(0)

    clump_df['clump_ind'] = node_ind
    
    clump_sum_df = clump_df[['clump_size', 'clump_ind']]
    clump_sum_df = clump_sum_df.groupby(['clump_size']).sum().reset_index()
    
    # creating a size dataframe to understand the final clusters and final cluster ratios
    clump_size_for_df = []
    clump_amount_for_df = []
    for i in range(len(clump_sum_df)):
        clump_size_for_df.append("clusters of "+str(clump_sum_df.clump_size[i]))
        clump_amount_for_df.append(clump_sum_df.clump_ind[i])
        
    size_df = pd.DataFrame([clump_amount_for_df], columns = clump_size_for_df)

    # saves the optimized seats to the Optimized Seats folder so that optimization does not have to run again
    group_item_name = 'group_label_'+group_label+'_opt_seats'
    clump_df.to_csv('Optimized Seats/'+group_item_name+'.csv')
    
    # prints and returns the optimization time, important for experimentation and evolution
    toc_o = time.perf_counter()
    opt_time_num = round(toc_o-tic_o,2)
    print(opt_time_num)
    opt_time = group_label+f" took {toc_o-tic_o:0.4f} seconds\n"
    print(f"Total Optimization for "+opt_time+f" or {(toc_o-tic_o)/60:0.1f} minutes with tolerance")
    
    return opt_time, opt_time_num, output_val, clump_df, size_df
Пример #24
0
from conference_scheduler import scheduler
from conference_scheduler.heuristics import hill_climber
from conference_scheduler.heuristics import simulated_annealing
from conference_scheduler.lp_problem.objective_functions import (
    efficiency_capacity_demand_difference, equity_capacity_demand_difference,
    number_of_changes)
from pulp import GLPK
from pulp import PULP_CBC_CMD

logger = daiquiri.getLogger(__name__)

solvers = {
    'pulp_cbc_cmd': {
        'function': scheduler.solution,
        'kwargs': {
            'solver': PULP_CBC_CMD(msg=False)
        }
    },
    'glpk': {
        'function': scheduler.solution,
        'kwargs': {
            'solver': GLPK(msg=False)
        }
    },
    'hill_climber': {
        'function': scheduler.heuristic,
        'kwargs': {
            'algorithm': hill_climber
        }
    },
    'simulated_annealing': {
Пример #25
0
from pulp import LpProblem, LpMinimize, LpVariable, LpStatus, value

from pm4py.util import exec_utils
from pm4py.util.lp.parameters import Parameters

MIN_THRESHOLD = 10**-12
# max safe number of constraints (log10)
MAX_NUM_CONSTRAINTS = 7

# keeps compatibility with 1.6.x versions of PuLP in which the interface
# for solving was the latter one
if hasattr(pulp, "__version__"):
    # new interface
    from pulp import PULP_CBC_CMD

    solver = lambda prob: PULP_CBC_CMD(msg=0).solve(prob)
else:
    # old interface
    solver = lambda prob: prob.solve()


def get_terminal_part_name_num(num):
    """
    Gets the terminal part of the name of a variable

    Parameters
    ---------------
    nam
        Name

    Returns
Пример #26
0
def lrs_ilp(s, verbosity=0):
    if len(s) == 1:
        return Solution(1, [[s[0]]])
    try:
        try:
            from pulp import (
                LpVariable,
                LpProblem,
                LpMaximize,
                LpInteger,
                PulpSolverError,
            )

            model = LpProblem("LRS", LpMaximize)

            # create variables
            x = [
                LpVariable("x_{}".format(i), 0, 1, LpInteger)
                for i in range(len(s))
            ]

            # node degree
            for j in range(len(s)):
                for i in range(j):
                    if s[i].char == s[j].char:
                        model += (j - i) * x[i] + sum([
                            x[l] if s[l].char != s[i].char else 0
                            for l in range(i + 1, j)
                        ]) + (j - i) * x[j] <= 2 * (j - i)

            # objective
            model += sum([x[i] * s[i].length for i in range(len(s))])

            # depending on pulp version, solvers have to be created differently
            try:
                from pulp import getSolver, listSolvers

                solvers = [getSolver(s, msg=0) for s in listSolvers()]
            except:
                from pulp import COIN_CMD, PULP_CBC_CMD, PulpSolverError

                solvers = [COIN_CMD(msg=0), PULP_CBC_CMD(msg=0)]

            solved = False
            for solver in solvers:
                if solved:
                    break
                try:
                    model.solve(solver)
                    solved = True
                except PulpSolverError:
                    pass

            if not solved:
                raise ImportError

            sol = [s[i] for i in range(len(s)) if x[i].varValue > 0.999]

            return Solution(sum([run.length for run in sol]), [sol])
        except (ModuleNotFoundError, ImportError) as e:
            if verbosity == 1:
                print(
                    "PuLP itself or some of its properties could not be loaded. Solving model with DP instead."
                )
            elif verbosity >= 2:
                print("Error loading PuLP solver:")
                print(e)
                print("Solving model with DP instead.")
            return lrs_dp(s)
    except:
        if verbosity >= 1:
            print(
                "Unexpected error occured while loading PuLP. Solving model with DP instead."
            )
        return lrs_dp(s)
Пример #27
0
def OPT(wcet):

    task_count, core_count = wcet.shape
    """
    
    wcet = dict()
    for task in range(task_count):
        for cpu in range(core_count):
            fit_count = 0
            #print(M)
            for i in M[:,cpu]:
                if i == 1:
                    fit_count += 1
            fit_value = 1/fit_count
            not_fit_value = fit_value + 0.1

            if M[task,cpu] == 1:
                wcet[(task, cpu)] = fit_value
            else:
                wcet[(task, cpu)] = not_fit_value
    """


    # Create the model
    model = LpProblem(name="partition-partition-scheduler", sense=LpMinimize)

    # Initialize the decision variables
    x_variables = dict()
    for t in range(task_count):
        for j in range(core_count):
            if (t, j) not in x_variables:
                x_variables[(t, j)] = LpVariable(name="x_task{}_cpu{}".format(t, j), lowBound=0, cat="Binary")
    y_variables = dict()
    for j in range(core_count):
        if j not in y_variables:
            y_variables[j] = LpVariable(name="y_{}".format(j), lowBound=0, cat="Binary")

    # Add the constraints to the model
    for t in range(task_count):
        model += (lpSum([x_variables[(t, j)] for j in range(core_count)]) == 1, "One_assignment_constraint{}".format(t))

    for j in range(core_count):
        model += (
            lpSum([x_variables[(t, j)] * wcet[t,j]  for t in range(task_count)]) <= 1 * y_variables[j],
            "EDF constraint on CPU{}".format(j))

    # Add the objective function to the model
    obj_func = lpSum(y_variables)
    model += obj_func

    # The problem data is written to an .lp file
    model.writeLP("TestProblem.lp")

    # Solve the problem
    #status = model.solve()
    status = None
    time_limit = 900
    status = model.solve(PULP_CBC_CMD(msg=0, timeLimit=time_limit, threads=1))

    #print("-------------------------------------------------------")
    #print(f"status: {model.status}, {LpStatus[model.status]}")
    #print(f"objective: {model.objective.value()}")

    #for var in model.variables():
    #    print(f"{var.name}: {var.value()}")

    #for name, constraint in model.constraints.items():
    #    print(f"{name}: {constraint.value()}")

    #print("Solver: {}".format(model.solver))

    if model.solutionTime > time_limit:
        return np.inf, LpStatus[model.status]
    elif status == 1:
        return model.objective.value(), LpStatus[model.status]
    else:
        #print("OPT is not optimal solution! Reason: {}".format(LpStatus[model.status]))
        return np.inf, LpStatus[model.status]
Пример #28
0
def optimize_scenario(rate_of_return_6m: float,
                      rate_of_return_12m: float,
                      rsu_witholding_rate: float,
                      current_state_ltcg_tax_rate: float,
                      current_state_stcg_tax_rate: float,
                      new_state_ltcg_tax_rate: float,
                      new_state_stcg_tax_rate: float,
                      federal_ltcg_tax_rate: float,
                      federal_stcg_tax_rate: float,
                      share_basis_price: float,
                      pre_tax_num_shares: float,
                      alternate_investment_rate_of_return: float,
                      moving_costs: float,
                      debug: bool = False) -> dict:
    """
    This is the meat of the script that calculates the optimal number of shares to sell for short and long term tax
    rates and in your current or new state. It models this as a linear programming problem, which finds the variable
    values that maximize the objective function given constraints.

    :param rate_of_return_6m: The 6-month rate of return for your shares for the first six months after IPO
    :param rate_of_return_12m: The 6-month rate of return for your shares for the second six months after IPO
    :param rsu_witholding_rate: How many of your vested shares are withheld for taxes
        (typically, companies withhold 22 percent)
    :param current_state_ltcg_tax_rate: The long term capital gains tax rate of your current state
        (if no separate rate exists, you likely should use your marginal state income tax rate)
    :param current_state_stcg_tax_rate: The short term capital gains tax rate of you current state
    :param new_state_ltcg_tax_rate: The long term capital gains tax rate of you prospective new state
    :param new_state_stcg_tax_rate: The short term capital gains tax rate of you prospective new state
    :param federal_ltcg_tax_rate: The federal long term capital gains tax rate for your shares
    :param federal_stcg_tax_rate: The federal short term capital gains tax rate for your shares
    :param share_basis_price: The cost basis of your stock grant, likely the IPO price
    :param pre_tax_num_shares: Your vested shares that are becoming liquid through IPO
    :param alternate_investment_rate_of_return: If you sell your shares at 6 months, the rate of return you expect from
        investing those proceeds elsewhere
    :param moving_costs: How much more moving to the new state must save you to make it worthwhile to move. Can be
        actual expenses or a reasonable margin
    :param debug: Prints out more info about this optimization
    :return: A dictionary with the parameters of the optimal solution
    """

    # Derived inputs
    post_tax_num_shares = pre_tax_num_shares * (1 - rsu_witholding_rate)

    # Create the linear programming model
    model = LpProblem(name="optimize_returns", sense=LpMaximize)

    # Variables that will be optimized in the model
    current_state_stcg_num_shares = LpVariable(name="current_state_stcg_num_shares", lowBound=0,
                                               upBound=post_tax_num_shares)
    current_state_ltcg_num_shares = LpVariable(name="current_state_ltcg_num_shares", lowBound=0,
                                               upBound=post_tax_num_shares)
    new_state_stcg_num_shares = LpVariable(name="new_state_stcg_num_shares", lowBound=0, upBound=post_tax_num_shares)
    new_state_ltcg_num_shares = LpVariable(name="new_state_ltcg_num_shares", lowBound=0, upBound=post_tax_num_shares)
    is_moving = LpVariable(name="is_moving", lowBound=0, upBound=1, cat="Integer")

    # Calculations used in the constraints and objective functions below
    short_term_price = share_basis_price * rate_of_return_6m
    long_term_price = short_term_price * rate_of_return_12m
    current_state_stcg = current_state_stcg_num_shares * (short_term_price - share_basis_price)
    current_state_ltcg = current_state_ltcg_num_shares * (long_term_price - share_basis_price)
    new_state_stcg = new_state_stcg_num_shares * (short_term_price - share_basis_price)
    new_state_ltcg = new_state_ltcg_num_shares * (long_term_price - share_basis_price)
    current_state_short_term_proceeds = current_state_stcg_num_shares * short_term_price
    current_state_alternate_investment_gain = (current_state_short_term_proceeds * alternate_investment_rate_of_return) \
                                              - current_state_short_term_proceeds
    new_state_short_term_proceeds = new_state_stcg_num_shares * short_term_price
    new_state_alternate_investment_gain = (new_state_short_term_proceeds * alternate_investment_rate_of_return) \
                                          - new_state_short_term_proceeds
    total_capital_gains = current_state_stcg + new_state_stcg + current_state_ltcg + new_state_ltcg \
                          + current_state_alternate_investment_gain + new_state_alternate_investment_gain
    post_tax_capital = post_tax_num_shares * share_basis_price

    # Constraints of the model
    model += (post_tax_num_shares == current_state_stcg_num_shares + current_state_ltcg_num_shares
              + new_state_stcg_num_shares + new_state_ltcg_num_shares,
              "total_shares_sum")

    # Makes is_moving a flag dependent on whether we have new_state capital gains
    model += (is_moving <= (new_state_stcg_num_shares + new_state_ltcg_num_shares),
              "new_state_shares_sold_dependency")
    model += ((new_state_stcg_num_shares + new_state_ltcg_num_shares) <= is_moving * post_tax_num_shares,
              "new_state_shares_sold_flag")

    # Objective function we are optimizing
    total_earnings = (post_tax_capital + total_capital_gains) \
                     - current_state_stcg * (federal_stcg_tax_rate + current_state_stcg_tax_rate) \
                     - current_state_ltcg * (federal_ltcg_tax_rate + current_state_ltcg_tax_rate) \
                     - new_state_stcg * (federal_stcg_tax_rate + new_state_stcg_tax_rate) \
                     - new_state_ltcg * (federal_ltcg_tax_rate + new_state_ltcg_tax_rate) \
                     - current_state_alternate_investment_gain * (federal_stcg_tax_rate + current_state_stcg_tax_rate) \
                     - new_state_alternate_investment_gain * (federal_stcg_tax_rate + new_state_stcg_tax_rate) \
                     - moving_costs * is_moving
    model += total_earnings

    msg = False
    if debug:
        msg = True
    status = model.solve(PULP_CBC_CMD(msg=msg))
    if status != 1:
        print(f"status: {model.status}, {LpStatus[model.status]}")
        raise Exception("No solution for scenario")

    if debug:
        print(model)
        for name, constraint in model.constraints.items():
            print(f"{name}: {constraint.value()}")

        for var in model.variables():
            print(f"{var.name}: {var.value()}")

    results = {
        "short_term_price": short_term_price,
        "long_term_price": long_term_price,
        "rate_of_return_6m": rate_of_return_6m,
        "rate_of_return_12m": rate_of_return_12m,
        "objective": model.objective.value(),
    }
    for var in model.variables():
        results[var.name] = var.value()

    return results
Пример #29
0
class PuLPSolver(Solver):
    LP_SOLVER = PULP_CBC_CMD(msg=False)

    def __init__(self):
        self.prob = LpProblem('pydfs_lineup_optimizer', LpMaximize)

    def setup_solver(self):
        pass

    def add_variable(self, name, min_value=None, max_value=None):
        name = name.replace(' ', '_')
        if any([min_value, max_value]):
            return LpVariable(name,
                              lowBound=min_value,
                              upBound=max_value,
                              cat=LpInteger)
        return LpVariable(name, cat=LpBinary)

    def set_objective(self, variables, coefficients):
        self.prob += lpSum([
            variable * coefficient
            for variable, coefficient in zip(variables, coefficients)
        ])

    def add_constraint(self, variables, coefficients, sign, rhs, name=None):
        if coefficients:
            lhs = [
                variable * coefficient
                for variable, coefficient in zip(variables, coefficients)
            ]
        else:
            lhs = variables
        if sign == SolverSign.EQ:
            self.prob += lpSum(lhs) == rhs, name
        elif sign == SolverSign.NOT_EQ:
            self.prob += lpSum(lhs) != rhs, name
        elif sign == SolverSign.GTE:
            self.prob += lpSum(lhs) >= rhs, name
        elif sign == SolverSign.LTE:
            self.prob += lpSum(lhs) <= rhs, name
        else:
            raise SolverException('Incorrect constraint sign')

    def copy(self):
        new_solver = type(self)()
        new_solver.prob = self.prob.copy()
        return new_solver

    def solve(self):
        self.prob.solve(self.LP_SOLVER)
        if self.prob.status == LpStatusOptimal:
            result = []
            for variable in self.prob.variables():
                val = variable.value()
                if val is not None and round(val) >= 1.0:
                    result.append(variable)
            return result
        else:
            invalid_constraints = [
                (name or str(constraint))
                for name, constraint in self.prob.constraints.items()
                if not constraint.valid()
            ]
            raise SolverInfeasibleSolutionException(invalid_constraints)
Пример #30
0
bincolumns = [
    col for col in df.columns if len(df[col].unique()) <= 3 and col != "page"
]
df = df.rename(columns={name: name + "bin" for name in bincolumns})
intcolumns = [
    col for col in df.columns if len(df[col].unique()) > 3 and col != "page"
]
df = df.rename(columns={name: name + "int" for name in intcolumns})

#End Preprocessing step
print "Total rows (M) after preprocessing: %i" % len(df)

#Start Solving Rank LP's

#specify solving method (add more here for whichever methods are installed)
solver = PULP_CBC_CMD()  #default, comes with pulp
#solver=GLPK()

####2016-10-08 [Evan] Make upper/lower bounds variable
#upperA = 100    ###(default 10)  ###copy this into params: ubound_a=upperA
#upperV = 100    ###(default 100) ###copy this into params: ubound_v=upperV
#lowerA = .001    ###(default .01) ###copy this into params: lbound_a=lowerA
lowerV = 1  ###(default .01) ###copy this into params: lbound_v=lowerV

pageset = {1: range(1, 2), 2: range(2, 4), 3: range(4, 8)}

#### NEED TO ADD: progressbar

threshes = {"bin": (.5, 2, 8), "int": (.02, .1, 1)}
threshloop = [(a, b) for a in threshes["bin"] for b in threshes["int"]]