Pyomo creating a variable time index - python

I'm trying to bring this constraint in my pyomo model
[1
I define a set for indexing over time and I want to optimize the corresponding energy variable below
model.grid_time = Set(initialize=range(0, 23)))
model.charging_energy = Var(model.grid_time, initialize=0)
My constraint definition looks like as follows:
model.limits = ConstraintList()
for t in model.grid_time:
model.limits.add(sum(model.charging_energy[t] for t in model.grid >= energy_demand.at[t,"total_energy_demand"])
The problem with these codelines is that I'm summing over the whole indexing set model.grid_time and not just up to t. I think I need a second variable indexing set (replacing for t in model.grid), but I'm searching unsuccessfully after how creating a variable index set..
I would appreciate any help or comment!

Would something like this work?
def Sum_rule(model, v, t):
return sum(model.Ech[t2] for t2 in model.grid_time if t2 <= t) <= model.Edem[v,t]
model.Sum_constraint = Constraint(model.grid_time, model.V, rule=Sum_rule)
Essentially, what happens is that the t in the Sum_rule(model, v, t) makes sure that the constraint is called for each t in model.grid_times. The t2 in the sum is also part of model.grid_times, but it will only take values that are smaller than the t at which the constraint is called.
I am not sure if my constraint matches exactly your notation, as you have not provided all the information required (e.g. regarding the subscript v of the E^dem variable, but it will basically do what you want with the sum.

Related

Pyomo Constraint iteration for Optimal Power Flow

I am solving a DC Optimal Power Flow Problem and I am trying to brainstorm the most efficient way to iterate over a constraint in Pyomo.
The following is the data structure, where i and k are the nodes connected through a branch, and X is the reactance, a property of the branch.
Sample Branch Data
The constraint I am having trouble with is the following:
constraint
Where the symbol "delta" and "p" is a variable in the constraint, each node has a single value of delta and p. What this constraint basically does, is it insures that all the powers flowing into the node i, from all the connected nodes k, are equal to the existing power value in the same node.
Here is an example for i=1 and i=2, iterations of the constraint.
Sample constraint
So I am trying to find the most efficient way to state this constraint in pyomo, where instead of having several constraint iterations written like this:
def P1_rule(modelo):
return modelo.p[0]-L[0]== ((modelo.d[0]-modelo.d[1])/0.1)+((modelo.d[0]-modelo.d[2])/0.1)
model.P1 = Constraint(rule=P1_rule)
def P2_rule(modelo):
return modelo.p[1]-L[1]==((modelo.d[1]-modelo.d[0])/0.1)+((modelo.d[1]-modelo.d[2])/0.1)
model.P2 = Constraint(rule=P2_rule)
def P3_rule(modelo):
return modelo.p[2]-L[2] ==((modelo.d[2]-modelo.d[0])/0.1)+((modelo.d[2]-modelo.d[1])/0.1)
model.P3 = Constraint(rule=P3_rule)
I want a single line like this, so that it easily generalizes over a huge network:
def P3_rule(modelo):
return modelo.p[i] ==((modelo.d[i]-modelo.d[k])/X[k])
model.P3 = Constraint(rule=P3_rule)
I have came up with a way that includes restructuring the data and creating new arrays of indices etc... I would like to see if i can apply the constraint using the data keeping the same structure and more directly.
Ok so I figured out how to do it. The best way, which I didn't know was possible, is through making an if statement within the summation, so basically make a full conditional iteration inside of the summation. In the code bellow, G is the list of nodes, while "From" and "To" are the branch number columns in the FullBranch data table.
def Try_rule(mod,g):
return mod.p[g] - L[g] == sum((mod.d[i-1]-mod.d[k-1])/FullBranch.loc[x,"X"] for x,(i,k) in enumerate(zip(FullBranch["From"], FullBranch["To"])) if i == g+1)
model.Try = Constraint(G,rule=Try_rule)

How to add condition to gurobi

I have variables whose values change every hour during the day (24 values):
plants = ['Plant1', 'Plant2']
users = ['user1', 'user2']
time_steps = range(0,24)
p_gen = model.addVars(plants, time_steps, name="pow_gen")
tot_consume = model.addVars(users, time_steps, name="total_demand")
p_grid = model.addVars(time_steps, lb = -GRB.INFINITY, name="exch_pow")
I want to implement something like this:
If ((quicksum(p_gen[t] for pp in plants) - quicksum(tot_d[u,t] for u in users) )>= p_grid[t] for t in time_steps)
model.addConstrs(A)
model.addConstrs(B)
else:
model.addConstrs(C)
My problem is that Gurobi does not understand the variables which depend on the time. I want to implement if the condition, so it depends on the condition the program, will you different addConstr.
How to implement this condition in Gurobi?
Linear Programming doesn't work like this.
You have constraints and your model must fulfill them, otherwise your model is infeasible.
You can't put constraints based on constraints conditions, if anything you can put constraints based on boolean conditions (like a setting, a value...) or you can put boolean constraints.
You can, however, have two models at the same time, with the same vars and constraints before the if / else branches.
You can resolve the first model, get the value you need with the x attribute (just call variable.x to get its value), and with that value you can select which constraints add to second model, and then resolve it.

Pyomo: is possible to assign to a design variable only defined values?

I want that a design variable assumes only specified values during optimization process.
For example:
Let x be the variable which can assume only specific value, e.g.:
x = [0.1,0.5,1.0,1.7,2.3]
How can be written in python using pyomo (if it's possible)?
I hope I was clear.
You have to do this with integer variables. For example, if there are N possible values of x, then let x[n] = 1 if x equals the nth possible value, and 0 otherwise. Any time you have an x in your original model, replace it with
sum {n=1,...,N} v[n] * x[n]
where v[n] is the nth possible value. Finally, add a constraint that says:
sum {n=1,...,N} x[n] == 1
I'm not writing these in Pyomo syntax, but this is a general modeling approach that is the same no matter what modeling language/package you use.

for loop iteration-population conflict

I am new in python and I am trying to learn it by myself. I am currently working on a code, which gives me index error because somehow for loop does not populate my data. I am supposed to iterate a value and with it, I depend on the previous value to produce the new value. Normally this was easy with matlab, only with x(:,k) but python does not work the same way and I will really be grateful for any help that does not judge my level of knowledge in python. Here how it goes:
x = np.matrix([[1.2],[.2]]) # prior knowledge
A = np.matrix([[1, 1], [0, 1]])
B = np.matrix([[.5], [1]])
U = -9
t1 = range(1,100,1)
for k, val in enumerate(t1):
x[:,k] = A*x[:,k-1] + B*U
To my understanding, the error 'IndexError: index 1 is out of bounds for axis 1 with size 1' pops up because the for loop does not populate the data 'x' and therefore, there is no value for neither 'k-1' nor 'k'.
What I should do is to iterate and store 'x' values and pick the relevant previous value each time to obtain new value with given equation till the end of loop. As you can see, I have a column matrix and I should have a column matrix each time. I hope I could make myself clear.
Thank you
The first line is the initial value of x, the second, third, fourth and fifth lines are the values that are used in for loop to calculate iterations for x.
What I am trying to implement is code for kaman filter in general. In this system, the current value x(k) is calculated with previous value x(k-1) with given equation x(k) = Ax(k-1) + BU. Each x(k) value becomes x(k-1) in next iteration until loop is executed. Here, I am expecting to have (2,k) matrix after every loop because record of values are essential for other calculations. And to use the previous value in current value, I need to access to (k-1)th value.
The question was solved by juanpa.arrivillaga (https://stackoverflow.com/users/5014455/juanpa-arrivillaga) Thank you.

Update a key by calling a recursive function, updating other keys during same sequence

I'm excited to ask my first question here. I've run into some problems with recursion. I am coding with Python.
I am using a dictionary to store previously solved numbers in a mathematical sequence. I then check this dictionary when solving later sequences to make the program run faster. Each key represents solved 'starting numbers,' the value represents how long it took the sequence to take the starting number and take it down to 1 using a particular formula.
I'm solving the problem using recursion, which itself is very easy but there's more to it for me.
Each recursive step gives me the opportunity to update a different key in the library, but I am unable to find a way to do this.
So where a sequence might look like 13 -> x -> y -> z ... -> 1, what would you do to not only update the 13 key with value, but also the x, y, x values in the dictionary during the same recursive path? Right now I'm only able to update one number per sequence.
cache = {1:1}
def solve(number):
if cache.has_key(number):
return cache[number]
else:
if condition one..
return 1 + solve(number * formula 1)
else condition two...
return 1 + solve(number * formula 2)
for x in xrange(1,1000):
cache[x] = solve(x) <-- right now only cache[x] is being updated.
Thank you!
Couldn't you just put it in cache before returning it for each recursive call?
instead of:
return 1 + solve(number * formula 1)
you'd do:
result = 1 + solve(number * formula 1)
cache[number] = result
return result
Or are you after something different?
In principle the dictionary.update() method is able to update several values of a dictionary in one shot. But I assume your problem lies in the fact, that you update cache[x] only in the caller, i. e. outside of the recursion.
You can update another parameter of solve to contain all of the numbers in the sequence, like
def solve(number, valueList):
...
...
if condition one:
valueList.append(number)
return 1 + solve(number * formula 1, valueList)
etc. I'm assuming that what you mean by "the numbers in the sequence" are the ones that meet condition 1 or 2 before being accepted.
If you don't have a problem with Mattias' answer, his is more straightforward. I'm assuming that for whatever reason, you don't want to add to the cache until the recursion finishes.
Anyway, when the recursion finishes, you can iterate through valueList and add it to cache.

Categories

Resources