Google OR Tools constraints from DataFrame

佐手、 提交于 2019-12-13 20:18:55

问题


I would like to build a Google OR Tools model to use linear_solver for a CBC_MIXED_INTEGER_PROGRAMMING. Following Google tutorial I learned hot to build the constraints but I have a question...is it necessary to hand write every constraint? I mean, I have the following DataFrame df_constraint which contain the coefficient of the constraints in the form of ax+by<=c.

+---+---+---+
| A | B | C |
+---+---+---+
| 1 | 5 | 7 |
| 2 | 9 | 3 |
| 3 | 0 | 4 |
+---+---+---+

the table could be translated into the following contraints

# 1x+5y<=7
constraint1 = solver.Constraint(-solver.infinity(), 7)
constraint1.SetCoefficient(x, 1)
constraint1.SetCoefficient(y, 5)

# 2x+9y<=3
constraint2 = solver.Constraint(-solver.infinity(), 3)
constraint2.SetCoefficient(x, 2)
constraint2.SetCoefficient(y, 9)

# 3x<=4
constraint3 = solver.Constraint(-solver.infinity(), 4)
constraint3.SetCoefficient(x, 3)

Instead of write every rows I would like something like this:

for index, row in df.iterrows():
    constraint = solver.Constraint(-solver.infinity(), row['C'])
    constraint.SetCoefficient(x, row['A'])
    constraint.SetCoefficient(y, row['B'])

My snippet won't work, as every constraint must have a different name (like constraint1, constraint2, ...).


回答1:


does this, solve your issue ?

 df_constraints = pd.DataFrame({
    'A': pd.Series([1, 2, 3]),
    'B': pd.Series([5, 9, 0]),
    'C': pd.Series([7, 3, 4]),
    })
for row in df_constraints.itertuples():
    #print("row {}".format(row))
    #print("A {}".format(row[0]))
    #print("B {}".format(row[1]))
    #print("C {}".format(row[2]))
    constraint = solver.Constraint(-solver.infinity(), row[2])
    constraint.SetCoefficient(x, row[0])
    constraint.SetCoefficient(y, row[1])



回答2:


In fact, OR-Tools doesn't require each constraint to have a unique name. But the following gives them unique names anyway. As mentioned above, if you need to store the constraints, you can do so in an array as follows. Here I'm using the more common notation (A is the constraint coefficients, B is the constraint right-hand sides, c is the objective coefficients). But it will adapt to your Pandas setup.

from ortools.linear_solver import pywraplp # adapted from one of the examples

inf = float("inf")

AB = [
    [1, 0, 1], # x <= 1
    [0, 1, 2], # y <= 2
    [1, 1, 2], # x + y <= 2
    [-1, -1, 0] # x + y >= 0
]
c = [3, 1]

def main():
    solver = pywraplp.Solver('simple_lp_program',
                             pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)
    x = solver.NumVar(-inf, inf, 'x') # no UB or LB on x, y
    y = solver.NumVar(-inf, inf, 'y')

    cts = []
    for i, (*a, b) in enumerate(AB):
        ct = solver.Constraint(-inf, b, 'ct' + str(i))
        ct.SetCoefficient(x, a[0])
        ct.SetCoefficient(y, a[1])
        cts.append(ct)

    print('Number of constraints =', solver.NumConstraints())
    objective = solver.Objective()
    objective.SetCoefficient(x, c[0])
    objective.SetCoefficient(y, c[1])
    objective.SetMaximization()
    solver.Solve()
    print('Solution:')
    print('Objective value =', objective.Value())
    print('x =', x.solution_value())
    print('y =', y.solution_value())

if __name__ == '__main__':
    main()


来源:https://stackoverflow.com/questions/54519478/google-or-tools-constraints-from-dataframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!