Google 或来自 DataFrame 的工具约束
Google OR Tools constraints from DataFrame
我想构建一个 Google OR 工具模型以将 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 |
+---+---+---+
table可以转化为以下约束
# 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
、...)。
这样可以解决您的问题吗?
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])
事实上,OR-Tools 并不要求每个约束都具有唯一的名称。但无论如何,以下内容都给了他们独特的名字。如上所述,如果需要存储约束条件,可以按如下方式在数组中进行。这里我使用了更常见的符号(A 是约束系数,B 是约束 right-hand 边,c 是 objective 系数)。但它会适应您的 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()
我想构建一个 Google OR 工具模型以将 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 |
+---+---+---+
table可以转化为以下约束
# 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
、...)。
这样可以解决您的问题吗?
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])
事实上,OR-Tools 并不要求每个约束都具有唯一的名称。但无论如何,以下内容都给了他们独特的名字。如上所述,如果需要存储约束条件,可以按如下方式在数组中进行。这里我使用了更常见的符号(A 是约束系数,B 是约束 right-hand 边,c 是 objective 系数)。但它会适应您的 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()