【问题标题】:Can the genetic-algorithm in Matlab pass a second return value from the fitness-function to the constraints?Matlab 中的遗传算法可以将适应度函数的第二个返回值传递给约束吗?
【发布时间】:2014-04-28 19:52:47
【问题描述】:

我在 Matlab 中模拟批量蒸发器。遗传算法改变了几个起始变量 x(例如尺寸、工作流体的最大质量、使用的蒸发器的总数......),目标是最大化效率。所以我的函数evaporator(x) 返回了被算法最小化的负效率。
除了效率之外,还计算了其他几个值。一是模拟周期的持续时间(不是计算本身的运行时间!)。作为一个约束,整个蒸发周期的持续时间应根据蒸发器的数量而定,不能太短(例如,如果使用三个蒸发器,整个蒸发周期至少需要 3*5s = 15s)。
我知道我可以轻松使用 ga (nonlcon) 的非线性约束选项。在这种情况下,我只需要再次从evaporator(x) 进行相同的计算,但这次返回计算的持续时间。问题是,每次运行我必须调用一个外部 DLL 数千次,并且计算变得非常慢。因此,我真的想避免将所有计算运行两次。
evaporator(x) 是否有可能同时返回负效率和持续时间?然后 ga 应该最小化负面效率并评估有关约束的持续时间。我想过将evaporator(x) 嵌套在一个匿名函数中,但我认为我的函数仍然需要调用两次?

我在效率和持续时间的多目标优化方面有很好的经验,但不幸的是gamultiobj 算法无法处理整数变量。

目前我在evaporator(x) 内使用短期惩罚函数,但我认为 ga 算法的约束处理会比这更好。

编辑: 所以它变得有点复杂,但最终它正在工作:

function [ returnValue ] = switchHXoutput( requestedCase, inputs )
%SwitchHXoutput returns fitness value or duration depending on requested
%case

persistent fitnessValue duration oldInputs;

if isempty(oldInputs)
    oldInputs = {}; %initialize oldInputs as cell
end


[isAllreadyCalculated, iOldInput] =...
ismember(cell2mat(inputs), cell2mat([oldInputs{:}]), 'rows'); 

if isempty(oldInputs) || ~isAllreadyCalculated
    [fitnessValue(end+1), duration(end+1)] = lengthyCalculation(inputs); %add current results to persistent array
    oldInputs(end+1) = {inputs}; %add current inputs to persistent array
    returnValue = [fitnessValue(end), duration(end)];
else
    returnValue = [fitnessValue(iOldInput), duration(iOldInput)]; % return old values
end

if strcmp(requestedCase, 'FitnessValue')
    returnValue = returnValue(1);
elseif strcmp(requestedCase, 'duration')
    returnValue = returnValue(2);
else
    error('MyApp:SelectOutput','Requested case not supported')
end

end %function

我知道不断增长的单元阵列并不是很快。但是由于我的lengthyCalculation 每次通话大约需要 2 分钟,我仍然节省了大量时间。此外,每一代中最好的个体在下一代中再次被使用。因此,在这种情况下,可以使用保存的值而不是再次重新计算它们。该代码也适用于并行计算。通常,适应度值和持续时间由同一个工作人员计算。只有下一代的结果才能在另一个工人身上。

【问题讨论】:

    标签: matlab mathematical-optimization genetic-algorithm


    【解决方案1】:

    一种选择是包含一些持久状态,它记录上次运行时计算的效率和持续时间(这是memoization),并根据函数输入决定返回哪个。

    例如,

    function return_value = evaporator(method, value, inputs)
    
      persistent efficiency duration;
    
      if strcmp(method, 'recalculate')
          % Some lengthy calculation goes here
          efficiency = inputs + 1;
          duration   = inputs + 10;
          pause(5);
      end
    
      switch value
        case 'efficiency'
          return_value = efficiency;
        case 'duration'
          return_value = duration;
      end
    
    end
    

    结果是

    >> evaporator('recalculate', 'efficiency', 10)
    11
    >> evaporator('memoized', 'duration')
    20
    >> evaporator('recalculate', 'efficiency', 20)
    21
    >> evaporator('memoized', 'duration')
    30
    

    【讨论】:

    • 我可能对术语持续时间不清楚。约束不应该是计算本身的持续时间,而是我计算的结果值之一(这是一个持续时间,但也可能是温度或其他东西)。但我认为你的建议仍然很有趣。我会尝试调整它以适应我的问题!
    • 好的,基本的想法很完美。只有 ga 算法首先调用种群中所有成员的适应度函数(效率),然后才调用所有成员的约束函数(持续时间)。所以只保存最后一个结果是行不通的。我将尝试将所有结果保存在持久(单元格)数组中,然后在稍后调用约束函数时访问相应的存储结果。我只担心如果对效率和持续时间的要求不在同一个工作人员中发生,那么并行计算将无法很好地工作......
    • 是的,这可能不会很好地并行化。
    猜你喜欢
    • 2020-05-12
    • 2014-09-11
    • 2023-02-20
    • 2011-09-17
    • 2011-10-07
    • 1970-01-01
    • 2011-04-07
    • 2017-09-26
    • 2011-12-21
    相关资源
    最近更新 更多