Example #1
0
def add_constraints(opt_model, const_df):
    const_count = 0
    for index, row in const_df.iterrows():
        const_count += 1
        if row['SIGN'] == '':
            continue
        elif row['SIGN'] == '<=': 
            const_sign = plp.LpConstraintLE
        else:
            const_sign = plp.LpConstraintGE
        if row['LEFT HAND SIDE'] == '# OF POKEMON':
            new_const = plp.LpConstraint(
                             e=plp.lpSum(x_vars[p] for p in pokes),
                             sense=const_sign,
                             rhs=int(row['RIGHT HAND SIDE']),
                             name="constraint_{0}".format(const_count))
        elif 'TOTAL' in row['LEFT HAND SIDE']:
            my_const_stat = list(compress(poke_stats, [s in row['LEFT HAND SIDE'] for s in poke_stats]))[0]
            new_const = plp.LpConstraint(
                             e=plp.lpSum(x_vars[p] * param_stats.get((p, my_const_stat)) for p in pokes),
                             sense=const_sign,
                             rhs=int(row['RIGHT HAND SIDE']),
                             name="constraint_{0}".format(const_count))
        elif 'TYPE' in row['LEFT HAND SIDE']:
            my_type = list(compress(poke_types, [t in row['LEFT HAND SIDE'] for t in poke_types]))[0]
            new_const = plp.LpConstraint(
                             e=plp.lpSum(x_vars[p] * param_types.get((p, my_type)) for p in pokes),
                             sense=const_sign,
                             rhs=int(row['RIGHT HAND SIDE']),
                             name="constraint_{0}".format(const_count))
        opt_model += new_const
    return(opt_model)
Example #2
0
    def _create_constraints(self, variables, nutrients, food_items,
                            expressions):
        """Create LP problem constraints

		Args:
			variables: Dictionary with problem variables
			nutrients: Nutrients to use in the problem formulation
			food_items: Food items to use in the problem formulation

		Returns:
			List of constraints to apply to the problem
		"""
        constraints = []

        # Iterate all nutrients to create constraints
        for nutrient_id, nutrient_data in nutrients.items():

            max_nutrient_amount_constraint = pulp.LpConstraint(
                e=expressions[
                    self.NUTRIENTS_QTY_EXPRESSIONS_CATEGORY][nutrient_id],
                sense=pulp.LpConstraintLE,
                rhs=nutrient_data["constraints"]["max"],
                name='_'.join([nutrient_id, "max"]))
            constraints.append(max_nutrient_amount_constraint)

            min_nutrient_amount_constraint = pulp.LpConstraint(
                e=expressions[
                    self.NUTRIENTS_QTY_EXPRESSIONS_CATEGORY][nutrient_id],
                sense=pulp.LpConstraintGE,
                rhs=nutrient_data["constraints"]["min"],
                name='_'.join([nutrient_id, "min"]))
            constraints.append(min_nutrient_amount_constraint)

            # Demerits constrain => use max(of deviation)
            if self.use_demerits:
                # Nutrient variation
                nutrient_demerits_variable = variables['nutrient_demerit'][
                    nutrient_id]

                nutrient_deviation_constraint = pulp.LpConstraint(
                    e=nutrient_demerits_variable -
                    (expressions[self.NUTRIENTS_VARIATION_EXPRESSIONS_CATEGORY]
                     [nutrient_id] *
                     nutrient_data["weights"]["overconsumption"]),
                    sense=pulp.LpConstraintGE,
                    rhs=0.,
                    name='_'.join([nutrient_id, "dev"]))
                constraints.append(nutrient_deviation_constraint)

                nutrient_deviation_ve_constraint = pulp.LpConstraint(
                    e=nutrient_demerits_variable -
                    (-expressions[self.NUTRIENTS_VARIATION_EXPRESSIONS_CATEGORY]
                     [nutrient_id] *
                     nutrient_data["weights"]["overconsumption"]),
                    sense=pulp.LpConstraintGE,
                    rhs=0.,
                    name='_'.join([nutrient_id, "dev_ve"]))
                constraints.append(nutrient_deviation_ve_constraint)

        return constraints
Example #3
0
    def general_constr(self):
        # Making sure if you enter a node, you leave the same node (flow continuity)
        for k in range(self.drone_amount):
            for h in range(0, self.i):
                self.pm.addConstraint(
                    plp.LpConstraint(
                        plp.lpSum(self.x_vars[i, h, k]
                                  for i in self.value_list[h]) -
                        plp.lpSum(self.x_vars[h, j, k]
                                  for j in self.value_list[h]) == 0))

        # Making sure all the nodes are visited
        for i in range(0, self.i):
            if i not in self.charge_nodes:
                self.pm.addConstraint(
                    plp.LpConstraint(
                        plp.lpSum(self.x_vars[i, j, k]
                                  for j in self.value_list[i]
                                  for k in range(self.drone_amount)) >= 1))

        # Making sure all the drones leave the home station
        for k in range(self.drone_amount):
            self.pm.addConstraint(
                plp.LpConstraint(
                    plp.lpSum(self.x_vars[0, j, k]
                              for j in self.value_list[0]) == 1))
Example #4
0
def get_optimal_quantities(
    y: {'coin name': 'amount_held'}, x: ['coin names'],
    c: {'coin name': 'cost'}, p: {'coin name': 'current price'},
    B: 'Int: budget', f: {'coin name': 'max fraction in portfolio'}) -> {
        'coin name': 'quantity'
    }:
    problem = plp.LpProblem("Crypto-currency porfolio", sense=plp.LpMaximize)
    x_var = {(i): plp.LpVariable(cat=plp.LpContinuous, name="x{0}".format(i))
             for i in x}
    problem += plp.LpConstraint(e=plp.lpSum(x_var[i] * c[i] for i in x),
                                sense=plp.LpConstraintLE,
                                rhs=B,
                                name="budget")
    for i in x:
        problem += plp.LpConstraint(e=x_var[i],
                                    sense=plp.LpConstraintLE,
                                    rhs=f[i] - y[i],
                                    name="limit_{0}".format(i))
        problem += plp.LpConstraint(e=x_var[i],
                                    sense=plp.LpConstraintGE,
                                    rhs=-y[i],
                                    name="amount_constraint{0}".format(i))
    print(problem)
    objective = plp.lpSum(x_var[i] * (p[i] - c[i]) for i in x)
    problem.setObjective(objective)
    problem.solve()
    # opt_df = pd.DataFrame.from_dict(x, orient="index", columns = ["variable_object"])
    # opt_df["solution_value"] = opt_df["variable_object"].apply(lambda item: item.varValue)
    results = {i: x_var[i].varValue for i in x_var}
    return results
Example #5
0
    def charge_constr(self):
        # Set charge at a charging station equal to 100
        for k in range(self.drone_amount):
            for i in self.charge_nodes:
                # Charging station charge equals 100
                self.pm.addConstraint(plp.LpConstraint(self.q[i, k] == 100))

        # Never go below a certain battery level
        for k in range(self.drone_amount):
            for i in range(0, self.i):
                self.pm.addConstraint(
                    plp.LpConstraint(self.q[i, k] >= self.min_charge))

        # Decrease the charge when moving from one node to another
        for k in range(self.drone_amount):
            for i in range(0, self.i):
                for j in self.value_list[i]:
                    if j not in self.charge_nodes:
                        self.pm.addConstraint(
                            plp.LpConstraint(
                                self.q[i, k] - self.q[j, k] -
                                self.charge_constant * self.link(i, j) *
                                self.x_vars[i, j, k] - self.charge_scan +
                                (1 - self.x_vars[i, j, k]) * self.M >= 0))
                    if j in self.charge_nodes:
                        self.pm.addConstraint(
                            plp.LpConstraint(
                                self.q[i, k] - self.charge_constant *
                                self.link(i, j) * self.x_vars[i, j, k] +
                                (1 - self.x_vars[i, j, k]) * self.M >= 0))
Example #6
0
    def time_constr(self):
        # Start at time equal to 0
        for k in range(self.drone_amount):
            self.pm.addConstraint(plp.LpConstraint(self.time[0, k] == 0))

        # Decrease the time when moving from one node to another
        for k in range(self.drone_amount):
            for i in range(0, self.i):
                for j in self.value_list[i]:
                    if j not in self.charge_nodes:
                        self.pm.addConstraint(
                            plp.LpConstraint(
                                self.time[i, k] - self.time[j, k] +
                                self.time_constant * self.link(i, j) *
                                self.x_vars[i, j, k] + self.scan_time -
                                (1 - self.x_vars[i, j, k]) * self.M <= 0))
                        if j != 0:
                            self.pm.addConstraint(
                                plp.LpConstraint(
                                    self.time[i, k] - self.time[j, k] +
                                    self.time_constant * self.link(i, j) *
                                    self.x_vars[i, j, k] + self.charge_time *
                                    (100 - self.q[i, k]) +
                                    self.landing_takeoff_penalty -
                                    (1 - self.x_vars[i, j, k]) * self.M <= 0))
Example #7
0
    def _create_main_constraints(self):
        # Depending on what you need, you may want to consider creating any of
        # the expressions (constraints or objective terms) as an attribute of
        # the OptimizationModel class (e.g. self.inv_balance_constraints).
        # That way if, for example, at the end of the optimization you need to check
        # the slack variables of certain constraints, you know they already exists in your model

        # ================== Inventory balance constraints ==================
        self.inv_balance_constraints = {
            period: add_constr(self.model, pulp.LpConstraint(
                e=self.inventory_variables[period - 1] + self.production_variables[period]
                  - self.inventory_variables[period],
                sense=pulp.LpConstraintEQ,
                name='inv_balance' + str(period),
                rhs=value.demand))
            for period, value in self.input_data.iloc[1:].iterrows()}

        # inv balance for first period
        self.first_period_inv_balance_constraints = add_constr(self.model, pulp.LpConstraint(
            e=self.production_variables[0] - self.inventory_variables[0],
            sense=pulp.LpConstraintEQ,
            name='inv_balance0',
            rhs=self.input_data.iloc[0].demand - self.input_params['initial_inventory']))

        # ================== Production capacity constraints ==================
        self.production_capacity_constraints = {
            index: add_constr(self.model, pulp.LpConstraint(
                e=value,
                sense=pulp.LpConstraintLE,
                name='prod_cap_month_' + str(index),
                rhs=self.input_data.iloc[index].production_capacity))
            for index, value in self.production_variables.items()}
    def solve_problem(obj, tolerance=0.01, threads=1, timeLimit=120):
        material_model = pulp.LpProblem("MaterialProductionModel",
                                        pulp.LpMinimize)

        # Create Equality Constraints that produce the Price and Volume as independent variables.
        price_coefficients = [(mineral, obj.price_per_ore[mineral])
                              for mineral in obj.variable_ore_dict.values()]
        price_coefficients.append((obj.price, -1))
        price_constraint = pulp.LpConstraint(
            pulp.LpAffineExpression(price_coefficients),
            sense=pulp.LpConstraintEQ,
            name='PriceConstraint',
            rhs=0)

        volume_coefficients = [(mineral, obj.volume_per_ore[mineral])
                               for mineral in obj.variable_ore_dict.values()]
        volume_coefficients.append((obj.volume, -1))
        volume_constraint = pulp.LpConstraint(
            pulp.LpAffineExpression(volume_coefficients),
            sense=pulp.LpConstraintEQ,
            name='VolumeConstraint',
            rhs=0)

        material_model += price_constraint
        material_model += volume_constraint

        # Create Cost Function in terms of variables
        # I'll be lazy for now and just minimize price in ISK.
        material_model += (obj.weight_of_price * obj.price +
                           obj.weight_of_volume * obj.volume)

        # Now go through the required materials and impose constraints that ensure we produce the right amount of stuff
        for material, amount in obj.required_materials.items():

            production_expr = pulp.LpAffineExpression(
                obj.yield_per_mineral[material].items())
            production_constraint = pulp.LpConstraint(
                production_expr,
                sense=pulp.LpConstraintGE,
                name='Produce{}'.format(material),
                rhs=amount)

            # Add Constraint to Model
            material_model += production_constraint

        solver = pulp.PULP_CBC_CMD(timeLimit=timeLimit,
                                   gapRel=tolerance,
                                   threads=threads)

        print(material_model)

        material_model.solve(solver)

        # The status of the solution is printed to the screen
        print("Status:", pulp.LpStatus[material_model.status])

        result = dict()
        for v in material_model.variables():
            result[v.name] = v.varValue
        return result
Example #9
0
    def solve(self):

        self.X = []
        for i in range(self.left):
            self.X.append([])
            for j in range(self.right):
                self.X[i].append(
                    pulp.LpVariable(cat=pulp.LpBinary,
                                    name="x" + str(i) + str(j)))

        for i in range(self.left):
            self.m += pulp.LpConstraint(sum(
                [self.X[i][j] for j in range(self.right)]),
                                        sense=pulp.LpConstraintLE,
                                        rhs=1)

        for j in range(self.right):
            self.m += pulp.LpConstraint(sum(
                [self.X[i][j] for i in range(self.left)]),
                                        sense=pulp.LpConstraintLE,
                                        rhs=1)

        for i in range(self.left):
            for j in range(self.right):
                self.m += pulp.LpConstraint(self.X[i][j],
                                            sense=pulp.LpConstraintLE,
                                            rhs=self.A[i, j])

        self.m.setObjective(
            sum([
                self.X[i][j] for i in range(self.left)
                for j in range(self.right)
            ]))

        self.m.solve()
Example #10
0
def add_default_sudoku_constraints(prob, grid_vars, rows, cols, grids, values):

    # Constraint to ensure only one value is filled for a cell
    for row in rows:
        for col in cols:
                prob.addConstraint(plp.LpConstraint(e=plp.lpSum([grid_vars[row][col][value] for value in values]),
                                        sense=plp.LpConstraintEQ, rhs=1, name=f"constraint_sum_{row}_{col}"))


    # Constraint to ensure that values from 1 to 9 is filled only once in a row
    for row in rows:
        for value in values:
            prob.addConstraint(plp.LpConstraint(e=plp.lpSum([grid_vars[row][col][value]*value  for col in cols]),
                                        sense=plp.LpConstraintEQ, rhs=value, name=f"constraint_uniq_row_{row}_{value}"))

    # Constraint to ensure that values from 1 to 9 is filled only once in a column
    for col in cols:
        for value in values:
            prob.addConstraint(plp.LpConstraint(e=plp.lpSum([grid_vars[row][col][value]*value  for row in rows]),
                                        sense=plp.LpConstraintEQ, rhs=value, name=f"constraint_uniq_col_{col}_{value}"))


    # Constraint to ensure that values from 1 to 9 is filled only once in the 3x3 grid
    for grid in grids:
        grid_row  = int(grid/3)
        grid_col  = int(grid%3)

        for value in values:
            prob.addConstraint(plp.LpConstraint(e=plp.lpSum([grid_vars[grid_row*3+row][grid_col*3+col][value]*value  for col in range(0,3) for row in range(0,3)]),
                                        sense=plp.LpConstraintEQ, rhs=value, name=f"constraint_uniq_grid_{grid}_{value}"))
Example #11
0
def TSP(T, k, names):
    # initialize ILP as a min problem
    model = pl.LpProblem(name='Optimizacion_Labiales', sense=pl.LpMinimize)

    # number of lipsticks
    n = len(T)
    N = {x for x in range(1, n + 1)}

    print('\nNúmero de productos a optimizar sus tiempos de producción: ',
          (n - 1))

    # variables
    x = pl.LpVariable.dicts('cambio_labial', ((i, j) for i in N for j in N),
                            cat='Binary')

    # objective function
    z = pl.LpAffineExpression(e=[(x[i, j], T[i - 1, j - 1]) for i, j in x],
                              constant=k,
                              name='Funcion_Objetivo')
    model += z

    # constraints
    # constraint 1: all are visited but only once
    for i in N:
        N_update = N - {i}
        model += pl.LpConstraint(
            [(x[i, j], 1) for j in N_update],
            sense=pl.LpConstraintEQ,
            rhs=1  # right side of the equality
        )

    # constraint 2: all are leaved and only once
    for j in N:
        N_update = N - {j}
        model += pl.LpConstraint(
            [(x[i, j], 1) for i in N_update],
            sense=pl.LpConstraintEQ,
            rhs=1  # right side of the equality
        )

    # subtour elimination
    # aux vars definied by Miller, Tucker and Zemlin
    u = pl.LpVariable.dict('aux_var', (i for i in N), cat='Continuous')

    N0 = N - {1}
    for (i, j) in product(N0, N0):
        if i != j:
            model += pl.LpConstraint(u[i] - u[j] + n * x[i, j],
                                     sense=pl.LpConstraintLE,
                                     rhs=n - 1)
    # solve model
    # solve
    model.solve()

    # print answer
    print_TSP(model, names, k, n)

    return ()
Example #12
0
def add_diagonal_sudoku_constraints(prob, grid_vars, rows, cols, values):

        # Constraint from top-left to bottom-right - numbers 1 - 9 should not repeat
        for value in values:
                prob.addConstraint(plp.LpConstraint(e=plp.lpSum([grid_vars[row][row][value]*value  for row in rows]),
                                            sense=plp.LpConstraintEQ, rhs=value, name=f"constraint_uniq_diag1_{value}"))


        # Constraint from top-right to bottom-left - numbers 1 - 9 should not repeat
        for value in values:
                prob.addConstraint(plp.LpConstraint(e=plp.lpSum([grid_vars[row][len(rows)-row-1][value]*value  for row in rows]),
                                            sense=plp.LpConstraintEQ, rhs=value, name=f"constraint_uniq_diag2_{value}"))
Example #13
0
def solve(dat):
    """
    core solving routine
    :param dat: a good ticdat for the input_schema
    :return: a good ticdat for the solution_schema, or None
    """
    assert input_schema.good_tic_dat_object(dat)
    assert not input_schema.find_foreign_key_failures(dat)
    assert not input_schema.find_data_type_failures(dat)

    model = pulp.LpProblem(name="netflow", sense=pulp.LpMinimize)

    flow = {(h, i, j): pulp.LpVariable(name=f"flow_{h}_{i}_{j}", cat=pulp.LpContinuous, lowBound=0)
            for h, i, j in dat.cost if (i,j) in dat.arcs}

    flowslice = Slicer(flow)

    # Arc Capacity constraints
    for i,j in dat.arcs:
        model.addConstraint(pulp.LpConstraint(
                            e=pulp.lpSum(flow[_h, _i, _j] * dat.commodities[_h]["Volume"]
                                         for _h, _i, _j in flowslice.slice('*', i, j)),
                            rhs=dat.arcs[i,j]["Capacity"],
                            name=f'cap_{i}_{j}', sense=pulp.LpConstraintLE))

    # Flow conservation constraints. Constraints are generated only for relevant pairs.
    # So we generate a conservation of flow constraint if there is negative or positive inflow
    # quantity, or at least one inbound flow variable, or at least one outbound flow variable.
    for h,j in set((h,i) for (h,i), v in dat.inflow.items() if abs(v["Quantity"]) > 0)\
               .union({(h,i) for h,i,j in flow}, {(h,j) for h,i,j in flow}):
        model.addConstraint(pulp.LpConstraint(
            e=pulp.lpSum(flow[h_i_j] for h_i_j in flowslice.slice(h,'*',j)) +
              dat.inflow.get((h, j), {"Quantity": 0})["Quantity"] -
              pulp.lpSum(flow[h_j_i] for h_j_i in flowslice.slice(h, j, '*')),
            rhs=0, # pulp isn't quite as nice as gurobipy, the rhs cannot have expressions
            sense=pulp.LpConstraintEQ,
            name=f'node_{h}_{j}'))

    model.setObjective(pulp.lpSum(flow * dat.cost[h, i, j]["Cost"]
                                 for (h, i, j), flow in flow.items()))
    model.solve()

    if pulp.LpStatus[model.status] == 'Optimal':
        rtn = solution_schema.TicDat()
        for (h, i, j), var in flow.items():
            if var.varValue > 0:
                rtn.flow[h, i, j] = var.varValue
        rtn.parameters["Total Cost"] = sum(dat.cost[h, i, j]["Cost"] * r["Quantity"]
                                           for (h, i, j), r in rtn.flow.items())
        return rtn
Example #14
0
    def constrain(
        self,
        grid: GridProblem[GP],
        right_grid: GridProblem[GPx],
        mode: Literal["right_excludes", "right_implies", "same_as"],
        **kwargs: Any,
    ) -> None:

        assert (
            grid.prob is right_grid.prob
        ), "Passed grids have separate problems!"

        for left, rights in self.cross_map.items():

            left_elem = grid.lpa[..., left.value]
            right_expr = right_grid.lpa[
                ..., [right.value for right in rights]
            ].sum(axis=-1)

            if mode == "right_excludes":
                mode = pulp.LpConstraintLE
            elif mode == "right_implies":
                mode = pulp.LpConstraintGE
            else:
                mode = pulp.LpConstraintEQ

            grid.prob += pulp.LpConstraint(
                left_elem, rhs=right_expr, sense=mode, name=self.name
            )
Example #15
0
    def _add_constraints(self):
        max_node = self.nodes.max()
        for node in self.nodes:

            node_mask = np.zeros(max_node + 1).astype(bool)
            node_mask[node] = True

            in_flow_mask = node_mask[self.graph.edge_index[1]]
            in_flow_edges = self.graph.edge_index.T[in_flow_mask]
            inc_flow = plp.lpSum((self.model_vars[tuple(edge)] for edge in in_flow_edges))
            self.m.addConstraint(plp.LpConstraint(e=inc_flow, sense=plp.LpConstraintLE, rhs=1))

            out_flow_mask = node_mask[self.graph.edge_index[0]]
            out_flow_edges = self.graph.edge_index.T[out_flow_mask]
            out_flow = plp.lpSum((self.model_vars[tuple(edge)] for edge in out_flow_edges))
            self.m.addConstraint(plp.LpConstraint(e=out_flow, sense=plp.LpConstraintLE, rhs=1))
 def addConstr(self, exp1, op=None, exp2=None):
     if op is None:
         assert isinstance(exp1, pulp.LpConstraint)
         the_constr = exp1
     elif isinstance(exp2, float):
         #print("addC/3: exp1 =", exp1, ", op =", op, ", exp2 =", exp2)
         the_constr = pulp.LpConstraint(exp1, op, rhs=exp2)
         #print("constr =", the_constr)
     else:
         #print("addC/3: exp1 =", exp1, ", op =", op, ", exp2 =", exp2)
         #new_exp = exp1 - exp2
         #print(new_exp, type(new_exp))
         the_constr = pulp.LpConstraint(exp1 - exp2, op, rhs=0)
         #print("constr =", the_constr)
     self.constraints.append(the_constr)
     return the_constr
Example #17
0
    def pulp_solve(self):
        problem = pulp.LpProblem(pulp.LpMinimize)

        vs = self.get_vars()
        our_vars = dict()
        v = []
        for i in range(len(vs)):
            v.append(pulp.LpVariable('%d' %vs[i][0], vs[i][1], vs[i][2]))
            our_vars[vs[i][0]] = v[i]

        ob = self.get_objective()
        problem.objective = pulp.LpAffineExpression([(our_vars[ob[i][0]], ob[i][1]) for i in range(len(ob))])

        css = self.get_linear_cons()
        for i in range(len(css)):
            ids, coefs, cnst = css[i]
            c = pulp.LpConstraint(
                pulp.LpAffineExpression([(our_vars[ids[j]], coefs[j]) for j in range(len(coefs))], 
                                        constant=cnst)
                , sense=-1)
            problem.constraints[i] = c
            
        problem.solve()
        self.solutions.clear()
        for variable in problem.variables():
            self.solutions[int(variable.name)] = variable.varValue
        self.obj_val = pulp.value(problem.objective)
def update_for_next_period(mdl, trend_dict, today, target_day):
    # ----------------------------------------------------------------------- #
    # Update number of cases for next period
    # ----------------------------------------------------------------------- #
    for d in mdl.deps:
        for t in mdl.transfer_periods:

            # Calculate existing cases and reallocations
            existing_cases = mdl.o_vars[d, t]
            cases_in = plp.lpSum(mdl.y_vars[dx, d, t] for dx in mdl.deps)
            cases_out = plp.lpSum(mdl.y_vars[d, dx, t] for dx in mdl.deps)

            # Get prognosis for organic growth
            prognosis = trend_dict[d][trend_dict[d]["Date"] ==
                                      target_day].IVA.values[0]
            current = trend_dict[d][trend_dict[d]["Date"] ==
                                    today].IVA.values[0]
            organic_growth = prognosis - current  #Prediction for organic growth goes here

            #Summarize new cases
            new_cases = existing_cases + cases_in - cases_out + organic_growth

            # Add constraint
            mdl.addConstraint(
                plp.LpConstraint(e=mdl.o_vars[d, t + 1] - new_cases,
                                 sense=plp.LpConstraintEQ,
                                 rhs=0,
                                 name="new_cases_{0}_{1}".format(d, t)))
    return mdl
Example #19
0
 def con(self, affine, sense=0, rhs=0):
     affine = self._compress_affine(affine)
     con = pl.LpConstraint(pl.LpAffineExpression(affine),
                           sense=sense,
                           rhs=rhs)
     self.mip += con
     return con
def max_char_constraint(prob,
                        d_vars,
                        groups,
                        file,
                        elastic,
                        sheet="Constraint - Maximum"):
    """
    Add rigid or elastic maximum characterstic constraint based on elastic parameter. Constraint ensures or encourages no more than the maximum number of people with specified characteristic assigned to each group. With elastic constraint, allow maximum number to relax to zero to ensure the feasibility of the problem.
    """
    person_df = import_from_template(file, "Person Setup")
    max_df = import_from_template(file, sheet)
    for idx, max_row in max_df.iterrows():
        person_with_char_df = person_df.loc[person_df[
            max_row["characteristic"]] == max_row["value"]]
        names_with_char = person_with_char_df["name"].to_list()
        for group in groups:
            if elastic:
                constraint_lhs = sum(d_vars[(name, group)]
                                     for name in names_with_char)
                constraint_rhs = max_row["maximum"]
                # sense value -1 means less than or equal to (<=)
                constraint = pulp.LpConstraint(constraint_lhs,
                                               sense=-1,
                                               name=int(1000000 *
                                                        random.random()),
                                               rhs=constraint_rhs)
                # penalty-free target interval of 100% on left and 0% on right side of the rhs value ==> [0, constraint_rhs]
                e_constraint = constraint.makeElasticSubProblem(
                    penalty=1, proportionFreeBoundList=[1, 0])
                prob.extend(e_constraint)
            else:
                prob += sum(d_vars[(name, group)]
                            for name in names_with_char) <= max_row["maximum"]
    return prob
Example #21
0
def solve(AA, bb, ff, lb, ub, nn):
    vs1 = pulp.LpVariable.dicts('v', range(nn))
    vs2 = pulp.LpVariable.dicts('v', range(nn, 2 * nn))
    vs3 = pulp.LpVariable.dicts('v', range(2 * nn, 3 * nn), None, None,
                                pulp.LpInteger)
    vs4 = pulp.LpVariable.dicts('v', range(3 * nn, 4 * nn), None, None,
                                pulp.LpInteger)
    vs = {}
    vs.update(vs1)
    vs.update(vs2)
    vs.update(vs3)
    vs.update(vs4)
    for i in vs:
        vs[i].bounds(lb[i], ub[i])
    prob = pulp.LpProblem("New Problem", pulp.LpMinimize)
    obj = pulp.LpAffineExpression([(vs[i], v) for i, v in enumerate(ff) if v])
    prob += obj
    for i, rr in enumerate(AA):
        constraint = pulp.LpConstraint([(vs[i], v)
                                        for i, v in enumerate(rr) if v],
                                       pulp.LpConstraintLE, None, bb[i])
        prob += constraint
    solver = pulp.solvers.PULP_CBC_CMD()
    solver.maxSeconds = 120
    prob.setSolver(solver)
    prob.solve()
    xx = [0] * 4 * nn
    for v in prob.variables():
        s, n = v.name.split('_')
        xx[int(n)] = v.varValue
    xx = numpy.array(xx)
    solution = xx[:nn] - xx[nn:2 * nn]
    solution = numpy.round(solution * 1e9) / 1e9
    return pulp.LpStatus[prob.status], solution
Example #22
0
def create_problem(market):
    lp_vars = {}

    problem = pulp.LpProblem(market.name, pulp.LpMaximize)

    profit = pulp.LpVariable('profit', lowBound=0, cat='Continuous')

    problem += profit

    for c in market.contracts:
        lp_vars[market.contracts[c].name] = pulp.LpVariable(
            market.contracts[c].name, lowBound=0, cat='Integer')

    #print(lp_vars)
    for v in lp_vars:
        if v is not "profit":
            expr = pulp.LpAffineExpression(
                [(lp_vars[x], market.contracts[x].profit) if x != v else
                 (lp_vars[x], -1 * market.contracts[x].cost)
                 for x in lp_vars] + [(profit, -1)])
            c = pulp.LpConstraint(
                expr, 1)  #1 indicates the expression should be >= 0
            problem += c
            problem += lp_vars[v] * market.contracts[v].cost <= 850

    #max_profit = pulp.LpAffineExpression([(lp_vars[x], market.contracts[x].profit) for x in lp_vars])
    #max_profit += -850
    #c = pulp.LpConstraint(max_profit, -1)
    #problem += c

    return problem
Example #23
0
def mclp(candidates=None, K=None, radius=None, points=None):
    K = int(K)
    J = candidates.shape[0]
    I = points.shape[0]
    D = distance_matrix(points, candidates)

    mask = D <= radius
    D[mask] = 1
    D[~mask] = 0

    y_vars = {(i): plp.LpVariable(cat=plp.LpBinary, name="y_%d" % i)
              for i in range(I)}
    x_vars = {(j): plp.LpVariable(cat=plp.LpBinary, name="x_%d" % j)
              for j in range(J)}

    opt_model = plp.LpProblem()
    opt_model.addConstraint(
        plp.LpConstraint(e=plp.lpSum(x_vars[j] for j in range(J)),
                         sense=plp.LpConstraintEQ,
                         rhs=K,
                         name="constraint_%d" % 0))

    for i in range(I):
        mask = np.where(D[i] == 1)[0]
        if len(mask) > 0:
            newConstraint = plp.LpConstraint(
                e=plp.lpSum(x_vars[j] - y_vars[i] for j in mask),
                sense=plp.LpConstraintGE,
                rhs=0,
                name="constraint_%d" % len(opt_model.constraints))
            opt_model.addConstraint(newConstraint)

    objective = plp.lpSum(y_vars[i] for i in range(I))
    opt_model.sense = plp.LpMaximize
    opt_model.setObjective(objective)

    opt_model.solve(plp.PULP_CBC_CMD(msg=0))
    # opt_model.solve()

    solution = []
    if opt_model.status == 1:
        for v in opt_model._variables:
            if v.varValue == 1 and v.name[0] == 'x':
                solution.append(int(v.name[2:]))
    opt_candidates = candidates[solution]

    return opt_candidates
Example #24
0
def add_prefilled_constraints(prob, input_sudoku, grid_vars, rows, cols, values):
    for row in rows:
        for col in cols:
            if(input_sudoku[row][col] != 0):
                prob.addConstraint(plp.LpConstraint(e=plp.lpSum([grid_vars[row][col][value]*value  for value in values]),
                                                    sense=plp.LpConstraintEQ,
                                                    rhs=input_sudoku[row][col],
                                                    name=f"constraint_prefilled_{row}_{col}"))
Example #25
0
 def get_constraints(self):
     if len(self.get_input_totals()) != self.size:
         raise DimensionMismatchException(len(self.get_input_totals()),
                                          self.size)
     return (pulp.LpConstraint(self.get_input_totals()[i],
                               sense=1,
                               rhs=cons,
                               name=self.name + str(i + 1))
             for i, cons in enumerate(self.constraints))
Example #26
0
 def get_link_constraints(self):
     if self.fixed_locs: return None
     return [
         pulp.LpConstraint(
             self.get_output_totals()[i] -
             max(self.constraints[i], 10000000000000000) * self.ys[i],
             sense=-1,
             rhs=0,
             name=self.name + '_link' + str(i)) for i in range(self.size)
     ]
Example #27
0
 def get_constraints(self):
     if len(self.get_input_totals()) != len(self.get_output_totals()):
         raise DimensionMismatchException(len(self.get_input_totals()),
                                          len(self.get_output_totals()))
     if len(self.get_input_totals()) != self.size:
         raise DimensionMismatchException(len(self.get_input_totals()),
                                          self.size)
     for i in range(self.size):
         yield pulp.LpConstraint(self.get_input_totals()[i] -
                                 self.get_output_totals()[i],
                                 sense=0,
                                 rhs=0,
                                 name=self.name + str(i + 1) + '_Clear')
     for i, cons in enumerate(self.constraints):
         if cons:
             yield pulp.LpConstraint(self.get_input_totals()[i],
                                     sense=-1,
                                     rhs=cons,
                                     name=self.name + str(i + 1))
Example #28
0
def solveModel(capacity, timeVect, revenueVect):
    """Linear Optimization Model for NYC taxi rides selection.
    Params: @capacity: number of taxis the company owns
    		@timeVect: binary 2D matrix with row representing each ride and column being time
    		@revenueVect: Vector on revenue on each ride, ordering same as timeVect
    """
    print("Solving model for " + str(capacity))

    timeSectionNum = timeVect.shape[1]
    model = pulp.LpProblem("Profit maximizing problem", pulp.LpMaximize)

    tripNum = numpy.size(revenueVect)
    RANGE = range(tripNum)
    assignment = pulp.LpVariable.dicts('assignment', RANGE, cat='Binary')

    #Maximize revenue, set objective
    totalRev = 0
    for j in range(tripNum):
        totalRev += assignment[j] * revenueVect[j][0]
    model += totalRev

    time = []
    #print "Time Vect: ", timeVect
    for i in xrange(timeSectionNum):
        time.append(
            pulp.LpAffineExpression([(assignment[j], timeVect[j][i])
                                     for j in range(tripNum)]))

    print('time')
    print(time)
    #Setting time constraint
    for temp in xrange(timeSectionNum):
        timeVal = time[temp]
        # print('timeVal')
        # print(timeVal)
        # print('capacity')
        # print(capacity)

        print(timeVal <= capacity)
        model += pulp.LpConstraint(e=timeVal,
                                   sense=-1,
                                   name=str(temp) + "time_constraint",
                                   rhs=capacity)
    print "Objective was: ", model
    optimization_result = model.solve()
    # print('Objective becomes')
    # print pulp.value(model.objective)
    # print('optimization_result')
    # print(optimization_result)
    # print(time)
    with open("result.csv", "wb") as out:
        writer = csv.writer(out)
        for i in xrange(tripNum):
            print(assignment[i].value())
            writer.writerow(assignment[i].value())
def set_initial_state(mdl, current_df):
    # ----------------------------------------------------------------------- #
    # Set initial state
    # ----------------------------------------------------------------------- #
    for d in mdl.deps:
        mdl.addConstraint(
            plp.LpConstraint(e=mdl.o_vars[d, 0],
                             sense=plp.LpConstraintEQ,
                             rhs=current_df.at[d, "IVA"],
                             name="initial_state_{0}".format(d)))
    return mdl
Example #30
0
 def con(self, affine, sense=0, rhs=0):
     # sum up (pulp doesnt do this)
     affine_ = {a: 0 for a, b in affine}
     for a, b in affine:
         affine_[a] += b
     affine = [(a, affine_[a]) for a in affine_]
     con = pl.LpConstraint(pl.LpAffineExpression(affine),
                           sense=sense,
                           rhs=rhs)
     self.mip += con
     return con