Proper way to write a complex objective and constraints in Python Pulp - python

I am following a book that explains advanced linear programs. So far it's been good, but this example has me stumped on how to properly write the objective functions and constraints.
Below you'll find my attempt at coding the left coefficient but as you can see it doesn't seem correct.
My implementation so far is as follow
import pulp as lp
# data
r = 0.02
T = 2
J = 3
E = 6
K = {(1): 2, (2): 3, (3): 4, (4): 4, (5): 6, (6): 7}
C_j_t = {(1, 1): 2, (1, 2): 3, (2, 1): 4, (2, 2): 5, (3, 1): 6, (3, 2): 7}
F_j_e = {(1, 1): 2, (1, 2): 3, (2, 1): 4, (2, 2): 5, (3, 1): 6, (3, 2): 7}
I_j_e = {(1, 1): 2, (1, 2): 3, (2, 1): 4, (2, 2): 5, (3, 1): 6, (3, 2): 7}
# F_j_e = 1
prob = lp.LpProblem('Foobar Village Highway Problem', lp.LpMaximize)
X_j_t = lp.LpVariable.dicts("X",
[(j, t)
for j in range(1, J)
for t in range(1, T)],
cat='Continuous')
coef_left = {}
for t in range(1, T):
for j in range(1, J):
coef_left[(j, t)] = (1 + r)**-t * C_j_t[(j, t)]
pv = (1 + r)**-T
right_side = {}
for j in range(1, J):
for e in range(1, K[(j)]):
right_side[(j, e)] = pv * F_j_e[(j, e)] * I_j_e[(j, e)]
prob += lp.lpSum(coef_left[(j, t)] * X_j_t[(j, t)] + right_side[(j, e)]
for j in range(1, J)
for t in range(1, T)
for e in range(1, E))
prob.writeLP(r'8.2.1.lp')
# Solve
prob.solve()
I don't think this is correct or that I'm using the right methodology to code this complex objective an constraint.
it returns the following:
\* Foobar_Village_Highway_Problem *\
Maximize
OBJ: 3.92156862745 X_(1,_1) + 7.8431372549 X_(2,_1)
Subject To
Bounds
X_(1,_1) free
X_(2,_1) free
End

We cannot reproduce much because the fragment is incomplete, but there seems an issue with the loop structure:
prob += lp.lpSum(coef_left[(j, t)] * X_j_t[(j, t)]
for j in range(1, J)
for i in range(1, T)) <----- for t

Related

How to convert this C++ for loop to Python?

Here is a for loop in C++. How would you convert this to Python?
for(j=1, k=x; j<=x; j++, k--)
j = 1
k = x
while j <= x:
j = j + 1
k = k - 1
j = 1
k = x
while j <= x:
j += 1
k -= 1
same as previous small changed
I just think so:
x = 5
k = x
for j in range(1, x+1, 1):
# do something
print(j, k)
k -= 1
And it output:
(1, 5)
(2, 4)
(3, 3)
(4, 2)
(5, 1)

create list from repeated pattern in python

I would like to create a list in python3, which look like this:
L = [(0,(0,1,2,3,4)), (1, (5,6,7,8,9)),(2,(10,11,12,13,14))......)
lets call it L= [(i,(j1,j2,j3,j4,j5),...)
The important thing is that the pattern keep on repeating till the j5 reaches 740231
Any suggestions would be very much appreciated.
Another way, strictly comprehending:
L = [(i,tuple(range(i*5,i*5+5))) for i in range(740231//5+1)]
Here's one solution using enumerate and range:
n = 5
k = 14
ranger = (range(i, i+n) for i in range(0, k, n))
L = list(enumerate(map(tuple, ranger)))
# [(0, (0, 1, 2, 3, 4)), (1, (5, 6, 7, 8, 9)), (2, (10, 11, 12, 13, 14))]
Use generator function :
def gen():
x = 0
y = 0
while y < 740231:
yield( (x, tuple(range(y,y+5)), ) )
x += 1
y += 5
>>> list(gen())
[(0, (0, 1, 2, 3, 4)), (1, (5, 6, 7, 8, 9)), (2, (10, 11, 12, 13, 14)) ... ]

oneliner using pandas or numpy

How would I implment this code using pandas or numpy?
x =[]
for i in xrange(1,6):
x.append(i)
print x
combi = (list(itertools.permutations(x, 5)))
for i in combi:
print i
l = (i[0]) + abs(i[0] - i[1]) + abs(i[1] - i[2]) + abs(i[2] - i[3]) + abs(i[3] - i[4])
print l
output of combi is
(1, 2, 3, 4, 5)
(1, 2, 3, 5, 4)
(1, 2, 4, 3, 5)
(1, 2, 4, 5, 3)
I try to add the first number in each tuple to difference of second third 4th and fifth for each tuple which give me this
5
6
7
7
easier if increase my range to 10 i will have to write the code for variable l upto 10.
You are taking the diff between subsequent elements, and then summing the abs of those diffs and then you add to that, the first element in the sequence:
Code:
for i in it.permutations(xrange(1, 6), 5):
k = i[0] + sum(np.abs(np.diff(i)))
Test Code:
import numpy as np
import itertools as it
for i in it.permutations(xrange(1, 6), 5):
k = i[0] + sum(np.abs(np.diff(i)))
l = (i[0]) + abs(i[0] - i[1]) + abs(i[1] - i[2]) + abs(i[2] - i[3]) + abs(i[3] - i[4])
assert l == k

Number of pairs [duplicate]

I am trying to write a code that takes
m. a, a list of integers
n. b, an integer
and returns the number of pairs (m,n) with m,n in a such that |m-n|<=b.
So far, I've got this
def nearest_pairs(a, b):
m= []
n= int
num_pairs = 0
return num_pairs
def main():
# The nearest pairs are (1,2), (2,1), (2,5) and (5,2)
x = nearest_pairs( [1,2,5] , 3 )
print( "nearest_pairs([1, 2, 5], 3) = " , nearest_pairs([1, 2, 5], 3) )
# The nearest pairs are (1,2) and (2,1)
y = nearest_pairs( [1, 2, 5] , 2 )
print( "nearest_pairs([1, 2, 5], 2) = " , nearest_pairs([1, 2, 5], 2) )
if __name__ == '__main__':
main()
The desired output should look like
>>> nearest_pairs([1,2,5],3) = 4
where 4 is the number of close pairs according to the restrictions. However, I get an error. Could anyone lead me to the right direction?
Yours doesn't make sense. No idea what you're trying with len(a, b), but it's not even allowed, since len takes only one argument. And returning something just when you found the first counting pair? Here's a fix:
def close_pairs(l, d):
ctr = 0
for a,b in permutations(l, 2):
if (a - b) <= d and (b - a) <= d:
ctr += 1
return ctr
And here's how I'd do it:
def close_pairs(l, d):
return sum(abs(a-b) <= d for a, b in permutations(l, 2))
from itertools import permutations
def nearest_pairs(a, b):
for m, n in permutations(a, 2):
if abs(m - n) <= b:
yield (m, n)
>>> list(nearest_pairs([1, 2, 5], 3))
[(1, 2), (2, 1), (2, 5), (5, 2)]
>>> list(nearest_pairs([1, 2, 5], 2))
[(1, 2), (2, 1)]
If you just want the count:
def nearest_pairs_count(a, b):
c, l = 0, len(a)
for i in range(l):
for j in range(i + 1, l):
if abs(a[i] - a[j]) <= b:
c += 2
return c

Python, finding neighbors in a 2-d list

So here's the issue, I have a 2-d list of characters 'T' and 'F', and given coordinates I need to get all of its neighbors. I have this:
from itertools import product, starmap
x, y = (5, 5)
cells = starmap(lambda a, b: (x + a, y + b), product((0, -1, +1), (0, -1, +1)))
from determining neighbors of cell two dimensional list But it will only give me a list of coordinantes, so i still fetch the values afterwords. I'd like the search and retrieval done in one step, so findNeighbors(5,5) would return F,T,F,F,... instead of (5, 4), (5, 6), (4, 5), (4, 4)... Is there a fast way of doing this? The solutin can include a structure other than a list to hold the initial information
The following should work, with just a minor adaptation to the current code:
from itertools import product, starmap, islice
def findNeighbors(grid, x, y):
xi = (0, -1, 1) if 0 < x < len(grid) - 1 else ((0, -1) if x > 0 else (0, 1))
yi = (0, -1, 1) if 0 < y < len(grid[0]) - 1 else ((0, -1) if y > 0 else (0, 1))
return islice(starmap((lambda a, b: grid[x + a][y + b]), product(xi, yi)), 1, None)
For example:
>>> grid = [[ 0, 1, 2, 3],
... [ 4, 5, 6, 7],
... [ 8, 9, 10, 11],
... [12, 13, 14, 15]]
>>> list(findNeighbors(grid, 2, 1)) # find neighbors of 9
[8, 10, 5, 4, 6, 13, 12, 14]
>>> list(findNeighbors(grid, 3, 3)) # find neighbors of 15
[14, 11, 10]
For the sake of clarity, here is some equivalent code without all of the itertools magic:
def findNeighbors(grid, x, y):
if 0 < x < len(grid) - 1:
xi = (0, -1, 1) # this isn't first or last row, so we can look above and below
elif x > 0:
xi = (0, -1) # this is the last row, so we can only look above
else:
xi = (0, 1) # this is the first row, so we can only look below
# the following line accomplishes the same thing as the above code but for columns
yi = (0, -1, 1) if 0 < y < len(grid[0]) - 1 else ((0, -1) if y > 0 else (0, 1))
for a in xi:
for b in yi:
if a == b == 0: # this value is skipped using islice in the original code
continue
yield grid[x + a][y + b]

Categories

Resources