Related
I choose the recursive option in order to calculate weighted moving average starting from the latest calculated value.
According to Documentation :
When adjust=False, the exponentially weighted function is calculated
recursively:
y0 = x0
y(t) = (1-alpha) * y(t-1) + alpha * x(t)
So I have the following code :
import pandas as pd
df = pd.DataFrame({'col1':[1, 1, 2, 3, 3, 5, 8, 9],
})
alpha=0.5
df['ewm'] = df['col1'].ewm(alpha, adjust=False).mean()
which gives :
>>> df
col1 ewm
0 1 1.000000
1 1 1.000000
2 2 1.666667
3 3 2.555556
4 3 2.851852
5 5 4.283951
6 8 6.761317
7 9 8.253772
The problem is that it's not corresponding to following mathematical calculations :
y0 = x0 = 1
y1 = (1-0.5) * y0 + 0.5 * x1 = 0.5 + 0.5 = 1
y2 = (1-0.5) * y1 + 0.5 * x2 = 0.5 + 0.5 * 2 = 1.5
y3 = (1-0.5) * y2 + 0.5 * x3 = 0.5 * 1.5 + 0.5 * 3 = 0.75 + 1.5 = 2.25
...
We do not have the same values. What's wrong ?
Like I read in comments parameters should be named.
Documentation do not exposed this fact clearly.
One must be careful because no exception is raised when using no named arguments, but calculations are false.
Having issue with small python script. trying to add 1 to a global variable every 3 iterations. I keep seeing
"for 3 in scalerVal:
^
SyntaxError: cannot assign to literal"
I will appreciate an answer
x1 = 0
x2 = 0
x3 = 0
x4 = 0
x5 = 0
x6 = 0
x7 = 0
x8 = 0
x9 = 0
itVal = 0
scalerVal = 3
# -- STEP 1: --
# (greatest value) = 3 * itVal + itVal
# adder = (greatest value) - (current value) = (differnce in value) + itVal
# scaler = itVal - intVal - itVal
# -- STEP 2: --
# add the adder to all n values
def a1():
global x1
x1 = x1 + 3
global x2
x2 = x2 + 2
global x3
x3 = x3 + 1
global x4
x4 = x4 + 2
global x5
x5 = x5 + 2
global x6
x6 = x6 + 1
global x7
x7 = x7 + 1
global x8
x8 = x8 + 1
global x9
x9 = x9 + 1
global scalerVal
for 3 in scalerVal:
scalerVal + 1
return()
global itVal
if itVal == 0:
#gVal = 3 * itVal + itVal
#adder = gVal - x1 + itVal
#x1 = x1 + adder
itVal = itVal + 1
print(x1, x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
else:
gVal = scalerVal * itVal + itVal
adder = gVal - x1 + itVal
x1 = x1 + adder
itVal = itVal + 1
print(x1 , x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
return()
def a2():
global x1
x1 = x1 + 2
global x2
x2 = x2 + 3
global x3
x3 = x3 + 2
global x4
x4 = x4 + 2
global x5
x5 = x5 + 2
global x6
x6 = x6 + 2
global x7
x7 = x7 + 1
global x8
x8 = x8 + 1
global x9
x9 = x9 + 1
global itVal
return()
def a3():
global x1
x1 = x1 + 1
global x2
x2 = x2 + 2
global x3
x3 = x3 + 3
global x4
x4 = x4 + 1
global x5
x5 = x5 + 2
global x6
x6 = x6 + 2
global x7
x7 = x7 + 1
global x8
x8 = x8 + 1
global x9
x9 = x9 + 1
global itVal
if itVal == 0:
#gVal = 3 * itVal + itVal
#adder = gVal - x3 + itVal
#x3 = x3 + adder
itVal = itVal + 1
print(x1, x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
else:
gVal = 3 * itVal + itVal
adder = gVal - x3 + itVal
x3 = x3 + adder
itVal = itVal + 1
print(x1 , x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
return()
def valAdd():
#for _ in range(1000000000):
#a1()
a1()
a2()
a3()
print(x1, x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
valAdd()
Having issue with small python script. trying to add 1 to a global variable every 3 iterations. I keep seeing
"for 3 in scalerVal: ^ SyntaxError: cannot assign to literal"
I will appreciate an answer
The problem is that you are using a constant where you should put a variable instead.
More specifically, in the python for loop, it should be something like this:
for x in [scalerVal]
Actually, the first one should be a variable and the second one should be a iterable
3 needs to be a variable name such as X
for x in scalerVal:
x + 1
return()
Also, scalarVal should be a list or array, not a scalar for use with for.
You can just use the value directly.
I am trying to optimise the problem below using Mystic. I am currently receiving an error that I don't understand and was hoping someone more familiar with the library could help.
def objective(x):
x0,x1,x2,x3,x4,x5,x6,x7,x8 = x
return x0**2 + x4**2 + x8**2
equations = '''
x0 + x1 + x2 - x3 - x6 - 20 == 0.0
x4 + x3 + x5 - x1 - x7 - 150 == 0.0
x8 + x6 + x7 - x2 - x5 + 100 == 0.0
x6 == 0
x7 == 0
x0 >= 10
x4 >= 60
'''
from mystic.symbolic import generate_conditions, generate_penalty
pf = generate_penalty(generate_conditions(equations), k=1e4)
from mystic.symbolic import generate_constraint, generate_solvers, solve
cf = generate_constraint(generate_solvers(solve(equations))
When calculating cf i receive an 'NotImplementedError:cannot simplify inequalities' and wanted to know why this could be?
If anyone knows how i would extend this such that i can create the constraints through a function or in a different manner I would also be keen to know.
Cheers
I'm the mystic author. You should always first try just using solve(equations) and see what happens. It can fail to symbolically solve the equations due to the inequalities. If so, then try to do simplify(equalities) instead. That symbolically simplifies equations so there's only one variable on the LHS for each line. The inequality solver usually can then work in that case. If that fails, you can rewrite the equations so there's only one variable on the LHS.
>>> def objective(x):
... x0,x1,x2,x3,x4,x5,x6,x7,x8 = x
... return x0**2 + x4**2 + x8**2
...
>>> import mystic
>>> equations = '''
... x0 + x1 + x2 - x3 - x6 - 20 == 0.0
... x4 + x3 + x5 - x1 - x7 - 150 == 0.0
... x8 + x6 + x7 - x2 - x5 + 100 == 0.0
... x6 == 0
... x7 == 0
... x0 >= 10
... x4 >= 60
... '''
>>> eqns = mystic.symbolic.simplify(equations)
>>> print(eqns)
x0 == -x1 - x2 + x3 + x6 + 20
x8 == x2 + x5 - x6 - x7 - 100
x4 >= 60
x7 == 0
x6 == 0
x0 >= 10
x4 == x1 - x3 - x5 + x7 + 150
>>> from mystic.symbolic import generate_constraint, generate_solvers
>>> cf = generate_constraint(generate_solvers(eqns))
>>> cf([0,1,2,3,4,5,6,7,8])
[26, 1, 2, 3, 143, 5, 0, 0, -106]
>>>
I think I'm facing a Milp problem but I'm not sure.
The problem in a simplified form is: There are 3 suppliers of materials (trucks) for 3 cities. The real problem is 30 Suppliers and 100 cities...
Supliers capacity: a:1; b:2; c:3.
Cities Demand: a:2; b:3; c:1
Distances Supplier(Cities):
a(a:2;b:4;c:6)
b(a:4;b:2;c:4)
c(a:6;b:4;c:2)
like this with each Capacity and Demand
Sa1 - Ca2
Sb2 - Cb3
Sc3 - Cc1
The goal its optimize the suply but there is one (devil) condition:
Just one supplier per city.
Whitout the contidion the problem is a simple problem to solve with basic Linear Programming.
With the condition I think that could be solved with Mixed Integer Linear Programming - MILP.
But not figure it out how to solve this with MILP Method and Pulp (python module).
If someone can help me
Thanks!
My first try
from scipy.optimize import linprog
c = [2,4,6,4,2,4,6,4,2]
Ae = [[1,1,1,0,0,0,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,1,1,1],
[1,0,0,1,0,0,1,0,0],
[0,1,0,0,1,0,0,1,0],
[0,0,1,0,0,1,0,0,1],
]
be = [1,2,3,2,3,1]
x0_bounds = (0,None)
x1_bounds = (0,None)
x2_bounds = (0,None)
x3_bounds = (0,None)
x4_bounds = (0,None)
x5_bounds = (0,None)
x6_bounds = (0,None)
x7_bounds = (0,None)
x8_bounds = (0,None)
sol = linprog(c, A_eq= Ae, b_eq = be, bounds = ((x0_bounds,x1_bounds,x2_bounds,x3_bounds,x4_bounds,x5_bounds,x6_bounds,x7_bounds,x8_bounds)) )
print(sol)
fun: 18.0
message: 'Optimization terminated successfully.'
nit: 10
slack: array([], dtype=float64)
status: 0
success: True
x: array([1., 0., 0., 0., 2., 0., 1., 1., 1.])
Process finished with exit code 0
I've done!
Videos of Caylie Cincera from youtube help me a lot. Illustration of the problem. Each location could receive at most of one supplier.
https://imgur.com/O2CNa9M
from pulp import *
#Pulp way to start a LP problem
prob = LpProblem("testpulp",LpMinimize)
#The 9 Arcs Origin and destiny
x1 = LpVariable("x1_11",0,None,LpInteger)
x2 = LpVariable("x2_12",0,None,LpInteger)
x3 = LpVariable("x3_13",0,None,LpInteger)
x4 = LpVariable("x4_21",0,None,LpInteger)
x5 = LpVariable("x5_22",0,None,LpInteger)
x6 = LpVariable("x6_23",0,None,LpInteger)
x7 = LpVariable("x7_31",0,None,LpInteger)
x8 = LpVariable("x8_32",0,None,LpInteger)
x9 = LpVariable("x9_33",0,None,LpInteger)
#Auxiliar Variables z y and k
z1 = LpVariable("z1",0,1,LpBinary)
z2 = LpVariable("z2",0,1,LpBinary)
z3 = LpVariable("z3",0,1,LpBinary)
y1 = LpVariable("y1",0,1,LpBinary)
y2 = LpVariable("y2",0,1,LpBinary)
y3 = LpVariable("y3",0,1,LpBinary)
k1 = LpVariable("k1",0,1,LpBinary)
k2 = LpVariable("k2",0,1,LpBinary)
k3 = LpVariable("k3",0,1,LpBinary)
#Objective Function
prob += 2*x1 + 4*x2+ 6*x3 + 4*x4 + 2*x5 + 4*x6 + 6*x7 + 4*x8 + 2*x9, "fobj"
#Constraints
#Supply constraints
prob += x1 + x2 + x3 == 1, "m1"
prob += x4 + x5 + x6 == 2, "m2"
prob += x7 + x8 + x9 == 3, "m3"
#Demand constraints
prob += x1 + x4 + x7 == 2, "d1"
prob += x2 + x5 + x8 == 3, "r2"
prob += x3 + x6 + x9 == 1, "r4"
#Trick to force unique supplier for each location
prob += x1 <= 2*y1, "yx1"
prob += x4 <= 2*y2, "yx2"
prob += x7 <= 2*y3, "yx3"
prob += x2 <= 3*z1, "zx1"
prob += x5 <= 3*z2, "zx2"
prob += x8 <= 3*z3, "zx3"
prob += x3 <= 1*k1, "kx1"
prob += x6 <= 1*k2, "kx2"
prob += x9 <= 1*k3, "kx3"
prob += y1 + y2 + y3 == 1, "yk"
prob += z1 + z2 + z3 == 1, "zk"
prob += k1 + k2 + k3 == 1, "kk"
prob.solve()
for v in prob.variables():
print(v.name, " = ", v.varValue)
print("Total Profit: ",value(prob.objective))
#The "optimal" solution of this problem is the unique solution
#The hard part is to force unique supplier for each location
The output:
k1 = 1.0
k2 = 0.0
k3 = 0.0
x1_11 = 0.0
x2_12 = 0.0
x3_13 = 1.0
x4_21 = 2.0
x5_22 = 0.0
x6_23 = 0.0
x7_31 = 0.0
x8_32 = 3.0
x9_33 = 0.0
y1 = 0.0
y2 = 1.0
y3 = 0.0
z1 = 0.0
z2 = 0.0
z3 = 1.0
Total Profit: 26.0
Process finished with exit code 0
I have some puLP code, which solves my knapsack problem.
prob = LpProblem("Knapsack problem", LpMaximize)
x1 = LpVariable("x1", 0, 12, 'Integer')
x2 = LpVariable("x2", 0, 12, 'Integer')
x3 = LpVariable("x3", 0, 12, 'Integer')
x4 = LpVariable("x4", 0, 12, 'Integer')
x5 = LpVariable("x5", 0, 12, 'Integer')
x6 = LpVariable("x6", 0, 12, 'Integer')
x7 = LpVariable("x7", 0, 12, 'Integer')
x8 = LpVariable("x8", 0, 12, 'Integer')
x9 = LpVariable("x9", 0, 12, 'Integer')
x10 = LpVariable("x10", 0, 12, 'Integer')
x11 = LpVariable("x11", 0, 12, 'Integer')
x12 = LpVariable("x12", 0, 12, 'Integer')
x13 = LpVariable("x13", 0, 12, 'Integer')
x14 = LpVariable("x14", 0, 12, 'Integer')
x15 = LpVariable("x15", 0, 12, 'Integer')
x16 = LpVariable("x16", 0, 12, 'Integer')
x17 = LpVariable("x17", 0, 12, 'Integer')
x18 = LpVariable("x18", 0, 12, 'Integer')
x19 = LpVariable("x19", 0, 12, 'Integer')
x20 = LpVariable("x20", 0, 12, 'Integer')
x21 = LpVariable("x21", 0, 12, 'Integer')
x22 = LpVariable("x22", 0, 12, 'Integer')
x23 = LpVariable("x23", 0, 12, 'Integer')
x24 = LpVariable("x24", 0, 12, 'Integer')
x25 = LpVariable("x25", 0, 12, 'Integer')
prob += 15 * x1 + 18 * x2 + 18 * x3 + 23 * x4 + 18 * x5 + 20 * x6 + 15 * x7 + 16 * x8 + 12 * x9 + 12 * x10 + 25 * x11 + 25 * x12 + 28 * x13 + 35 * x14 + 28 * x15 + 28 * x16 + 25 * x17 + 25 * x18 + 25 * x19 + 28 * x20 + 25 * x21 + 32 * x22 + 32 * x23 + 28 * x24 + 25 * x25, "obj"
prob += 150 * x1 + 180 * x2 + 180 * x3 + 230 * x4 + 180 * x5 + 200 * x6 + 150 * x7 + 160 * x8 + 120 * x9 + 120 * x10 + 250 * x11 + 250 * x12 + 280 * x13 + 350 * x14 + 280 * x15 + 280 * x16 + 250 * x17 + 250 * x18 + 250 * x19 + 280 * x20 + 250 * x21 + 320 * x22 + 320 * x23 + 280 * x24 + 250 * x25 == 6600, "c1"
prob.solve()
print "Status:", LpStatus[prob.status]
for v in prob.variables():
print v.name, "=", v.varValue
print ("objective = %s" % value(prob.objective))
But to this code I need append another restriction: For example, a restriction That the number of non-zero prob.variables must equal (say) 10.
Could anybody help with that?
UPDATE:
For this code I have output:
Status: Optimal
X1 = 1.0
x10 = 0.0
x11 = 0.0
x12 = 0.0
x13 = 0.0
x14 = 0.0
x15 = 0.0
x16 = 0.0
x17 = 0.0
x18 = 0.0
x19 = 0.0
x2 = 0.0
x20 = 0.0
x21 = 0.0
x22 = 0.0
x23 = 0.0
x24 = 0.0
x25 = 0.0
x3 = 0.0
x4 = 11.0
x5 = 0.0
x6 = 10.0
x7 = 0.0
x8 = 12.0
x9 = 0.0
objective = 660.0
The number of prob.variables that have non-zero values equals only 4. But say I need 10, how would I ensure that?
If you want a certain number of non-zero values, you can do that by introducing new 0/1 variables.
Formulation
Introduce 25 new Y variables [y1..y25] which are all binary {0,1}
If X[i] > 0, we want Y[i] to take on the value 1.
You can do by adding the following constraints.
x[i] < y[i] x M (where M is some big number, say 10,000) for 1 in 1..25
Now, to ensure that at least 10 Y values are non-zero, we want at least 10 of them to be 1.
Sum over Y[1]...y[25] >= 10 will ensure that.
In PuLP
The puLP code is untested, but will give you the right idea to proceed.
x=[]
y=[]
for index in range(25):
y[index] = LpVariable("y"+str(index), 0, 1) #binary variables
prob += x[index] <= 10000 * y[index], "If x%s is non-zero, then y%s is forced to be 1",%index, %index
prob += lpSum([y[i] for i in range(25)]) >= 10,"Ensuring at least 10 items are non-zero"
Hope that helps.
I second the provided answer, but also would comment on making better use of PuLP's (and Python's) list comprehensions for shorter code:
from pulp import *
prob = LpProblem("Knapsack problem", LpMaximize)
cost = [15,18,18,23,18,20,15,16,12,12,25,25,28,35,28,28,25,25,25,28,25,32,32,28,25]
x = LpVariable.dicts('x',range(1,26),lowBound=0,upBound=12,cat=pulp.LpInteger)
cap = [150,180,180,230,180,200,150,160,120,120,250,250,280,350,280,280,250,250,250,280,250,320,320,280,250]
prob += pulp.lpSum([cost[ix]*x[ix] for ix in range(1,25)]), "obj"
prob += pulp.lpSum([cap[ix]*x[ix] for ix in range(1,25)]) == 6600, "c1"
prob.solve()
print "Status:", LpStatus[prob.status]
for v in prob.variables():
if v.varValue>0.0001:
print v.name, "=", v.varValue
print ("objective = %s" % value(prob.objective))
I may have mistyped some coefficients in there, but I'm sure you get my point.
correct with new version pulp
for correct errors
# Import PuLP modeler functions
from pulp import *
prob = LpProblem("Knapsack_problem", LpMaximize)
cost = [30,18,18,23,18,20,15,16,12,12,25,25,28,35,28,28,25,25,25,28,25,32,32,28,25]
x = LpVariable.dicts('x',range(1,26),lowBound=0,upBound=12,cat=LpInteger)
cap = [150,180,180,230,180,200,150,160,120,120,250,250,280,350,280,280,250,250,250,280,250,320,320,280,250]
prob += pulp.lpSum([cost[ix]*x[ix] for ix in range(1,25)]), "obj"
prob += pulp.lpSum([cap[ix]*x[ix] for ix in range(1,25)]) == 6600, "c1"
prob.solve()
print ("Status:", LpStatus[prob.status])
for v in prob.variables():
if v.varValue>0.0001:
print (v.name, "=", v.varValue)
print ("objective = %s" % value(prob.objective))