【问题标题】:The Optimization of an Objective Function with Step Functions具有阶跃函数的目标函数优化
【发布时间】:2011-01-11 00:15:36
【问题描述】:

我曾在 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 工具箱中有什么东西可以让我在不进行平滑函数转换的情况下解决这个问题吗?

【问题讨论】:

标签: matlab mathematical-optimization


【解决方案1】:

这个问题可以完全使用混合整数规划求解器来解决。我在answer 中向您的 Math SE 帖子解释了详细信息;总而言之,您需要为涉及 Heaviside 阶跃函数的目标函数中的每一项引入一个二元变量和一个线性不等式。

【讨论】:

    【解决方案2】:

    在 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);
    

    将此函数另存为 objFun.m 在您的 Matlab 路径中。然后定义xdataydata(或从文件中加载),对loc(k×1 数组)进行初始猜测,并为线性等式约束对数组Aeq 进行初始猜测,使得@987654332 @(如果你有 3 个步骤,Aeq[1 1 1]),然后写

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

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

    【讨论】:

      【解决方案3】:

      沿 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 工具箱。

      【讨论】:

        猜你喜欢
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-03
        • 1970-01-01
        • 1970-01-01
        • 2012-10-16
        相关资源
        最近更新 更多