Related
I am trying to create a ConcreteModel using Pyomo. I have a list including the indices of the variable x_ij.
Xindex = [(619, 0), (620, 0), (621, 0), (622, 0), (623, 0), (624, 0), (625, 0), (626, 0), (627, 0), (628, 0), (619, 1), (620, 1), (621, 1), (622, 1), (623, 1), (624, 1), (625, 1), (626, 1), (627, 1), (628, 1), (1098, 2), (1099, 2), (1100, 2), (1101, 2), (1102, 2), (1103, 2), (1104, 2), (1105, 2), (1106, 2), (1107, 2), (1098, 3), (1099, 3), (1100, 3), (1101, 3), (1102, 3), (1103, 3), (1104, 3), (1105, 3), (1106, 3), (1107, 3), (619, 4), (620, 4), (621, 4), (622, 4), (623, 4), (624, 4), (625, 4), (626, 4), (627, 4), (628, 4), (1098, 5), (1099, 5), (1100, 5), (1101, 5), (1102, 5), (1103, 5), (1104, 5), (1105, 5), (1106, 5), (1107, 5), (1098, 6), (1099, 6), (1100, 6), (1101, 6), (1102, 6), (1103, 6), (1104, 6), (1105, 6), (1106, 6), (1107, 6), (1098, 7), (1099, 7), (1100, 7), (1101, 7), (1102, 7), (1103, 7), (1104, 7), (1105, 7), (1106, 7), (1107, 7), (1098, 8), (1099, 8), (1100, 8), (1101, 8), (1102, 8), (1103, 8), (1104, 8), (1105, 8), (1106, 8), (1107, 8), (1098, 9), (1099, 9), (1100, 9), (1101, 9), (1102, 9), (1103, 9), (1104, 9), (1105, 9), (1106, 9), (1107, 9), (1098, 10), (1099, 10), (1100, 10), (1101, 10), (1102, 10), (1103, 10), (1104, 10), (1105, 10), (1106, 10), (1107, 10), (1098, 11), (1099, 11), (1100, 11), (1101, 11), (1102, 11), (1103, 11), (1104, 11), (1105, 11), (1106, 11), (1107, 11), (1098, 12), (1099, 12), (1100, 12), (1101, 12), (1102, 12), (1103, 12), (1104, 12), (1105, 12), (1106, 12), (1107, 12)]
The first element of each tuple corresponds to an i and second one to a j. Using this list, I would like to add my variables to the model m. But, I do not see a straightforward method in the Pyomo User Manual. I tried the following and did not work.
m.Xindexi = Set(initialize=[i[0] for i in Xindex])
m.Xindexj = Set(initialize=[j[1] for j in Xindex])
m.Xindex = Set(within = m.Xindexi*m.Xindexj)
m.x = Var(m.Xindexi, m.Xindexj,domain=NonNegativeReals)
Isn't there a way to do this like a dictionary creation (similar to the one Gurobi's Python uses)? For example:
m.x = {}
for i in Xindex:
m.x[i[0],i[1]] = Var(domain=NonNegativeReals)
Based on the accepted answer, this is what I have done to resolve the issue. Adding it here for future reference...
m.Xindexi = Set(initialize=set([i[0] for i in Xindex]))
m.Xindexj = Set(initialize=set([j[1] for j in Xindex]))
m.Xindex = Set(within = m.Xindexi*m.Xindexj,
initialize=Xindex)
m.x = Var(m.Xindex,domain=NonNegativeReals)
There are a bunch of ways to do this. The basic idea here is to make a sparse set of combinations of (i, j). You can either strictly enumerate that sparse set or if for other parts of your model, you need a fuller set of (i, j) and you only need this sparse set for some of the variables/parameters, you can construct it on-the-fly from data or from any set rules you gin up.
Here are some examples:
# pyomo set patterns
from pyomo.environ import *
m = ConcreteModel()
# initialize two sets from data
I_vals = {1, 5, 9}
m.I = Set(initialize=I_vals)
m.J = Set(initialize={2, 4, 88}) # either way works
# crossed set from list of known combinations
my_sparse_indices = {(1, 4), (1, 88), (5, 4)}
m.IJ = Set(within=m.I * m.J, initialize=my_sparse_indices)
# make a variable X, indexed by this sparse set
m.X = Var(m.IJ, domain=NonNegativeReals)
# make a parameter from the same sparse indices
limit_dict = {(1, 4): 10, (1, 88): 20, (5,4): 30}
m.lim = Param(m.IJ, initialize=limit_dict)
m.pprint()
#############
m2 = ConcreteModel()
m2.I = Set(initialize=range(4))
m2.J = Set(initialize=range(3))
# make full x-product
m2.IJ = Set(within=m2.I * m2.J,
initialize=[(i, j) for i in m2.I for j in m2.J])
# make a sparse set from selected values
selected_vals = [(2,1), (1,1)]
m2.IJ_selected = Set(within=m2.IJ, initialize=selected_vals)
# make a sparse set by excluding prohibited values
prohibited={(2,2), (3,1), (0,0)}
IJ_without_prohibited = {(i, j) for i in m2.I
for j in m2.J
if (i, j) not in prohibited}
m2.IJ_without_prohibited = Set(within=m2.IJ, initialize=IJ_without_prohibited)
m2.pprint()
The output for these is:
4 Set Declarations
I : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(1, 9)
[1, 5, 9]
IJ : Dim=0, Dimen=2, Size=3, Domain=IJ_domain, Ordered=False, Bounds=None
[(1, 4), (1, 88), (5, 4)]
IJ_domain : Dim=0, Dimen=2, Size=9, Domain=None, Ordered=False, Bounds=None
Virtual
J : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(2, 88)
[2, 4, 88]
1 Param Declarations
lim : Size=3, Index=IJ, Domain=Any, Default=None, Mutable=False
Key : Value
(1, 4) : 10
(1, 88) : 20
(5, 4) : 30
1 Var Declarations
X : Size=3, Index=IJ
Key : Lower : Value : Upper : Fixed : Stale : Domain
(1, 4) : 0 : None : None : False : True : NonNegativeReals
(1, 88) : 0 : None : None : False : True : NonNegativeReals
(5, 4) : 0 : None : None : False : True : NonNegativeReals
6 Declarations: I J IJ_domain IJ X lim
Second model:
6 Set Declarations
I : Dim=0, Dimen=1, Size=4, Domain=None, Ordered=False, Bounds=(0, 3)
[0, 1, 2, 3]
IJ : Dim=0, Dimen=2, Size=12, Domain=IJ_domain, Ordered=False, Bounds=None
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2)]
IJ_domain : Dim=0, Dimen=2, Size=12, Domain=None, Ordered=False, Bounds=None
Virtual
IJ_selected : Dim=0, Dimen=2, Size=2, Domain=IJ, Ordered=False, Bounds=None
[(1, 1), (2, 1)]
IJ_without_prohibited : Dim=0, Dimen=2, Size=9, Domain=IJ, Ordered=False, Bounds=None
[(0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (3, 0), (3, 2)]
J : Dim=0, Dimen=1, Size=3, Domain=None, Ordered=False, Bounds=(0, 2)
[0, 1, 2]
6 Declarations: I J IJ_domain IJ IJ_selected IJ_without_prohibited
[Finished in 2.6s]
I am new to both Python and NetworkX. I have a square, regular graph G with NxN nodes (a lattice). Such nodes are labelled by means of a dict (see code below). Now I want the edgelist to return the start and endpoint of each edge not by referring to the node coordinates but to the label the node has been given.
Example:
N = 3
G=nx.grid_2d_graph(N,N)
labels = dict( ((i, j), i + (N-1-j) * N ) for i, j in G.nodes() )
#This gives nodes an attribute ID that is identical to their labels
for (i,j) in labels:
G.node[(i,j)] ['ID']= labels[(i,j)]
edgelist=G.edges() #This gives the list of all edges in the format (Start XY, End XY)
If I run it with N=3 I get:
In [14]: labels
Out[14]: {(0, 0): 6, (0, 1): 3, (0, 2): 0, (1, 0): 7, (1, 1): 4, (1, 2): 1, (2, 0): 8, (2, 1): 5, (2, 2): 2}
This scheme labels the upper left node as 0, with node (N-1)th being placed in the lower right corner. And this is what I want. Now the problem with edgelist:
In [15]: edgelist
Out [15]: [((0, 1), (0, 0)), ((0, 1), (1, 1)), ((0, 1), (0, 2)), ((1, 2), (1, 1)), ((1, 2), (0, 2)), ((1, 2), (2, 2)), ((0, 0), (1, 0)), ((2, 1), (2, 0)), ((2, 1), (1, 1)), ((2, 1), (2, 2)), ((1, 1), (1, 0)), ((2, 0), (1, 0))]
I tried to solve the problem with these lines (inspiration from here: Replace items in a list using a dictionary):
allKeys = {}
for subdict in (labels):
allKeys.update(subdict)
new_edgelist = [allKeys[edge] for edge in edgelist]
but I get this wonderful thing which enlightens my monday:
TypeError: cannot convert dictionary update sequence element #0 to a sequence
To sum up, I want to be able to replace the elements of the edgelist list with the values of the labels dictionary so that, say, the edge from ((2,0),(1,0)) (which correspond to nodes 8 and 7) is returned (8,7). Endless thanks!
I believe what you are looking for is simply nx.relabel_nodes(G,labels,False) here is the documentation
Here is the output when I printed the nodes of G before and after calling the relabel nodes function.
# Before relabel_nodes
[(0, 1), (1, 0), (0, 0), (1, 1)]
# After relabel_nodes
[0, 1, 2, 3]
After doing this, the edge labels automatically becomes what you expect.
# Edges before relabelling nodes
[((0, 1), (0, 0)), ((0, 1), (1, 1)), ((1, 0), (0, 0)), ((1, 0), (1, 1))]
# Edges after relabelling nodes
[(0, 1), (0, 2), (1, 3), (2, 3)]
Also, I have replied to this question in the chat that you created but it seems you were not notified.
I have a set of x and y coordinates as follows:
x = (1,1,2,2,3,4)
y= (0,1,2,3,4,5)
What is the best way of going about transforming this list into a multiline string format, e.g:
x_y = [((1,0)(1,1)),((1,1)(2,2)),((2,2)(2,3)),((2,3)(3,4)),((3,4)(4,5))]
You can pair up the elements of x and y with zip():
>>> x = (1,1,2,2,3,4)
>>> y = (0,1,2,3,4,5)
>>> xy = zip(x, y)
>>> xy
[(1, 0), (1, 1), (2, 2), (2, 3), (3, 4), (4, 5)]
Then you can rearrange this into the kind of list in your example with a list comprehension:
>>> x_y = [(xy[i], xy[i+1]) for i in xrange(len(xy)-1)]
>>> x_y
[((1, 0), (1, 1)), ((1, 1), (2, 2)), ((2, 2), (2, 3)), ((2, 3), (3, 4)), ((3, 4), (4, 5))]
If you don't care about efficiency, the second part could also be written as:
>>> x_y = zip(xy, xy[1:])
I am working on the question from this site, one of the question is asking to return Goldbach conjecture in a given range.
My answer works fine for small ranges, but for large range (e.g. 2 - 2000), it only return part of the solution like the following:
[(2, (2, 0)); (4, (2, 2)); (6, (3, 3)); (8, (3, 5)); (10, (3, 7));
(12, (5, 7)); (14, (3, 11)); (16, (3, 13)); (18, (5, 13)); (20, (3, 17));
(22, (3, 19)); (24, (5, 19)); (26, (3, 23)); (28, (5, 23)); (30, (7, 23));
(32, (3, 29)); (34, (3, 31)); (36, (5, 31)); (38, (7, 31)); (40, (3, 37));
(42, (5, 37)); (44, (3, 41)); (46, (3, 43)); (48, (5, 43)); (50, (3, 47));
(52, (5, 47)); (54, (7, 47)); (56, (3, 53)); (58, (5, 53)); (60, (7, 53));
(62, (3, 59)); (64, (3, 61)); (66, (5, 61)); (68, (7, 61)); (70, (3, 67));
(72, (5, 67)); (74, (3, 71)); (76, (3, 73)); (78, (5, 73)); (80, (7, 73));
(82, (3, 79)); (84, (5, 79)); (86, (3, 83)); (88, (5, 83)); (90, (7, 83));
(92, (3, 89)); (94, (5, 89)); (96, (7, 89)); (98, (9, 89)); (100, (3, 97));
(102, (5, 97)); (104, (3, 101)); (106, (3, 103)); (108, (5, 103));
(110, (3, 107)); (112, (3, 109)); (114, (5, 109)); (116, (3, 113));
(118, (5, 113)); (120, (7, ...)); ...]
I tried to use the solution provided by the website, but same thing happens. I wonder if there is a way to return the complete list of solutions.
Thanks!
I think you mean that the toplevel is only showing a prefix of the list. You can solve this by writing your own code to show the list.
Something like this would work:
let p (a, (b, c)) = Printf.printf "(%d, (%d, %d))\n" a b c
let printMyList l = List.iter p l
This is because the toplevel doesn't show values that are too long. You can change this lenght by using a pragma:
#print_length n;;
The other solution, perhaps better, is to write your own printing function. ;)
I have a list of tuples, with nested tuples and lists, that looks like the list bellow:
a= [('Maria', [1, [2, {'teste': (2, 1.0)}]]),
('Lisa ', [2, [4, {'field': (4, 0.75), 'bola': (4, 0.25)}]]),
('John ', [4, [5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}]]),
('Tracy ', [4, [6, {'pizza': (6, 0.16), 'fish': (6, 0.1), 'animals': (6, 0.1)}]])]
I want to flat out this list to look like:
a.modified = ('Maria', 1, 2, {'teste': (2, 1.0)}]]),
('Lisa ', 2, 4, {'field': (4, 0.75), 'bola': (4, 0.25)}]]),
('John ', 4, 5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}]]),
('Tracy ', 4, 6, {'pizza': (6, 0.16), 'fish': (6, 0.1), 'animals': (6, 0.1}]])])
I have tried doing it step by step, using:
a2=[item for sublist in a for item in sublist]
and
a2 = list(itertools.chain.from_iterable(a))
and also:
a2 = list(item for sublist in a for item in sublist)
Nothing seems to work. I know this is too basic, but any tips on how to solve this would be really helpful. Thanks!
So it appears you have a list of tuples and linked-list-like structures. Whenever operating on linked-lists, you should think, recursion.
def flatten(items):
from itertools import chain
def flatten_link(link):
if isinstance(link, list):
yield link[0]
for item in flatten_link(link[1]):
yield item
elif link is not None:
yield link
return list(tuple(chain(item[:1], flatten_link(item[1]))) for item in items)
a = [
('Maria', [1, [2, {'teste': (2, 1.0)}]]),
('Lisa ', [2, [4, {'field': (4, 0.75), 'bola': (4, 0.25)}]]),
('John ', [4, [5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}]]),
('Tracy', [4, [6, {'pizza': (6, 0.16), 'fish': (6, 0.1), 'animals': (6, 0.1)}]]),
]
print(flatten(a))
Which yields:
[
('Maria', 1, 2, {'teste': (2, 1.0)}),
('Lisa ', 2, 4, {'bola': (4, 0.25), 'field': (4, 0.75)}),
('John ', 4, 5, {'engine': (5, 0.2), 'wheel': (5, 0.4), 'wheels': (5, 0.2)}),
('Tracy', 4, 6, {'fish': (6, 0.1), 'animals': (6, 0.1), 'pizza': (6, 0.16)})
]