【发布时间】: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