pythonic/idiomatic 在 or-tools CP-Solver 上声明线性约束的方法
pythonic/idiomatic way of declaring linear constraints on or-tools CP-Solver
这就是我在 CP-Solver (OR-Tools) 上创建线性约束的方式:
constraint3 = [ None for n in range(N) ]
for n in range(0,N):
eq = "T3_n[%d] >= T2_n[%d]"%(n,n)
constraint3[n] = model.Add(eval(eq))
其中 T3_n
和 T2_n
是根据系统输入创建的变量列表。
它有效,但我有一种强烈的感觉,这不是我应该做的。 :-)
有没有更idiomatic/better的方法呢?
提前致谢!
编辑:
表达式本身如果内置于 运行 时间的另一个示例:
for i in range(0,I):
for n in range(0,N):
eq = ""
for m in range(0,N):
if n!=m:
eq = eq + "ORD_i_n_m[%d][%d][%d] + "%(i,n,m)
eq = eq + " OURD_i_n[%d][%d] == LRD_i_n[%d][%d]"%(i,n,i,n)
constraint12[i][n] = model.Add(eval(eq))
编辑 2:
使用 eval 的要点是表达式本身取决于输入和一些逻辑。它仅在执行时已知。所以我将它创建为 String 并对其进行 eval() 。
这是(某种程度上)第二个例子的情况。在其他 frameworks/languages 中,可以在约束中设置每个变量的乘数。例如,对于其他求解器,我可以这样写:
for n in range(0,N):
constraint3[n] = solver.Constraint(0,infinity)
constraint3[n].SetCoefficient(T3_n[n],1)
constraint3[n].SetCoefficient(T2_n[n],-1)
(当然这是一个简单的例子,也有使用毛茸茸的逻辑来定义系数的情况)
我没有在 cp-solver 中找到这样做的方法。
编辑 3:
另一个例子来说明为什么我一直在使用 eval...
for i in range(0,I):
for n in range(0,N):
for m in range(0,N):
constraint14[i][n][m] = solver.Constraint(-M,infinity)
constraint14[i][n][m].SetCoefficient(TRD_i_n[i][m],1)
if customer[n]!=customer[m]:
constraint14[i][n][m].SetCoefficient(limit[customer[n]],-1)
constraint14[i][n][m].SetCoefficient(ORD_i_n_m[i][n][m],-M)
其中 limit[] 是变量数组
在这种情况下,无法使用 model.Add() 预先编写约束方程,因为变量取决于根据输入数据选择的客户。我错了吗?请指教
使用list.append
:
constraint3 = []
for n in range(0,N):
constraint3.append(model.Add(T3_n[n] >= T2_n[n]))
我不知道 model.Add
的 return 值是多少,但我假设它默认为 None
如果那是你的意图
当然,关于list comprehensions:
是对的
constraint3 = [
model.Add(T3_n[n] >= T2_n[n])
for n in range(N)
]
这就是我在 CP-Solver (OR-Tools) 上创建线性约束的方式:
constraint3 = [ None for n in range(N) ]
for n in range(0,N):
eq = "T3_n[%d] >= T2_n[%d]"%(n,n)
constraint3[n] = model.Add(eval(eq))
其中 T3_n
和 T2_n
是根据系统输入创建的变量列表。
它有效,但我有一种强烈的感觉,这不是我应该做的。 :-)
有没有更idiomatic/better的方法呢?
提前致谢!
编辑: 表达式本身如果内置于 运行 时间的另一个示例:
for i in range(0,I):
for n in range(0,N):
eq = ""
for m in range(0,N):
if n!=m:
eq = eq + "ORD_i_n_m[%d][%d][%d] + "%(i,n,m)
eq = eq + " OURD_i_n[%d][%d] == LRD_i_n[%d][%d]"%(i,n,i,n)
constraint12[i][n] = model.Add(eval(eq))
编辑 2:
使用 eval 的要点是表达式本身取决于输入和一些逻辑。它仅在执行时已知。所以我将它创建为 String 并对其进行 eval() 。
这是(某种程度上)第二个例子的情况。在其他 frameworks/languages 中,可以在约束中设置每个变量的乘数。例如,对于其他求解器,我可以这样写:
for n in range(0,N):
constraint3[n] = solver.Constraint(0,infinity)
constraint3[n].SetCoefficient(T3_n[n],1)
constraint3[n].SetCoefficient(T2_n[n],-1)
(当然这是一个简单的例子,也有使用毛茸茸的逻辑来定义系数的情况)
我没有在 cp-solver 中找到这样做的方法。
编辑 3: 另一个例子来说明为什么我一直在使用 eval...
for i in range(0,I):
for n in range(0,N):
for m in range(0,N):
constraint14[i][n][m] = solver.Constraint(-M,infinity)
constraint14[i][n][m].SetCoefficient(TRD_i_n[i][m],1)
if customer[n]!=customer[m]:
constraint14[i][n][m].SetCoefficient(limit[customer[n]],-1)
constraint14[i][n][m].SetCoefficient(ORD_i_n_m[i][n][m],-M)
其中 limit[] 是变量数组
在这种情况下,无法使用 model.Add() 预先编写约束方程,因为变量取决于根据输入数据选择的客户。我错了吗?请指教
使用list.append
:
constraint3 = []
for n in range(0,N):
constraint3.append(model.Add(T3_n[n] >= T2_n[n]))
我不知道 model.Add
的 return 值是多少,但我假设它默认为 None
如果那是你的意图
当然,关于list comprehensions:
是对的constraint3 = [
model.Add(T3_n[n] >= T2_n[n])
for n in range(N)
]