Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 生成一个';口述顺序';对于scipy.optimize.minimize_Python_Python 2.7_Scipy_Minimize - Fatal编程技术网

Python 生成一个';口述顺序';对于scipy.optimize.minimize

Python 生成一个';口述顺序';对于scipy.optimize.minimize,python,python-2.7,scipy,minimize,Python,Python 2.7,Scipy,Minimize,我正在使用scipy.optimize.minimizewithconstraints。文档(at)中的示例用于约束: cons=({'type':'ineq','fun':lambda x:x[0]-2*x[1]+2}, {'type':'ineq','fun':lambda x:-x[0]-2*x[1]+6}, {'type':'ineq','fun':lambda x:-x[0]+2*x[1]+2}) 我想做一些类似的事情,但是在循环中生成这个序列的元素,但是我遇到了麻烦 我尝试将cons

我正在使用scipy.optimize.minimizewithconstraints。文档(at)中的示例用于约束:

cons=({'type':'ineq','fun':lambda x:x[0]-2*x[1]+2},
{'type':'ineq','fun':lambda x:-x[0]-2*x[1]+6},
{'type':'ineq','fun':lambda x:-x[0]+2*x[1]+2})

我想做一些类似的事情,但是在循环中生成这个序列的元素,但是我遇到了麻烦

我尝试将cons视为元组,这是一个与上述形式相同的示例:

cons=(,)
对于范围(4)中的i:
cons+=({'type':'ineq','fun':lambda x:x[0]-2*x[1]+i})

但是我得到了
TypeError:+=:“dict”和“dict”不支持的操作数类型

我还尝试使用
str
eval

cons=(str({'type':'ineq','fun':lambda x:x[0]-2*x[1]}))
对于范围(3)中的i:
cons+=(str({'type':'ineq','fun':lambda x:x[0]-2*x[1]+i+1}))
cons=评估(cons)

但那也不管用,我得到的是

cons=eval(cons)
文件“”,第1行 {'fun':,'type':'eq'}{'fun':,'type':'eq'}{'fun':,'type':'eq'}{'fun':,'type':'eq'}{' ^ 语法错误:无效语法

帮点忙就好了

不要添加dict(括号在这里没有任何作用):

添加元组,在dict后添加逗号:

for i in range(4):
    cons += ({'type': 'ineq', 'fun': lambda x:  x[0] - 2 * x[1] + i},)
>>> cons
({'fun': <function <lambda> at 0xb746de2c>, 'type': 'ineq'}, {'fun': <function <lambda> at 0xb747656c>, 'type': 'ineq'}, {'fun': <function <lambda> at 0xb74765a4>, 'type': 'ineq'}, {'fun': <function <lambda> at 0xb74765dc>, 'type': 'ineq'})
范围(4)内的i的
:
cons+=({'type':'ineq','fun':lambda x:x[0]-2*x[1]+i},)
>>>缺点
({'fun':,'type':'ineq'},{'fun':,'type':'ineq'},{'fun':,'type':'ineq'},{'fun':,'type':'ineq'})
--

请注意,正如@Jivan在其回答中所指出的,您应该使用列表来完成这类工作。

一旦创建了元组,就不能修改其中元素的数量或顺序

您可以这样做:

cons = []
for i in range(4):
    cons.append({'type': 'ineq', 'fun': lambda x:  x[0] - 2 * x[1] + i})
这会给你一个字典列表。完成列表后,如果要将其更改为元组,可以执行以下操作:

cons = tuple(cons)
结果是:

>>> cons
({'fun': <function <lambda> at 0x106e2cb18>, 'type': 'ineq'},
    {'fun': <function <lambda> at 0x106e2cf50>, 'type': 'ineq'},
    {'fun': <function <lambda> at 0x106e335f0>, 'type': 'ineq'},
    {'fun': <function <lambda> at 0x106e33cf8>, 'type': 'ineq'})
>>缺点
({'fun':,'type':'ineq'},
{'fun':,'type':'ineq'},
{'fun':,'type':'ineq'},
{'fun':,'type':'ineq'})
--

注意,他自己说:

通常,列表用于循环;结构的元组。名单是 同种类的元组异构。可变长度的列表


因此,在您的情况下,您可能希望保留该列表,除非某个第三方模块需要一个元组。

这是一个较老的问题,但两个建议的解决方案似乎都是错误的。还是我遗漏了什么

def generate_constraints_wrong(n_params):
    cons = []
    for i in range(n_params):
        cons.append({'type': 'ineq', 'fun': lambda x:  x[i]})
    return tuple(cons)

def generate_constraints_wrong2(n_params):
    cons = tuple()
    for i in range(n_params):
        cons += ({'type': 'ineq', 'fun': lambda x:  x[i]},)
    return cons

def generate_constraints_right(n_params):
    # let's create a function generator that uses closure to pass i to the generated function
    def wrapper_fun(x, i):
        def fun(x):
            return x[i]
        return fun
    cons = []
    for i in range(n_params):
        f = wrapper_fun(x, i)
        cons.append({'type': 'ineq', 'fun': f})
    return tuple(cons)

# verify the generated functions
n_params = 3
x = [1,10, 100]
cons1 = generate_constraints_wrong(n_params)
cons2 = generate_constraints_wrong2(n_params)
cons3 = generate_constraints_right(n_params)
print(cons1[0]['fun'](x)) # this should be 1 but instead we end up modifying all of our lambda objects to have the last i
print(cons1[1]['fun'](x))
print(cons2[0]['fun'](x))
print(cons2[1]['fun'](x))
print(cons3[0]['fun'](x))
print(cons3[1]['fun'](x))
印刷品:

100
100
100
100
1
10
问题是每个lambda的闭包指向对象i,而不是指向我在特定循环迭代中拥有的对象的值。有关更多详细信息,请参阅:

对不起,我编辑了你的答案,而不是我的!错了,曼尼普:)当然可以拒绝这个编辑。嗯,那是一个很好的编辑,所以我接受了。不过我会改变它,以符合您的要求。“…您不能修改其中的元素数”-不使用cons+=(stuff,)修改元组cons中的元素数吗?@JGM272不,不。它创建一个新的元组并用新元组替换旧元组,就像您创建了
cons=(previous,)+(new,)
一样。无论如何,在你的情况下,这可能不是最好的(最具python风格的)方式。
100
100
100
100
1
10