Python:如何使用lambda函数为fmin_cobyla优化创建多个约束

2 投票
2 回答
1174 浏览
提问于 2025-04-16 20:35

我有一个包含几百个数字的向量(比如这样:Xo = [x1, y1, x2, y2,..., xN, yN]),其中N是一个任意的数字。我需要把这个向量传递给scipy的fmin_cobyla优化器,并且对每个条目有一些简单的约束条件:

1. 所有的x(也就是x1, x2, ..., xN)都必须大于-1。

我尝试使用lambda函数来指定这些约束,像这样:

b0 = lambda Xo: 1 - Xo[n]
b1 = lambda Xo: Xo[n] + 1

但是我完全不确定怎么传入正确的索引n。我希望所有的偶数n都遵循b0和b1的约束,而所有的奇数n则遵循b2和b3的约束。

b2 = lambda Xo: 2 - Xo[n]
b3 = lambda Xo: Xo[n] + 2

我可能需要在fmin_cobyla中使用consargs。任何帮助都将非常感谢。

2 个回答

1

试试这个

even = lambda x: (x < 1 and x > -1)
odd = lambda x: (x < 2 and x > -2)
constraint = lambda index: (index % 2) and odd or even
filtered = [x for index, x in enumerate(Xo) if constraint(index)(x)]

老实说,我不知道fmin_cobyla是什么,但这是在看了David的评论后又一次尝试

even = lambda n: ((lambda x: 1 - x[n]), (lambda x: x[n] + 1))
odd = lambda n: ((lambda x: 2 - x[n]), (lambda x: 2 - x[n]))
constraint = lambda n: (n % 2) and odd(n) or even(n)
constraint_list = sum([constraint(i) for i in range(2 * N)], ())
1

约束条件需要是连续的吗?如果不需要,这里有一个简单的方法可以用一个函数来实现。如果约束条件满足,它会返回1;如果不满足,则返回-1:

def checkall(xs):
    for j, x in enumerate(xs):
        if abs(x) > (2 if j % 2 else 1):
            return -1
    return 1
cons = (checkall,)

如果你需要连续的约束条件,有很多方法可以做到。这是一个使用2N个线性函数的方法,其中N个用于正约束,N个用于负约束。

def checkpos(j):
    if j % 2:
        return lambda xs: 2 - xs[j]
    else:
        return lambda xs: 1 - xs[j]
def checkneg(j):
    if j % 2:
        return lambda xs: 2 + xs[j]
    else:
        return lambda xs: 1 + xs[j]

cons = [checkpos(j) for j in range(N)] + [checkneg(j) for j in range(N)]

撰写回答