Specify variables bounds in pulp - python-3.x

I'm working on linear programming using pulp and what I ask for is how can I specify each items bounds in my list
mylist=["x","y","z"]
I've created this:
vars = LpVariable.dicts("vars", mylist, lowBound=0, cat='Continuous')
but it creates a global bounds for all of the items inside my list and what I want is for each item in my list
I try this but it didn't work:
x = LpVariable("x", lowBound=5, upBound=10, cat='Continuous')
THANKS!!

You just need to create individual constraints for the low/upper bounds if you want them to be different in pulp. It's all the same to the solver.
Example:
import pulp as plp
products = ['rice', 'veggies', 'fruit']
low_bounds = { 'rice': 5,
'veggies': 7,
'fruit': 2}
prob = plp.LpProblem('example')
x = plp.LpVariable.dicts('products', products, cat='Continuous')
for p in products:
prob += x[p] >= low_bounds[p]
print(prob)
Yields:
MINIMIZE
None
SUBJECT TO
_C1: products_rice >= 5
_C2: products_veggies >= 7
_C3: products_fruit >= 2
VARIABLES
products_fruit free Continuous
products_rice free Continuous
products_veggies free Continuous

Related

How can i add interaction of two variables as a constraint in PuLP

I have an optimization problem in my hand and i want to add some constraints
maa_count = LpVariable("ManAtArmsCount", int(archer_count) - 1, None, LpInteger)
archer_count = LpVariable("ArcherCount", int(mangonel_count) + 1 , int(maa_count) - 1, LpInteger)
mangonel_count = LpVariable("MangonelCount", int(cavalry_count) + 1, int(archer_count) - 1, LpInteger)
cavalry_count = LpVariable("CavalryCount", 0, int(mangonel_count) - 1, LpInteger)
army_count = archer_count + maa_count + cavalry_count + mangonel_count
This code results in TypeError: int() argument must be a string, a bytes-like object or a number, not 'LpVariable'
I tried to define variables with standart bounds and add a constraint with
prob += maa_count > archer_count > mangonel_count > cavalry_count
but this resulted in a type error stating that > operator cannot be used between lpvariables.
How can i fix this?
Break up what you are trying to do. You cannot reference a variable as a part of the construct of another variable. The correct thing to do is to put upper/lower bounds (if it makes sense in the context of the problem) in the construction and then state any further relationships in constraints. For instance if I want 2 integer variables and I want y to be greater than x, I just need to state that relationship in a constraint. Also, do not cast things as int()... just declare the variable as an integer type. As such:
import pulp
prob = pulp.LpProblem('example', pulp.LpMinimize)
x = pulp.LpVariable('x', lowBound=0, cat=pulp.LpInteger)
y = pulp.LpVariable('y', lowBound=0, cat=pulp.LpInteger)
# state the relationship of the variables in a linear constraint... And add it to the problem
prob += y >= x
print(prob)
Yields:
example:
MINIMIZE
None
SUBJECT TO
_C1: - x + y >= 0
VARIABLES
0 <= x Integer
0 <= y Integer

Pulp : Adding bounds to LpVariable.dicts()

Let's say I have this dictionary :
cars = ["car1","car2","car3","car4","car5"]
x = LpVariable.dicts("car",cars, cat='Integer', lowBound=0, upBound=800)
Is there any way to add different lowBound and upBounds to each car, please?
Note
The easy code version looks like this :
car1 = LpVariable("car1", 0, 40)
car2 = LpVariable("car2", 0, 1000)
Please notice that the car1 upBound is 40 and the car 2 upBound is 1000.
Finally,
I 've done it, using his great code :
How do I generate PuLP variables and constrains without using exec?
Thanks a lot, DSM, bro !
prob = LpProblem("problem", LpMaximize)
# Setting LP variables
lpVars =["car1","car2","car3"]
upbounds=[40,80,30]
xs = [LpVariable("car{}".format(i+1), lowBound = 0, upBound = upbounds[i], cat='Integer' ) for i in range(len(lpVars))]
# add objective
margin = [3,2,3]
total_prof = sum(x * value for x,value in zip(xs, margin))
prob += total_prof
# add constraint
labour = [2,1,4]
total_labour = sum(x * w for x,w in zip(xs, labour))
prob += total_labour <= 100
# Solve the problem
prob.solve()
The next step is getting the arrays variables from the front end app (upbounds, margin, labour, etc ..) , thank you, bro, peep my github

Problem assigning values of a While loop in different variables

i'm coding a function to my phyton3 program that get the weight of 7 people.
I don't know how i assign these 7 values to different variables, like:
a = 0
while(a < 7):
p = int(input("Seu peso"))
a = a + 1
And after that, he assign the different "p" values to different variables like, p1, p2, p3 ...
But with my level of "coding", i simply can't do that.
The general purpose of the program is:
Get the different weights
Say which are the weight above 90kg
Do the arithmetic mean of the values.
And these 3 are why i have the need for different variables.
To get the weight of 7 people, you can do the following:
weights = [] #This is a list
for i in range(7): #This is a for loop
w = int(input("Seu peso "))
weights.append(w)
To say what weights are above 90kg:
for w in weights:
if w > 90:
print(w, "Is greater than 90kg")
To find the mean:
mean = sum(weights)/len(weights)
print("Mean Weight:", mean)

How to set LpVariable and Objective Function in pulp for LPP as per the formula?

I want to calculate the Maximised value of the particular user based on his Interest | Popularity | both Interest and Popularity using following Linear Programming Problem(LPP) equation
using pulp package in python3.7.
I have 4 lists
INTEREST = [5,10,15,20,25]
POPULARITY = [4,8,12,16,20]
USER = [1,2,3,4,5]
cost = [2,4,6,8,10]
and 2 variable values as
e=0.5 ; e may take (0 or 1 or 0.5)
budget=20
and
i=0 to n ; n is length of the list
means, the summation want to perform for all list values.
Here, if e==0 means Interest will 0 ; if e==1 means Popularity will 0 ; if e==0.5 means Interest and Popularity will be consider for Max Value
Also xi takes 0 or 1; if xi==1 then the user will be consider else if xi==0 then the user will not be consider.
and my pulp code as below
from pulp import *
INTEREST = [5,10,15,20,25]
POPULARITY = [4,8,12,16,20]
USER = [1,2,3,4,5]
cost = [2,4,6,8,10]
e=0.5
budget=10
#PROBLEM VARIABLE
prob = LpProblem("MaxValue", LpMaximize)
# DECISION VARIABLE
int_vars = LpVariable.dicts("Interest", INTEREST,0,4,LpContinuous)
pop_vars = LpVariable.dicts("Popularity",
POPULARITY,0,4,LpContinuous)
user_vars = LpVariable.dicts("User",
USER,0,4,LpBinary)
#OBJECTIVE fUNCTION
prob += lpSum(USER(i)((INTEREST[i]*e for i in INTEREST) +
(POPULARITY[i]*(1-e) for i in POPULARITY)))
# CONSTRAINTS
prob += USER(i)cost(i) <= budget
#SOLVE
prob.solve()
print("Status : ",LpStatus[prob.status])
# PRINT OPTIMAL SOLUTION
print("The Max Value = ",value(prob.objective))
Now I am getting 2 errors as
1) line 714, in addInPlace for e in other:
2) line 23, in
prob += lpSum(INTEREST[i]e for i in INTEREST) +
lpSum(POPULARITY[i](1-e) for i in POPULARITY)
IndexError: list index out of range
What I did wrong in my code. Guide me to resolve this problem. Thanks in advance.
I think I finally understand what you are trying to achieve. I think the problem with your description is to do with terminology. In a linear program we reserve the term variable for those variables which we want to be selected or chosen as part of the optimisation.
If I understand your needs correctly your python variables e and budget would be considered parameters or constants of the linear program.
I believe this does what you want:
from pulp import *
import numpy as np
INTEREST = [5,10,15,20,25]
POPULARITY = [4,8,12,16,20]
COST = [2,4,6,8,10]
N = len(COST)
set_user = range(N)
e=0.5
budget=10
#PROBLEM VARIABLE
prob = LpProblem("MaxValue", LpMaximize)
# DECISION VARIABLE
x = LpVariable.dicts("user_selected", set_user, 0, 1, LpBinary)
# OBJECTIVE fUNCTION
prob += lpSum([x[i]*(INTEREST[i]*e + POPULARITY[i]*(1-e)) for i in set_user])
# CONSTRAINTS
prob += lpSum([x[i]*COST[i] for i in set_user]) <= budget
#SOLVE
prob.solve()
print("Status : ",LpStatus[prob.status])
# PRINT OPTIMAL SOLUTION
print("The Max Value = ",value(prob.objective))
# Show which users selected
x_soln = np.array([x[i].varValue for i in set_user])
print("user_vars: ")
print(x_soln)
Which should return the following, i.e. with these particular parameters only the last user is selected for inclusion - but this decision will change - for example if you increase the budget to 100 all users will be selected.
Status : Optimal
The Max Value = 22.5
user_vars:
[0. 0. 0. 0. 1.]

Order constraints in optimisation

I have a set of many (10000+) items, from which have I have to choose exactly 20 items. I can only choose each item once. My items have profits, and costs, as well as several boolean properties (such as colour). I need to output the results in a specific order: in particular I need the first and third items to be blue, and the second and fourth items to be red.
Each item is represented as a tuple:
item = ('item name', cost, profit, is_blue, is_red)
as an example
vase = ['Ming Vase', 1000, 10000, 0, 1]
plate = ['China Plate', 10, 5, 1, 0]
and the total set of items is a list of lists:
items = [item1, item2, ..., itemN].
My profits and costs are also lists:
profits = [x[2] for x in items]
costs = [x[1] for x in items]
For each item chosen, it needs to have a minimum value, and a minimum of 5 items must have the property (is_blue) flag set to 1.
I want to choose the 20 cheapest items with the highest value, such that 5 of them have the is_blue flag set to 1, and the first and third items are blue (etc).
I'm having trouble formulating this using google OR tools.
from ortools.linear_solver import pywraplp
solver = pywraplp.Solver('SolveAssignmentProblemMIP',
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
x = {}
for i in range(MAX_ITEMS):
x[i] = solver.BoolVar('x[%s]' % (i))
#Define the constraints
total_chosen = 20
solver.Add(solver.Sum([x[i] for i in range(MAX_ITEMS)]) == total_chosen)
blues = [x[3] for x in items]
solver.Add(solver.Sum([blues[i] * x[i] for i in .
range(MAX_ITEMS)]) >= 5)
max_cost = 5.0
for i in range(MAX_ITEMS):
solver.Add(x[i] * cost[i] <= max_cost)
solver.Maximize(solver.Sum([profits[i] * x[i] for i in range(total_chosen)]))
sol = solver.Solve()
I can get the set of items I've chosen by:
for i in range(MAX_ITEMS):
if x[i].solution_value() > 0:
print(item[i].item_name)
This works fine - it chooses the set of 20 items which maximise the profits subject to the cost constraint, but I'm stuck on how to extend this to choosing items in way that guarantees that the first is blue etc.
Any help in formulating the constraints and objective would be really helpful. Thanks!
Instead of expressing chosen items with BoolVar, consider making a list of 20 IntVar with domain of 0..MAX_ITEMS. From there it should be fairly easy to do something like this:
solver.Add(chosens[0].IndexOf(all_items)[3] == 1)
solver.Add(chosens[2].IndexOf(all_items)[3] == 1)
chosens[i].IndexOf(all_items) simply means all_items[IndexOfChosen], I.E: whichever item is chosen for the Ith place. If you go with this approach, do not forget to MakeAllDifferent!

Resources