使用 Mosek 在 Matlab 中并行优化
Optimizing in Parallel in Matlab with Mosek
我正在尝试通过调用 MOSEK 来求解 Matlab 中的圆锥体程序,同时改变其中一个约束的界限。
我想并行执行此操作以利用我拥有的所有内核。这是一个修改过的例子来说明我的观点。
testBounds=[0.1, 0.15, 0.2, 0.25, 0.3];
clear prob;
[r, res] = mosekopt('symbcon');
prob.c = [0 0 0 1 1 1];
% Specify the non-conic part of the problem.
prob.a = sparse([1 1 2 0 0 0]);
prob.buc = 1;
prob.blx = [0 0 0 -inf -inf -inf];
prob.bux = inf*ones(6,1);
% Specify the cones.
prob.cones.type = [res.symbcon.MSK_CT_QUAD, res.symbcon.MSK_CT_RQUAD];
prob.cones.sub = [4, 1, 2, 5, 6, 3];
prob.cones.subptr = [1, 4];
for i=1:5
% Specify the changing bound
prob.blc = testBounds(i);
% Optimize the problem.
[r,res]=mosekopt('minimize',prob);
% Display the primal solution.
res.sol.itr.xx'
end
我尝试使用 parfor 来执行此操作,但这是不允许的。不幸的是,MOSEK 文档没有详细介绍并行化。如何并行执行以上操作?
N=5;
r = cell(1,N);
res = cell(1,N);
for ii=1:N
% Specify the changing bound
prob2=prob;
prob2.blc = testBounds(ii);
% Optimize the problem.
[r{ii},res{ii}]=mosekopt('minimize',prob2);
% Display the primal solution.
res{ii}.sol.itr.xx' %'// better not display at all during calculation
end
parfor
不允许在其范围内创建变量。因此我选择预分配 r
和 res
作为单元格,它们可以充当输出存储。请参阅
中的 prob
/prob2
问题
您的代码的问题在于您使用了变量 prob
。虽然在算法级别上它是独立的,因为循环的每次迭代都使用它自己的 blc 设置而不使用任何以前的数据,但 parfor 不支持这种用法。最简单的解决方案是不修改变量 prob
而是在每次迭代中复制它,使 prob
成为一个广播变量而 prob2
成为一个局部变量:
parfor ii=1:5
% Specify the changing bound
%copy broadcast variable prob to a temporary variable prob2
%this way the iteration has writing capabilities
prob2=prob
prob2.blc = testBounds(ii);
% Optimize the problem.
[r,res]=mosekopt('minimize',prob2);
% Display the primal solution.
res.sol.itr.xx'
end
您的代码的另一个问题是您返回数据的方式。 parfor 在处理数据时没有顺序,因此仅将其显示到控制台不会给您任何有用的结果。它也很慢。我不知道您到底需要什么以及数据类型是什么,因此我没有触及那部分代码。我回答中的代码进行了计算,但没有返回任何结果,因为 res 和 r 都是临时变量。
我正在尝试通过调用 MOSEK 来求解 Matlab 中的圆锥体程序,同时改变其中一个约束的界限。
我想并行执行此操作以利用我拥有的所有内核。这是一个修改过的例子来说明我的观点。
testBounds=[0.1, 0.15, 0.2, 0.25, 0.3];
clear prob;
[r, res] = mosekopt('symbcon');
prob.c = [0 0 0 1 1 1];
% Specify the non-conic part of the problem.
prob.a = sparse([1 1 2 0 0 0]);
prob.buc = 1;
prob.blx = [0 0 0 -inf -inf -inf];
prob.bux = inf*ones(6,1);
% Specify the cones.
prob.cones.type = [res.symbcon.MSK_CT_QUAD, res.symbcon.MSK_CT_RQUAD];
prob.cones.sub = [4, 1, 2, 5, 6, 3];
prob.cones.subptr = [1, 4];
for i=1:5
% Specify the changing bound
prob.blc = testBounds(i);
% Optimize the problem.
[r,res]=mosekopt('minimize',prob);
% Display the primal solution.
res.sol.itr.xx'
end
我尝试使用 parfor 来执行此操作,但这是不允许的。不幸的是,MOSEK 文档没有详细介绍并行化。如何并行执行以上操作?
N=5;
r = cell(1,N);
res = cell(1,N);
for ii=1:N
% Specify the changing bound
prob2=prob;
prob2.blc = testBounds(ii);
% Optimize the problem.
[r{ii},res{ii}]=mosekopt('minimize',prob2);
% Display the primal solution.
res{ii}.sol.itr.xx' %'// better not display at all during calculation
end
parfor
不允许在其范围内创建变量。因此我选择预分配 r
和 res
作为单元格,它们可以充当输出存储。请参阅
prob
/prob2
问题
您的代码的问题在于您使用了变量 prob
。虽然在算法级别上它是独立的,因为循环的每次迭代都使用它自己的 blc 设置而不使用任何以前的数据,但 parfor 不支持这种用法。最简单的解决方案是不修改变量 prob
而是在每次迭代中复制它,使 prob
成为一个广播变量而 prob2
成为一个局部变量:
parfor ii=1:5
% Specify the changing bound
%copy broadcast variable prob to a temporary variable prob2
%this way the iteration has writing capabilities
prob2=prob
prob2.blc = testBounds(ii);
% Optimize the problem.
[r,res]=mosekopt('minimize',prob2);
% Display the primal solution.
res.sol.itr.xx'
end
您的代码的另一个问题是您返回数据的方式。 parfor 在处理数据时没有顺序,因此仅将其显示到控制台不会给您任何有用的结果。它也很慢。我不知道您到底需要什么以及数据类型是什么,因此我没有触及那部分代码。我回答中的代码进行了计算,但没有返回任何结果,因为 res 和 r 都是临时变量。