Ограничения Google OR Tools из DataFrame

Я хотел бы построить модель Google OR Tools для использования linear_solver для CBC_MIXED_INTEGER_PROGRAMMING, После обучения Google я научился создавать ограничения, но у меня возник вопрос: нужно ли писать каждое ограничение вручную? Я имею в виду, у меня есть следующий DataFrame df_constraint которые содержат коэффициент ограничений в виде ax+by<=c,

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

таблицу можно перевести на следующие ограничения

# 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)

Вместо того, чтобы писать все строки, я хотел бы что-то вроде этого:

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

Мой фрагмент не будет работать, так как каждое ограничение должно иметь другое имя (например, constraint1, constraint2...).

1 ответ

Это решить вашу проблему?

 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])

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()
Другие вопросы по тегам