0

I am a new Pyomo/Python user. Now I need to formulate one set of constraints with index 'n', where all of the 3 components are with different indices but correlate with index 'n'. I am just curious that how I can map the relationship between these sets.

In my case, I read csv files in which their indices are related to 'n' to generate my set. For example: a1.n1, a2.n3, a3.n5 /// b1.n2, b2.n4, b3.n6, b4.n7 /// c1.n1, c2.n2, c3.n4, c4.n6 ///. The constraint expression of index n1 and n2 is the follows for example:

for n1: P(a1.n1) + L(c1.n1) == D(n1)
for n2: - F(b1.n2) + L(c2.n2) == D(n2)

Now let's go the coding. The set creating codes are as follow, they are within a class:

import pyomo
import pandas
import pyomo.opt
import pyomo.environ as pe

class MyModel:

    def __init__(self, Afile, Bfile, Cfile):
        self.A_data = pandas.read_csv(Afile)
        self.A_data.set_index(['a'], inplace = True)
        self.A_data.sort_index(inplace = True) 
        self.A_set = self.A_data.index.unique()

        ... ...

Then I tried to map the relationship in the constraint construction like follows:

    def createModel(self):

        self.m = pe.ConcreteModel()

        self.m.A_set = pe.Set( initialize = self.A_set )

        def obj_rule(m):
            return ...
        self.m.OBJ = pe.Objective(rule = obj_rule, sense = pe.minimize)

        def constr(m, n)
            As = self.A_data.reset_index()
            Amap = As[ As['n'] == n ]['a']
            Bs = self.B_data.reset_index()
            Bmap = Bs[ Bs['n'] == n ]['b']
            Cs = self.C_data.reset_index()
            Cmap = Cs[ Cs['n'] == n ]['c']

            return sum(m.P[(p,n)] for p in Amap) - sum(m.F[(s,n)] for s in Bmap) + sum(m.L[(r,n)] for r in Cmap) == self.D_data.ix[n, 'D']
        self.m.cons = pe.Constraint(self.m.D_set, rule = constr)

    def solve(self):
        ... ...

Finally, the error raises when I run this:

KeyError: "Index '(1, 1)' is not valid for indexed component 'P'"

I know it is the wrong way, so I am wondering if there is a good way to map their relationships. Thanks in advance!

Gabriel

Gabriel Yin
  • 53
  • 1
  • 6
  • What do you mean by "map relationship"? – V. Brunelle Jan 10 '19 at 14:24
  • Just look into my example at the beginning of the problem. Imagine an inventory problem, but one position might have multiple stocks and multiple customers (the distance between those customers in one position is neglected). Then it turns out to have one index for the position, one index for the customer and one index for the stocks, and they have correlations. For example, position a1 has two customers b1 and b2, and one stock c1, position a2 has one customer b3 and two stocks c2 and c3, then the correlation, or the map, can be formulated as : a1.b1, a1.b2, a2.b3, a1.c1, a2.c2, a2.c3. – Gabriel Yin Jan 11 '19 at 15:53

1 Answers1

2

I just forgot to post my answer to my own question when I solved this one week ago. The key thing towards this problem is setting up a map index.

Let me just modify the code in the question. Firstly, we need to modify the dataframe to include the information of the mapped indices. Then, the set for the mapped index can be constructed, taking 2 mapped indices as example:

self.m.A_set = pe.Set( initialize = self.A_set, dimen = 2 )

The names of the two mapped indices are 'alpha' and 'beta' respectively. Then the constraint can be formulated, based on the variables declared at the beginning:

def constr(m, n)
    Amap = self.A_data[ self.A_data['alpha'] == n ]['beta']
    Bmap = self.B_data[ self.B_data['alpha'] == n ]['beta']
    return sum(m.P[(i,n)] for i in Amap) + sum(m.L[(r,n)] for r in Bmap) == D.loc[n, 'D']
m.TravelingBal = pe.Constraint(m.A_set, rule = constr)

The summation groups all associated B to A with a mapped index set.

Gabriel Yin
  • 53
  • 1
  • 6