具有阶函数的目标函数的优化

时间:2011-01-10 07:12:55

标签: matlab mathematical-optimization

我在Math SE问过this question,但回复并不是很令人满意。所以我再次问到这里:

我有线性不等式和等式约束的优化问题:

A*x<=b 
Aeq*x=beq

问题在于目标函数由一系列Heaviside阶梯函数的总和组成,

这是目标函数的伪代码:

function f(k, c, x)
  ffunction =0;
  for i=0;i<k.row.length;i++
     smallF=0
     for j=0; j<k.column.length; j++
      smallF+= k.row[i]*k.column[j]*x[j]+c[j]
     end 
     ffunction += u(smallF)
  end
 f=ffunction 
end


function u(x)
  if(x>0)
   return 1
  else
   return 0
  end
end

我得到的建议是将阶梯函数近似为平滑函数,并为此目的使用非线性优化。但是MATLAB工具箱中有什么东西可以让我在不进行平滑函数转换的情况下解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

使用混合整数编程求解器可以完全解决此问题。我将answer中的详细信息解释到您的Math SE帖子中;总结一下,你需要为涉及Heaviside阶梯函数的目标函数中的每个项引入一个二元变量和一个线性不等式。

答案 1 :(得分:1)

在Matlab中,您可以进行数值优化。这意味着您不必担心目标函数的分析形式。相反,您需要编写一个目标函数,使用优化参数为数据的每个值x创建y - 您可以将其与输入数据进行比较的值。

使用线性和非线性约束,您可以使用FMINCON来解决问题。

我不完全确定我理解你想要优化的内容(抱歉,它有点早),但为了举个例子,让我假设你有一个x值为xdata的向量和一个y值ydata的矢量,你想要适合“阶梯函数”。你知道有多少步骤,但你不知道它们的位置。此外,您知道步长位置的总和必须为5(线性等式约束)。

首先编写目标函数,使其输出尽可能接近0。这可以是残差的平方和(即,实际y值和估计的y值之间的差)。为方便起见,我不会通过线性方程来定义步长位置,但我会直接设置它们。

function out = objFun(loc,xdata,ydata)
%#OBJFUN calculates the squared sum of residuals for a stair-step approximation to ydata
%# The stair-step locations are defined in the vector loc

%# create the stairs. Make sure xdata is n-by-1, and loc is 1-by-k
%# bsxfun creates an n-by-k array with 1's in column k wherever x>loc(k)
%# sum sums up the rows
yhat = sum(bsxfun(@gt,xdata(:),loc(:)'),2); %'# SO formatting

%# sum of squares of the residuals
out = sum((ydata(:)-yhat).^2);

将此功能保存为Matlab路径中的objFun.m。然后定义xdataydata(或从文件中加载),对loc(k-by-1数组)和数组Aeq进行初始猜测线性相等约束使Aeq*loc==beqAeq[1 1 1],如果你有3步),并写

locEst = fmincon(@(u)objFun(u,xdata,ydata),locInitialGuess,[],[],Aeq,5);

这将估计步骤的位置。您可以添加不等式约束而不是两个空括号,而5是因为我假设等式约束的计算结果为5。

答案 2 :(得分:0)

沿着X的任何一个维度的绝对最小化是一个简单的任务,可以在O(i)时间内找到。

1)选择一个Xj进行修改(其他所有修复)

2)创建一个长度为i的列表,其中包含沿Xj的每个方程的切换位置,映射到1或-1,具体取决于它是否随着接近+ inf而减小或增加。

3)按切换位置排序...在最小切换位置从0开始,加上或减去映射值。

4)在逐步浏览此列表时跟踪最小总和,将切换位置保持为最佳映射到分数。

5)在列表的末尾,您最佳的切换位置将成为Xj的新值。

从这里开始,您可以沿着X的每个维度进行共轭最小化,重复直到您停止改进结果。这至少会找到当地的最低限度。


或者,您可以使用不需要渐变的固定本地优化代码...例如Nelder Mead downhill simplex方法。该任务有Matlab libraries available


这两种方法都会给你带来局部最优。如果你真的需要一个更全面的解决方案,你可以查看Simulated Annealing或遗传算法解决方案,这可能会很好地解决这类问题。


最后,如果你有一大笔钱要花(不确定这是免费的),我会检查Matlab Global Optimization工具箱。