【问题标题】:Google OR Tools constraints from DataFrame来自 DataFrame 的 Google OR Tools 约束
【发布时间】:2019-06-28 09:22:26
【问题描述】:

我想构建一个 Google OR Tools 模型,以将 linear_solver 用于 CBC_MIXED_INTEGER_PROGRAMMING。 在Google tutorial 之后,我学会了构建约束,但我有一个问题......是否有必要手写每个约束? 我的意思是,我有以下 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'])

我的 sn-p 不起作用,因为每个约束都必须有不同的名称(例如 constraint1constraint2、...)。

【问题讨论】:

  • 你能用完整的模型和数据框创建一个最小的 sn-p 吗?
  • 不明白你可以使用约束数组来存储它们,如果你需要在循环之外访问它们?

标签: python python-3.x pandas constraints or-tools


【解决方案1】:

事实上,OR-Tools 并不要求每个约束都有一个唯一的名称。但无论如何,下面给了他们唯一的名字。如上所述,如果需要存储约束,可以按如下方式在数组中进行。这里我使用更常见的符号(A 是约束系数,B 是约束右侧,c 是目标系数)。但它会适应您的 Pandas 设置。

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

【讨论】:

    【解决方案2】:

    这样可以解决你的问题吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-17
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 2022-06-30
      相关资源
      最近更新 更多