Scipy最小化不服从约束不最小化objective函数

Scipy minimize not obeying the constraint and not minimizing the objective function

我有以下代码:

import numpy as np
from scipy.optimize import minimize

def U(contributions, sizes, l):
    return sizes*l*np.log(np.sum(contributions)) - contributions**2/sizes

def min_Ui(vars, sizes,l, number):
    return -U(vars, sizes, l)[number]


sizes = np.array([1,1/4])
l = 4
number = 1       # 1 refers to nation 2

    
m_N = sizes**2 * np.sqrt(l/(2*np.sum(sizes**2)))
U_N = U(m_N, sizes, l)
    
constr = []
for i in range(len(sizes)):
    if i != number:
        constr.append({'type':'eq', 'fun': lambda x, sizes,l, U_N: U(x,sizes,l)[i] - U_N[i], 'args': (sizes,l, U_N)})
            
    
res = minimize(min_Ui, m_N, method='SLSQP', constraints=constr, args=(sizes,l, number))
    
print(res)

在此代码中,多个国家/地区为 public 物品做出了贡献。他们每个人都有一个效用函数(由 U 计算),该函数正向取决于所做的总贡献,负向地取决于他们自己的贡献。每个国家都有其特定的大小(以大小描述),参数 l 对所有国家都是通用的。我现在想最大化其中一个国家(用 'number' 表示)的效用,同时使其他国家的效用保持在其初始值不变(U_N)。这意味着一个国家可以选择所有其他国家的贡献来最大化自己的效用,前提是他们不比起点差。

在显示的代码中,我为大小为 1 和 1/4 的 2 个国家执行此操作,参数 l 取值 4,国家 2 最大化其效用(我使用这些值是因为我知道这种情况的解决方案:捐款应为 1.70297443 和 0.17713154)。然而,该代码应该适用于 n 个国家和任何正参数值。

但是,最小化函数没有给出正确的结果。结果中国家 2 的效用通常是其初始效用,而国家 1 的效用根据我给出的初始猜测而变化。然而在这个问题中,约束表示国家 1 的效用应该是它的初始值,而国家 2 的效用最大化。

有人可以解释我做错了什么或者为什么它不起作用吗?

在循环内通过 lambda 表达式定义约束时,您需要捕获循环变量 i,有关详细信息,请参阅 here。定义约束如下

constr = []
for i in range(len(sizes)):
    if i != number:
        constr.append({'type':'eq', 'fun': lambda x, sizes,l, U_N, i=i: U(x,sizes,l)[i] - U_N[i], 'args': (sizes,l, U_N)})

产生您期望的解决方案。