I have a question regarding the toolbox PyMacroFin.
Is handling simultaneous constraints possible? I mean for example we>1 && wr<0? (we and wr are two endogenous variables that need to be constrained at the same time)
You would do that as follows, following this page of the documentation:
m.constraint(‘we’,’>’,1, label=’one’)
m.constraint(‘wr’,’<’,0, label=’two’)
s = system([‘one’,’two’],m)
…
m.systems.append(s)
Basically, you just add the list of constraint labels to the system. The solution procedure should sort the systems such that if you have a system with both constraints, then another system with just one of the constraints, it will check for the combined constraints first, then check for the individual constraints. For example, you can do the following:
m.constraint(‘we’,’>’,1, label=’one’)
m.constraint(‘wr’,’<’,0, label=’two’)
s1 = system([‘one’,’two’],m)
…
m.systems.append(s1)
s2 = system([‘one’],m)
…
m.systems.append(s2)
If we <= 1 and wr >=0, then it will switch to system s1. If however we <= 1 and wr < 0, it will switch to system 2.
Related
I can't manage to find a way to create a constraint that sounds like this: for example I have 2 variables, one is a regular product and the other one is a super rare product. In order to have a super rare product, you will need to have already 25 of the regular version of that product. This can be stackable (e.g. if the algorithm select 75 of that regular product, it can have 3 super rare). The reason for this is that the super rare is more profitable, so if I place it without any constraints, it will select only the super rare ones. Any ideas on how to write such a constraint?
Thanks in advance!
Part of the code:
hwProblem = LpProblem("HotWheels", LpMaximize)
# Variables
jImportsW_blister = LpVariable("HW J-Imports w/ blister", lowBound=20, cat=LpInteger) # regular product
jImportsTH = LpVariable("HW J-Imports treasure hunt", lowBound=None, cat=LpInteger) # super rare product
# Objective Function
hwProblem += 19 * jImportsW_blister + 350 * jImportsTH # profit for each type of product
# Constraints
hwProblem += jImportsW_blister <= 50, "HW J-Imports maximum no. of products"
hwProblem += jImportsTH <= jImportsW_blister / 25
# ^this is where the error is happening
There's a few "missing pieces" here regarding the structure of your model, but in general, you can limit the "super rare" (SR) by doing something like:
prob += SR <= R / 25
I am new to Pyomo and python and am currently trying to build a MILP model. It'd be great if someone can help me out on this.
So in my production model, I have packing families,pf, and a packing line,l, can handle a packing family at a time. I also have a set of products, p.
In my model, capacity is reserved on a family level, so I want to construct sets in such a way that pf1 in set pf includes product p1,p2,p3,p4 and pf2 includes p5,p6,p7,p8. For instance, a constraint for implementing packing capacity restriction would be:
model.ct6rePackCap = ConstraintList()
for pf in model.PF for l in model.L for t in model.T for s in model.S for n in model.N:
lhs = sum(r[p,l,t,s,n] for p in model.P)
rhs = RPack[l,pf,t,s]
model.ct6reCap.add (lhs <= rhs)
Here r is the quantity of product with product index p and RPack is the capacity reserved for the packing family pf, to which each p belongs. How can I connect p and pf here such that each element of pf (pf1, pf2..) contains a set of products e.g. (pf1 = (p1,p2,p3,p4), pf2 =(p5,p6,p7,p8)) ?
I read pyomo document and read something about subset but it didn't seem like it would achieve what I want.
Thanks a lot in advance!
I have been trying to get into python optimization, and I have found that pyomo is probably the way to go; I had some experience with GUROBI as a student, but of course that is no longer possible, so I have to look into the open source options.
I basically want to perform an non-linear mixed integer problem in which I will minimized a certain ratio. The problem itself is setting up a power purchase agreement (PPA) in a renewable energy scenario. Depending on the electricity generated, you will have to either buy or sell electricity acording to the PPA.
The only starting data is the generation; the PPA is the main decision variable, but I will need others. "buy", "sell", "b1" and "b2" are unknown without the PPA value. These are the equations:
Equations that rule the problem (by hand).
Using pyomo, I was trying to set up the problem as:
# Dataframe with my Generation information:
January = Data['Full_Data'][(Data['Full_Data']['Month'] == 1) & (Data['Full_Data']['Year'] == 2011)]
Gen = January['Producible (MWh)']
Time = len(Generacion)
M=100
# Model variables and definition:
m = ConcreteModel()
m.IDX = range(time)
m.PPA = Var(initialize = 2.0, bounds =(1,7))
m.compra = Var(m.IDX, bounds = (0, None))
m.venta = Var(m.IDX, bounds = (0, None))
m.b1 = Var(m.IDX, within = Binary)
m.b2 = Var(m.IDX, within = Binary)
And then, the constraint; only the first one, as I was already getting errors:
m.b1_rule = Constraint(
expr = (((Gen[i] - PPA)/M for i in m.IDX) <= m.b1[i])
)
which gives me the error:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-5d5f5584ebca> in <module>
1 m.b1_rule = Constraint(
----> 2 expr = (((Generacion[i] - PPA)/M for i in m.IDX) <= m.b1[i])
3 )
pyomo\core\expr\numvalue.pyx in pyomo.core.expr.numvalue.NumericValue.__ge__()
pyomo\core\expr\logical_expr.pyx in pyomo.core.expr.logical_expr._generate_relational_expression()
AttributeError: 'generator' object has no attribute 'is_expression_type'
I honestly have no idea what this means. I feel like this should be a simple problem, but I am strugling with the syntax. I basically have to apply a constraint to each individual data from "Generation", there is no sum involved; all constraints are 1-to-1 contraints set so that the physical energy requirements make sense.
How do I set up the constraints like this?
Thank you very much
You have a couple things to fix. First, the error you are getting is because you have "extra parenthesis" around an expression that python is trying to convert to a generator. So, step 1 is to remove the outer parenthesis, but that will not solve your issue.
You said you want to generate this constraint "for each" value of your index. Any time you want to generate copies of a constraint "for each" you will need to either do that by making a constraint list and adding to it with some kind of loop, or use a function-rule combination. There are examples of each in the pyomo documentation and plenty on this site (I have posted a ton if you look at some of my posts.) I would suggest the function-rule combo and you should end up with something like:
def my_constr(m, i):
return m.Gen[i] - m.PPA <= m.b1[i] * M
m.C1 = Constraint(m.IDX, rule=my_constr)
I am completely new to fipy. I am trying to solve the following set of pdes across two different domains using fipy. The variables are p,n and ψ and q,Dn,Dp,un,up,e and N are all constants. N and e change values from domain 1 to domain 2. Domain 2 is a rectangular domain stacked above a similar rectangular domain 1. The variables p and n are to be solved for in domain 1 and ψ is to be solved for in both the domains- domain1 and domain 2.
qDn∇2n − qun∇.(n∇ψ) = q(n-10**11)/10**(-6), in Domain 1
qDp∇2p + qup∇.(p∇ψ) = -q(p-10**21)/10**(-6), in Domain 1
∇2ψ = −(p − n- N)/e in Domain 1
e∇2ψ = 0 in Domain 2
The code that I have written for solving the pdes has been attached below.
! pip install pyparse
from fipy import *
L= 10**(-6)
h= 20**(-6)
tox= 0.1*10**(-6)
q=1.6*10**(-19)
un=0.14
up=0.045
Vth=0.026
Dp= up*Vth
Dn=un*Vth
p0= 10**(21)
n0= 10**(11)
e0=8.854*10**(-12)
mesh1= Grid2D(dx= L/100,nx=100,dy=h/200,ny=200)
mesh2= Grid2D(dx= L/100,nx=100,dy=tox/10,ny=10)
mesh3= mesh1+(mesh2+[[0],[h]]) # final mesh
x,y= mesh3.cellCenters
N= 10**21*(y<=h) # N changes from Domain 1 to Domain 2
e= 11.9*e0*(y<=h)+ 3.9*e0*(y>h) # e changes from Domain 1 to Domain 2
p1=CellVariable(name='hole',mesh=mesh3,hasOld=True,value=p0)
n1=CellVariable(name='electron',mesh=mesh3,hasOld=True,value=n0)
psi=CellVariable(name='potential',mesh=mesh3,hasOld=True,value=1)
p=p1*(y<=h) # for domain separation
n=n1*(y<=h) # for domain separation
mask1=((y==0))
mask2=(y==h)
mask3=(y==(h+tox))
# 1e50 is the large value
# boundary conditions are p(x,0)= p0, n(x,0)= n0, psi(x,0)= 0, p(x,h)= p0*exp(-psi/Vth), n(x,h)= n0*exp(psi/Vth), psi(h+tox)= 5
eq1=(DiffusionTerm(coeff=q*Dn,var=n)-ConvectionTerm(coeff=q*un*psi.faceGrad,var=n)==ImplicitSourceTerm(coeff=q*(n-10**5)/10**(-6),var=n)-ImplicitSourceTerm(mask1*1e50)-ImplicitSourceTerm(mask2*1e50)+mask1*1e50*n0+mask2*1e50*n0*numerix.exp(psi/Vth))
eq2=(DiffusionTerm(coeff=q*Dp,var=p)+ConvectionTerm(coeff=q*up*psi.faceGrad,var=p)==ImplicitSourceTerm(coeff=-q*(p-10**15)/10**(-6),var=p)-ImplicitSourceTerm(mask1*1e50)-ImplicitSourceTerm(mask2*1e50)+mask1*1e50*p0+mask2*1e50*p0*numerix.exp(psi/Vth))
eq3=(DiffusionTerm(coeff=e,var=psi)==ImplicitSourceTerm(coeff=-q*(p-n-N),var=psi)-ImplicitSourceTerm(mask1*1e50)-ImplicitSourceTerm(mask2*1e50)-ImplicitSouceTerm(mask3*1e50)+mask1*1e50*0+mask2*1e50*psi+mask3*1e50*5)
eq= eq1 & eq2 & eq3
for t in range (50):
p.updateOld()
n.updateOld()
psi.updateOld()
eq.solve(dt=10) # Since the equation does not have any transient term, a large value of dt=5 has been chosen
Now, I am getting the following error: ExplicitVariableError: Terms with explicit Variables cannot mix with Terms with implicit Variables.
I am also not sure whether the coupling between the equations actually work out considering the way I have written the code.
Please note that I am actually solving a MOSCAP using the above pdes.
Any help regarding this would be highly appreciated.
FiPy does not support this usage. One set of equations govern one set of variables defined on one domain. n, p, and psi must all exist on the same mesh in order to be able to write eq3.
Define all equations on mesh3.
Use an internal constraint on n and p.
You will not be able to use mesh1.facesTop and mesh1.facesBottom. Define the internal boundary parametrically.
Note: e should be moved to the diffusion coefficient in eq3. This is both physically correct (divergence of the electric displacement field goes like the charge) and necessary to account for the step in permittivity at the boundary between your subdomains.
I'm trying to solve my MIP with CPLEX (python). I'm new to CPLEX (for the record also new to MIP). I have my objective function containing two variables so this implies I only have to declare two variables right?
e.g.:
first_scene = list(cpx.variables.add(.....
last_scene = list(cpx.variables.add(.....
My problem is I have a constraint that uses other variable thus I don't understand how to construct this contraint. More specific what I should use as indices.
## Constraint: Each scene j can be assigned to at most one shooting day:
## sum(k in shooting_days) presence[j][k] <=1 || for each scene
for j in range(number_of_scenes):
cpx.linear_constraints.add(
lin_expr=[cplex.SparsePair(
ind=??, val=??)],
senses=["L"],
rhs=[1.0])
I define presence_matrix earlier as:
presence_matrix = np.zeros(shape=(number_of_scenes,int(number_of_shooting_days)))