我想重申这个问题,以确保我完全理解您的问题。从这个问题中我不清楚这是否正是你的
记住,但这里是......
问题陈述
对于所有i 和sum(x) == 1,最大化min_i f(x,i) 超过x 以0 <= x(i) <= 1。
f 定义为
f(x,1) = k(1) * x(1)
f(x,2) = k(2) * x(2)
...
f(x,20) = k(20) * x(20)
和k 一样
k(i) = N(i) / M(i)
封闭式解决方案
首先,请注意这是一个凸优化问题,这意味着任何局部最大值也是全局最大值。这意味着您绝对不会陷入局部最大值。假设所有i 都是k(i) > 0,您实际上可以手动解决这个问题。我不会在这里进行数学运算,但直观地我们看到这些函数是独立的。考虑到约束,这导致了最优解必须满足k(1)*x(1) == k(2)*x(2) == ... == k(20)*x(20) 的结论。由于限制,这意味着最佳点是
x = (1./k) / sum(1./k)
fminimax解决方案
使用fminimax 的求解最好尽可能避免非线性约束,以便求解器能够正确优化。等式约束sum(x) == 1 可以写成A*x == 1,其中A 是全1 的行向量。
此外,x(i) <= 1 的上限由 x(i) >= 0 和 sum(x) == 1 隐含。显然,如果满足后两者,则自动满足上限。由于上限是多余的,我们可以省略它以加快速度。
也就是说,您发布的代码的主要问题是求解器提前终止。这似乎正在发生,因为默认公差都在 1e-6 的顺序上,但目标函数的值在 1e-7 的顺序上。这意味着求解器采取的任何步骤最终都会小于容差,因此一旦满足约束条件,求解器就会立即停止。
您可以通过观察argmax_x(min_i(f(x,i)) == argmax_x(min_i(c*f(x,i))) 来避免这种情况,其中c 是某个正常数。例如,如果我们按1e7 缩放目标函数,那么我们开始在更合理的范围内运行,但最佳点x 保持不变。
你已经否定了将极小值转换为极大值的目标,所以我不会再多说什么了。
这是修正后的 MATLAB 代码
M=[9.3 5.3 4.4 4.4 1.7 4.8 4.8 11 1.7 5.2 8.1 6.2 2.8 3.2 4 3.9 4.6 1 2.5 7.6]*10^7;
N=[2 2 2 2 1 2 2 2 1 2 1 1 2/3 0.5 2 2 2 0.4 0.5 2];
x0=zeros(20,1);
k = (N./M).';
scale = 1/min(abs(k)); % scale to put everything in a reasonable range
f = @(x) (-1*(scale*k).*x).'; % -1 to convert minmax to maxmin
lb=zeros(20,1); % x >= 0
Aeq = ones(1,20); beq = 1; % sum(x) == 1 constraint
[x,fval]=fminimax(f,x0,[],[],Aeq,beq,lb);
g = min(k.*x)
或者,您应该能够调整求解器选项以避免提前终止。我试图找到正确的设置,但没有成功。