Extract gurobi muti-dimensional variable value and form a numpy array - python

I want to know that when I defined a multi-dimension variables in Gurobi, how can I extract all the value of the solution and organize them in to a Numpy array according to the original coordinate of the variable.
I have the following decision variables defined in Gurobi using Python API:
for i in range(N):
for t in range(M):
Station_Size[i,t] = m.addVar(ub=Q, name = 'Station_Size_%s_%s' %(i,t))
for j in range(N):
Admission[i,j,t] = m.addVar(ub = Arrival_Rate[t,i,j], obj=-1, name = 'Admission_Rate_%s_%s_%s' %(i,j,t))
Return[i,j,t] = m.addVar(name = 'Return_Rate_%s_%s_%s' %(i,j,t))
I have the problem solved and I have three dictionary:
Station_Size, Admission and Return
I know that the solution can be accessed as:
Station_Size[i,t].X, Admission[i,j,t].X and Return[i,j,t].X
I want to creat three Numpy array such that:
Array_Station_Size[i,t] = Station_Size[i,t].X
Array_Admission[i,j,t] = Admission[i,j,t].X
I can definitely do this by creating three loops and creat the Numpy Array element by element. It's do-able if the loop doesn't take a lot of time. But I just want to know if there is a better way to do this. Please comment if I did not make myself clear.

Assuming your model's name is m, do the following:
Array_Station_Size = m.getAttr('x', Station_Size)
which is a gurobipy.tupledict now.
see gurobi doc here
http://www.gurobi.com/documentation/8.1/quickstart_windows/py_results.html

I figured this problem out.
Do the following:
Array_Station_Size = np.array()
Array_Station_Size[i,] = [Station_Size[i,t].X for t in rang(T)]

Related

Variable indexed by an indexed Set with Pyomo

im trying to figure out how to index a variable with an indexed Set:
For example:
model = AbstractModel()
model.J = Set()
model.O = Set(model.J)
I want to define a variable indexed over both Sets. Can Someone help me? I tried the following:
model.eb=Param(model.J, model.O)
which gives
TypeError("Cannot index a component with an indexed set")
Has anyone any suggestions on how to define this variable properly?
Pyomo doesn't support indexed Sets like that (I'm actually unaware of use cases for indexed sets in Pyomo, although they seem to be a thing in GAMS). You could approach this as follows (using ConcreteModel here, for illustration):
Define Sets for all unique values of jobs and operations (I assume you have some data structure which maps the operations to the jobs):
import pyomo.environ as po
import itertools
model = po.ConcreteModel()
map_J_O = {'J1': ['O11', 'O12'],
'J2': ['O21']}
unique_J = map_J_O.keys()
model.J = po.Set(initialize=unique_J)
unique_O = set(itertools.chain.from_iterable(map_J_O.values()))
model.O = po.Set(initialize=unique_O)
Then you could define a combined Set which contains all valid combinations of J and O:
model.J_O = po.Set(within=model.J * model.O,
initialize=[(j, o) for j in map_J_O for o in map_J_O[j]])
model.J_O.display()
# Output:
#J_O : Dim=0, Dimen=2, Size=3, Domain=J_O_domain, Ordered=False, Bounds=None
# [('J1', 'O11'), ('J1', 'O12'), ('J2', 'O21')]
Create the parameter using the combined Set:
model.eb = po.Param(model.J_O)
This last line will throw an error the parameter is initialized using any non-valid combination of J and O. Alternatively, you can also initialize the parameter for all combinations
po.Param(model.J * model.O)
and only initialize for the valid combinations, but this might bite you later. Also, model.J_O might be handy also for variables and constraints, depending on your model formulation.

Store histograms in a large array depending on location in for loop

I'm trying to store histograms in an array full of nested arrays that are created in multiple for a loop.
The error that I am getting is that: 'TH1F' object has no attribute 'append'
Here's an example of how the code works (a simplified version):
hist = []
for c in range 2:
hist.append([])
for e in range 4:
hist[c].append([])
hist_m = ROOT.TH1F("some name","some name",0,0.0,50.0)
hist[c][e].append(hist_m)
for z in range 8:
hist[c][e].append([])
hist_m = ROOT.TH1F("some name","some name",0,0.0,50.0)
hist[c][e][z].append(hist_m) #crashes here
for pT in range 32:
hist[c][e][z].append([])
hist_m = ROOT.TH1F("some name","some name",0,0.0,50.0)
hist[c][e][z][pT].append(hist_m)
I'm trying to store all of these different histograms inside of this large array so that I can use them later in the code by simply using the index. But I am getting the error
'TH1F' object has no attribute 'append'
which I don't know how to fix. Any solutions?
The code crashes on this line:
hist[c][e][z].append( hist )
Thanks in advance!
Here, and in other places, you're overwriting your hist variable that otherwise points to the large "array" you're building:
hist = ROOT.TH1F("some name","some name",0,0.0,50.0)
Use a different name ...
EDIT: since you now changed the naming, consider that you first add a TH1F:
hist[c][e].append(hist_m)
and afterwards a fresh list:
hist[c][e].append([])
so now the first element of list hist[c][e] is a TH1F, the second is a new list. Ie., you have:
[[[<ROOT.TH1F object ("some name") at 0x556fd65038d0>, []]]]
and zero indexing (c == e == z == 0) selects that TH1F.
The data structure as you seem to envision (an indexing being both a histogram if no further indexing happens, but a list if it does), isn't going to work. (Granted, you can add a __getitem__ method to the TH1F class to return a list, but that'd be a rather odd thing to do.)
If you want to have a large, indexable, "array" of histograms, those histograms will all have to be on the final leaf nodes.

Python - Append to an array whose name is given by a string

I created multiply arrays and want to append something to them, but the user should choose which array he want append it to.
So to clarify what I mean: (The code down under is wrong, but I do not know how I could write it.)
x = []
y = []
def test(pName):
%s.append(1) %pName
test(y)
Edit:
#Jim Fasarakis-Hilliard
I am trying to program in PyGame.
Therefor I have to initalise all the images I want to use.
To not expand it, I wanted to create a function where you can easily append to any array you want to, so I do not have to create a new function every time I want to initalise new pictures.
My code looks like this atm.:
def loadImages(self,pName,pAnz,pScaleX,pScaleY):
for i in range(0,pAnz):
tux = pygame.transform.scale(pygame.image.load('./images/%s.png'),(pScaleX,pScaleY) % pName)
self.%s.append(tux) %pName
length_array = len(self.%s) %pName
return length_array
You could use globals, pass a string of the variable name to the function:
def test(pName):
globals()[pName].append(1)
test('y')
this, of course, relies on the name existing in the global scope.
You could put the array's in a dictionary. Assuming that there is a fixed number of arrays, the code would look something like this:
arrays = {}
arrays['x'] = []
arrays['y'] = []
def test(pName):
arrays[pName].append(1)
test('y')
You will want to check the user input, as a pName which is not a key in the dictionary will throw a key exception. If you want the arrays to be dynamic, you could do something like this:
arrays={}
def test(pName):
if pName not in arrays.keys():
arrays[pName]=[]
arrays[pName].append(1)
test('y')
If all you want is to be able to save your objects into different "namespaces", you can use dictionaries:
lists = {
"x": [],
"y": []
}
def test(pName):
lists[pName].append(1)
test("y")
Cleaner and easier to understand than using globals or similars IMHO.

creating new numpy array dataset for each loop

I need to create a new dataset variable everytime within a for loop
using .append as below wont work. Note the shape of each numpy array type variable is (56, 25000)
ps=[1,2,3,4]
for subj in ps:
datapath = '/home/subj%d' % (subj)
mydata.append = np.genfromtext(datapath, mydatafile)
so basically I need her 4 instances of mydata, each with a shape of (56, 25000), or that for each loop a new dataset variable is created eg mydata1, ..., mydata4....however .append won't do it. I could do this with
if ps==1: mydata1 = np.genfromtext(datapath, mydatafile)
if ps==2: mydata2 = np.genfromtext(datapath, mydatafile)
etc but I have far to many instances of ps, so would be nice to loop it
thanks!
It's hard to say without more code, but .append is generally a method, and should be called like this:
some_container.append(your_object)
Note I'm also initializing mydata to be an empty list -- you don't show how you initialize it (if you do at all), so just be aware:
mydata = []
for subj in [1,2,3,4]:
datapath = '/home/subj%d' % (subj)
mydata.append( np.genfromtext(datapath, mydatafile) )
Then, mydata will be a 4-element Python list of numpy arrays.
There is also numpy's vstack() and concatenate() functions which may be worth looking in to.
Lastly, just wanted to point out that
ps = [1,2,3,4]
for sub in ps:
...
Can be written as (as I do above):
for sub in [1,2,3,4]:
...
but also as:
for sub in range(1,5):
...
# or
for sub in range(4):
datapath = '/home/subj%d' % (subj + 1)
...

For Loop error?

I'm new to Python, but I'm trying to learn. I'm trying to recreate a Matlab for loop in Python. The Matlab for loop looks like this:
for i = 2:(L-1)
Acceleration_RMT5_x(i-1) = (RMT5(i+1,1)-2*RMT5(i,1)+RMT5(i
1,1))/(1/FrameRate)^2;
end
The datatype is float64, and is a 288x1 vector. My Python so far is:
for i in RMT5x:
Acceleration_RMT5x = RMT5x[i+1] -2*RMT5x[i] +RMT5x[i-1]/(1/250)^2)
This gives me "invalid syntax".
What do I need to fix to resolve this error?
To raise something to a power in Python you need ** not ^
Also you are looping through the values of RMT5x but you are trying to use the value (i) as an index. Instead you want to loop through the index.
Acceleration_RMT5x = list()
for i in range(1, len(RMT5x)-1):
Acceleration_RMT5x.append(RMT5x[i+1] -2*RMT5x[i] +RMT5x[i-1]/(1./250)**2)
I would use a list comprehension:
import numpy as np
Acceleration_RMT5x = [np.power( (RMT5(i+1,1)-2*RMT5(i,1)+RMT5(i-1,1))/(1/FrameRate), 2)]

Categories

Resources