我有一组约束,我必须在scipy的优化中以特定的方式输入。格式如下所示
cons = ({'type' : 'eq', 'fun': lambda x: sum(x) - 1.},
{'type' : 'ineq', 'fun': lambda x: bounds(x)},
{'type' : 'ineq', 'fun': lambda x: -1*bounds(x) + 0.1})
bounds是计算点积的函数。在不进行太多细节的情况下,我必须在运行时手动创建字典的元组。我现在的问题是,如果它包含关键字,例如“lambda”,我如何连接/加入键和值?
我知道如何通过字符串调用函数
def install():
print "In install"
methods = {'install': install}
method_name = 'install'
if method_name in methods:
methods[method_name]()
但是我无法理解我如何能够使用这种方法。 感谢
答案 0 :(得分:2)
您需要编写一个返回函数的函数。例如:
def constraint_maker(delta):
def _(x):
return -1*bounds(x) + delta
return _
cons = ({'type' : 'ineq', 'fun': constraint_maker(0.1)},
{'type' : 'ineq', 'fun': constraint_maker(0.2)},
{'type' : 'ineq', 'fun': constraint_maker(0.3)})
名为_
的函数(名称是任意选择的,它可以是任何东西)是闭包; delta
在其正文中的值由您传递给constraint_maker
的参数确定。
请注意,您无法编写类似
的内容cons = []
for d in [0.1, 0.2, 0.3]:
cons += {'type': 'ineq', 'fun': lambda x: -1*bounds(x) + d}
因为你的lambda
表达式没有创建闭包;名称d
只是一个自由变量,其值在最终被调用时被查找,并且在评估d
表达式时与lambda
的值无关。在另一个函数中定义函数时会创建闭包。您可以将其写为
cons = []
for d in [0.1, 0.2, 0.3]:
cons += {'type': 'ineq', 'fun': lambda x, d=d: -1*bounds(x) + d}
因为d
正文中的lambda
现在不是自由变量;它是一个局部变量(特别是一个参数),其默认值取自循环中同名变量。这有点丑陋,甚至除了两个具有相同名称(但是不同的范围)的变量的混淆之外,因为现在你的函数需要2个参数,尽管第二个参数永远不会被明确使用。
答案 1 :(得分:0)
如果我正确理解了您的问题,您希望将两个功能组合成一个,例如:如果你这样做:
{'type': 'eq', 'fun': lambda x: x + 1} + {'type': 'ineq', 'fun': lambda x: x + 2}
你想得到:
{'type': 'eqineq', 'fun': lambda x: x + 1 + x + 2}
如果是这种情况,请尝试以下方法:
class FunctionSum(object):
def __init__(self, f1, f2):
self.f1 = f1
self.f2 = f2
def __call__(self, x):
return self.f1(x) + self.f2(x)
class ConstDict(dict):
def __add__(self, other):
_ = {}
for k, v in self.items():
if hasattr(v, '__call__'):
_[k] = FunctionSum(self[k], other[k])
else:
_[k] = self[k] + other[k]
return _
const = [ConstDict({'type': 'eq', 'fun': lambda x: x + 1}),
ConstDict({'type': 'ineq', 'fun': lambda x: x + 2})]
print (const[0] + const[1])['fun'](1)
答案 2 :(得分:-1)
使用您当前的结构,您可以使用以下代码:
for c in cons:
if c['type'] == type:
fun = c['fun']
fun(x)
其中type
和x
是您的参数。