Pulp : Adding bounds to LpVariable.dicts() - pulp

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

Related

Specify variables bounds in pulp

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

How to make a double loop inside a dictionary in Python?

I have a data cube with 2 dimensions of coordinates and a third dimension for wavelength. My goal is to write a mask for coordinates outside a circle of given radius to the central coordinates (x0 and y0 in my code). For this, I'm trying to use a dictionary, but I'm having throuble because it seems that I'll have to make a double loop inside the dictionary to iterate over the two dimensions, and as a beginner with dictionaries, I don't know yet how to do that.
I wrote the following code
x0 = 38
y0 = 45
radius = 9
xcoords = np.arange(1,flux.shape[1]+1,1)
ycoords = np.arange(1,flux.shape[2]+1,1)
mask = {'xmask': [xcoords[np.sqrt((xcoords[:]-x0)**2 + (y-y0)**2) < radius] for y in ycoords], 'ymask': [ycoords[np.sqrt((x-x0)**2 + (ycoords[:]-y0)**2) < radius] for x in xcoords]}
And it returned several arrays, one for each value of y (for xmasks), and one for each value of x (for ymasks), although I want just one array for each one. Could anyone say what I made wrong and how to achieve my goal?
Note: I also made it without using a dictionary, as
xmask = []
for x in xcoords:
for y in ycoords:
if np.sqrt((x-x0)**2 + (y-y0)**2) < radius:
xmask.append(x)
break
ymask = []
for y in xcoords:
for x in ycoords:
if np.sqrt((x-x0)**2 + (y-y0)**2) < radius:
ymask.append(y)
break
but I hope it's possible to make it more efficiently.
Thanks for any help!
Edit: I realized that no loop was needed. If I select y = y0 and x = x0, I get the values of x and y that are inside the circle, respectively. So I stayed with
mask = {'xmask': [xcoords[abs(xcoords[:]-x0) < radius]], 'ymask': [ycoords[abs(ycoords[:]-y0) < radius]]}
The OP explains that assigning
mask = {'xmask': [xcoords[abs(xcoords[:] - x0) < radius]],
'ymask': [ycoords[abs(ycoords[:] - y0) < radius]]}
solves the problem.

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.]

Implementing Oja's Learning rule in Hopfield Network using python

I am following this paper to implement Oja's Learning rule in python
Oja's Learning Rule
u = 0.01
V = np.dot(self.weight , input_data.T)
print(V.shape , self.weight.shape , input_data.shape) #(625, 2) (625, 625) (2, 625)
So far, I am able to follow the paper, however on arriving at the final equation from the link, I run into numpy array dimension mismatch errors which seems to be expected. This is the code for the final equation
self.weight += u * V * (input_data.T - (V * self.weight)
If I break it down like so:
u = 0.01
V = np.dot(self.weight , input_data.T)
temp = u * V #(625, 2)
x = input_data - np.dot(V.T , self.weight) #(2, 625)
k = np.dot(temp , x) #(625, 625)
self.weight = np.add(self.weight , k , casting = 'same_kind')
This clears out the dimension constraints, but the answer pattern is wrong by a stretch (I was just fixing the dimension orders knowing well the result would be incorrect). I want to know if my interpretation of the equation is correct in the first approach which seemed like the logical way to do so. Any suggestions on implementing the equation properly?
I have implemented the rule based on this link Oja Rule. The results I get are similar to the hebbian learning rule. So I am not exactly sure on the correctness of the implementation. However posting it so anyone looking for an implementation can get few ideas and correct the code if wrong
u = 0.01
V = np.dot(self.weight , input_data.T)
i = 0
for inp in input_data:
v = V[ : , i].reshape((n_features , 1)) #n_features is # of columns
self.weight += (inp * v) - u * np.square(v) * self.weight
i += 1

setting point sizes when using Gadfly in Julia

In my attempts to practice Julia, I've made a program which draws a bifurcation diagram. My code is as follows:
function bifur(x0,y0,a=1.3,b=0.4,n=1000,m=10000)
i,x,y=1,x0,y0
while i < n && abs(x) < m
x,y = a - x^2 + y, b * x
i += 1
end
if abs(x) < m
return x
else
return 1000
end
end
la = Float64[];
lx = Float64[];
for a=0:400
for j = 1:1000
x0 = rand()
y0 = rand()
x = bifur(x0,y0,a/100)
if x != 1000
push!(la,a/100)
push!(lx,x)
end
end
end
using Gadfly
myplot = Gadfly.plot( x=la, y=lx , Scale.x_discrete, Scale.y_continuous, Geom.point)
draw(PNG("myplot.png",10inch,8inch),myplot)
The output I get is this image:
In order to make my plot look more like this:
I need to be able to set point sizes to as small as one pixel. Then by increasing the iteration length I should be able to get a better bifurcation diagram. Does anyone know how to set the point sizes in Gadfly diagrams in Julia?
[Just to encapsulate the comments as an answer...]
Gadfly's Theme defaults can be changed. In particular, point_size is probably what you are looking for.
For changing the automatic plot scale/range settings, have a look at Gadfly's Scale params.

Resources