主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

使用 parfeval 在后台计算函数

此示例展示了如何通过在后台使用 parfeval 来评估函数来解决一个简单的优化问题。当您使用 parfeval 在后台评估函数时,您会创建 Future 对象。您可以收集可用的结果,并在结果足够好时尽早摆脱优化循环。

为了稍后重现相同的计算,请使用默认值为随机生成器提供种子。

rng("default")

目标函数 objFun 以行向量 x 作为输入,并返回表示函数输出的标量值。定义优化循环的目标函数和迭代次数。随机生成 x 值的候选值来评估目标函数。初始化最小值和索引变量。

objFun = @(x) x(1)^2 + x(2)^2;
numIterations = 500;
xCandidates = rand(numIterations,2);
minFval = inf;
minIndex = inf;

使用 parfeval 来评估背景中每组 x 候选者的目标函数。

当您使用 parfeval 在后台运行计算时,该函数会为每个计算创建一个 Future 对象并将其添加到池队列中。Future 一直留在队列中,直到工作单元闲置。当一个工作单元变得空闲时,如果队列不空,它就开始计算 future。当一个工作单元完成一个 future 时,这个 future 就会从队列中移除,并且这个工作单元会变为空闲状态。

为了提高效率,预先分配一个 Future 对象数组。

f(1:numIterations) = parallel.FevalFuture;
for i = 1:numIterations
    f(i) = parfeval(objFun,1,xCandidates(i,:));
end
Starting parallel pool (parpool) using the 'Processes' profile ...
08-Jul-2024 15:36:55: Job Queued. Waiting for parallel pool job with ID 26 to start ...
Connected to parallel pool with 6 workers.

当一个未来事件完成时,其 State 属性变为 'finished',其 Read 属性变为 false。您可以使用 fetchNext 函数在异步任务完成后获取其结果。在 fetchNext 从数组 f 中的下一个未读 future 检索到输出之后,MATLAB 将该 future 的 Read 属性设置为 true

运行一个与之前迭代次数相同的 for 循环。在每次迭代中,使用 fetchNext 来检索下一个完成的 future 索引和值。接下来,将新值与现有的值进行比较,如果发现较小的值,则更新值及其索引。

如果发现小于或等于 0.01 的值,则显示解决方案并提前退出循环。

for idx = 1:numIterations
    [completedIndex, fval] = fetchNext(f);
    if fval < minFval
        minFval = fval;
        minIndex = completedIndex;
    end
    if minFval <= 0.01
        fprintf("Best solution found: x = [%f,%f], fval = %f\n", ...
            xCandidates(minIndex,1),xCandidates(minIndex,2),minFval);
        break;
    end
end
Best solution found: x = [0.031833,0.093820], fval = 0.009816

取消所有剩余的 future。

cancel(f);
clear f;

另请参阅

|

主题