2

我有一个非负约束的优化问题(必须用下面的减号翻译)。约束由下式给出:

function
[neg_constraint,zero_con]=metric_con_130830(theta,v_b,spec,selector,time_all,lambda_all)
theta=exp(theta);
g_sum=selector*(lambda_all*theta.*time_all);
%minus v_b-g_sum because I want v_b-g_sum to be positive
neg_constraint=-(v_b-g_sum);
zero_con=[];

我不介意有时会违反约束。特别是,我不介意向量 (v_b-g_sum) 中是否有 20%(或其他数量)的条目为负数。任何想法如何有效地在我的代码中得到它?

一个快速的解决方法是这样做:

zero_con=sum((v_b-g_sum)<0)./length(g_sum)>.20

但我想知道优化器将如何找到一个不太平滑的指标函数的最小值。

或者,我可以随机抽取一个样本(其大小为 80%)并以这种方式检查约束:

zero_con=v_b-g_sum;
zero_con=zero_con(randsample(length(zero_con),round(.8*(length(zero_con)))));
4

1 回答 1

1

首先,给约束函数添加一些随机性是一个糟糕的计划——优化器没有机会......它会认为它找到了接近解决方案的东西,下次它尝试接近它的东西时,解决方案将完全改变.

你是对的,如果你有一个返回满足约束比例的函数,它会损害优化器的收敛性,因为它不会是平滑的——它是一个离散函数,会逐步跳跃。此外,您有效地向优化器隐藏了有用的信息,因为它不知道单个约束如何受解决方案参数的影响。

我建议您添加一个额外的未知数,比如说conval,而不是测试约束是否 <0,而是测试它们是否小于conval。这些中的每一个都将作为单独的约束返回,使优化器完全了解约束如何通过输入进行更改。

然后添加一个额外的约束:

if (number of constraints broken < 20%)
    return 0
else
    return (smallest constraint violation)^2

所以假设你有 100 个约束,其中 20 个被违反,我们没问题。然后随着第 21 次滑入被违反,您开始返回第 21 次违反约束的数量的平方。由于它是一个正方形,当约束开始起作用时,它将从零开始平滑增加。随着输入的变化,它并不总是最小的约束 - 它可以切换到另一个,但至少在两者之间切换时不会发生跳跃(只是导数的跳跃)。

于 2013-09-21T17:01:33.290 回答