优化不与 Scilab 中的 parallel_run 函数收敛
Optimization doesn't converge with parallel_run function in Scilab
我正在尝试对 Scilab 进行优化,我想使用 parallel_run 函数并行 运行 差分进化代码。
代码的原始版本包括一个 for 循环,用于我想要并行化的部分,它工作得很好。当我使用 parallel_run 函数和 运行 修改代码时,它在 Windows 机器上再次运行,但据我所知,此函数不适用于 Windows 并且它单核上只有 运行s。最后,我再次尝试在 Linux 机器上 运行 修改后的代码,没有出现任何错误,但是优化并没有收敛,并给了我更糟糕的最终结果。
在试图找出问题所在时,我意识到代码打印的部分内容在 Scilab 控制台上,另一部分在终端上。即使在终端中进行了一些计算,优化过程也无法从那里检索数据。
这是原始版本代码中的 for 循环:
//-----Select which vectors are allowed to enter the new population------------
for i=1:NP
tempval = fct(ui(:,i),y); // check cost of competitor
nfeval = nfeval + 1;
if (tempval <= val(i)) // if competitor is better than value in "cost array"
pop(:,i) = ui(:,i); // replace old vector with new one (for new iteration)
val(i) = tempval; // save value in "cost array"
//----we update optval only in case of success to save time-----------
if (tempval < optval) // if competitor better than the best one ever
optval = tempval; // new best value
optarg = ui(:,i); // new best parameter vector ever
end;
end;
end; //---end for imember=1:NP
这里是我用来替换循环的嵌套函数,并试图使其 运行 并行:
function gpar(i);
disp("called on "+string(i));
global nfeval
global val
global pop
global optval
global optarg
tempval = fct(ui(:,i),y); // check cost of competitor
nfeval = nfeval + i;
disp("tempval "+string(tempval));
disp("val(i) "+string(val(i)));
disp("optval "+string(optval));
disp("bef_pop(i) "+string(pop(:,i)));
if (tempval <= val(i)) // if competitor is better than value in "cost array"
pop(:,i) = ui(:,i); // replace old vector with new one (for new iteration)
val(i) = tempval; // save value in "cost array"
//----we update optval only in case of success to save time-----------
if (tempval < optval) // if competitor better than the best one ever
optval = tempval; // new best value
optarg = ui(:,i); // new best parameter vector ever
end;
end;
disp("aft_pop(i) "+string(pop(:,i)));
endfunction; //---end for imember=1:NP
parallel_run(1:NP, "gpar"); //calling function gpar in parallel
disp("popThisGen "+string(pop)); //display the population after changes
如果满足某些条件,则 pop 矩阵的第 i 列会发生变化。我在 if 语句前后打印第 i 列。 i 是从 1 到 40 运行s 的向量。我可以从 Scilab 控制台看到这些打印的前 10 个,从终端看到最后 30 个(我的机器有四个内核,我认为它与那)。然后我在 parallel 运行 完成它的工作后打印整个 pop 矩阵。从 pop 的最终版本中,我意识到只有我在 Scilab 控制台观察到的变化生效,并且 none 我在终端观察到的变化。
原始代码的完整版本在http://www1.icsi.berkeley.edu/~storn/code.html#scil
我认为这些损失是我得到糟糕结果的原因。有谁知道可能会发生什么?谢谢
回答有点仓促,不过应该通过结果变量导出结果。如 parallel_run docs 中所述:
Furthermore, no locking primitives are available in Scilab to handle
concurrent accesses to shared variables. For this reason, the
concurrent execution of Scilab macros cannot be safe in a shared
memory environment and each parallel execution must be done in a
separate memory space. As a result, one should not rely on side
effects such as modifying variables from outer scope : only the data
stored into the result variables will be copied back into the calling
environment.
还要检查所有并行计算是否完全独立。通过参数获取所有输入。
查看您的代码,声明为全局的所有内容将在所有进程之间共享。所以将它们全部放在参数列表中。您不应该假定单独计算的任何执行顺序。
the Scilab docs 中的示例实际上很好地解释了 return 值。比如下面这个例子。
function [r_min, r_med, r_max]=min_med_max(a, b, c)
r_min=min(a,b,c); r_med=median([a,b,c]); r_max=max(a,b,c);
endfunction
N=10;
A=rand(1:N);B=rand(1:N);C=rand(1:N);
[Min,Med,Max]=parallel_run(A,B,C,"min_med_max");
除了使用结果,SciLab 在定义结果方面非常严格,只有列向量等。
也结账 the Scilab Wiki about parallel computing。
希望对您有所帮助。
我正在尝试对 Scilab 进行优化,我想使用 parallel_run 函数并行 运行 差分进化代码。
代码的原始版本包括一个 for 循环,用于我想要并行化的部分,它工作得很好。当我使用 parallel_run 函数和 运行 修改代码时,它在 Windows 机器上再次运行,但据我所知,此函数不适用于 Windows 并且它单核上只有 运行s。最后,我再次尝试在 Linux 机器上 运行 修改后的代码,没有出现任何错误,但是优化并没有收敛,并给了我更糟糕的最终结果。
在试图找出问题所在时,我意识到代码打印的部分内容在 Scilab 控制台上,另一部分在终端上。即使在终端中进行了一些计算,优化过程也无法从那里检索数据。
这是原始版本代码中的 for 循环:
//-----Select which vectors are allowed to enter the new population------------
for i=1:NP
tempval = fct(ui(:,i),y); // check cost of competitor
nfeval = nfeval + 1;
if (tempval <= val(i)) // if competitor is better than value in "cost array"
pop(:,i) = ui(:,i); // replace old vector with new one (for new iteration)
val(i) = tempval; // save value in "cost array"
//----we update optval only in case of success to save time-----------
if (tempval < optval) // if competitor better than the best one ever
optval = tempval; // new best value
optarg = ui(:,i); // new best parameter vector ever
end;
end;
end; //---end for imember=1:NP
这里是我用来替换循环的嵌套函数,并试图使其 运行 并行:
function gpar(i);
disp("called on "+string(i));
global nfeval
global val
global pop
global optval
global optarg
tempval = fct(ui(:,i),y); // check cost of competitor
nfeval = nfeval + i;
disp("tempval "+string(tempval));
disp("val(i) "+string(val(i)));
disp("optval "+string(optval));
disp("bef_pop(i) "+string(pop(:,i)));
if (tempval <= val(i)) // if competitor is better than value in "cost array"
pop(:,i) = ui(:,i); // replace old vector with new one (for new iteration)
val(i) = tempval; // save value in "cost array"
//----we update optval only in case of success to save time-----------
if (tempval < optval) // if competitor better than the best one ever
optval = tempval; // new best value
optarg = ui(:,i); // new best parameter vector ever
end;
end;
disp("aft_pop(i) "+string(pop(:,i)));
endfunction; //---end for imember=1:NP
parallel_run(1:NP, "gpar"); //calling function gpar in parallel
disp("popThisGen "+string(pop)); //display the population after changes
如果满足某些条件,则 pop 矩阵的第 i 列会发生变化。我在 if 语句前后打印第 i 列。 i 是从 1 到 40 运行s 的向量。我可以从 Scilab 控制台看到这些打印的前 10 个,从终端看到最后 30 个(我的机器有四个内核,我认为它与那)。然后我在 parallel 运行 完成它的工作后打印整个 pop 矩阵。从 pop 的最终版本中,我意识到只有我在 Scilab 控制台观察到的变化生效,并且 none 我在终端观察到的变化。
原始代码的完整版本在http://www1.icsi.berkeley.edu/~storn/code.html#scil
我认为这些损失是我得到糟糕结果的原因。有谁知道可能会发生什么?谢谢
回答有点仓促,不过应该通过结果变量导出结果。如 parallel_run docs 中所述:
Furthermore, no locking primitives are available in Scilab to handle concurrent accesses to shared variables. For this reason, the concurrent execution of Scilab macros cannot be safe in a shared memory environment and each parallel execution must be done in a separate memory space. As a result, one should not rely on side effects such as modifying variables from outer scope : only the data stored into the result variables will be copied back into the calling environment.
还要检查所有并行计算是否完全独立。通过参数获取所有输入。
查看您的代码,声明为全局的所有内容将在所有进程之间共享。所以将它们全部放在参数列表中。您不应该假定单独计算的任何执行顺序。
the Scilab docs 中的示例实际上很好地解释了 return 值。比如下面这个例子。
function [r_min, r_med, r_max]=min_med_max(a, b, c)
r_min=min(a,b,c); r_med=median([a,b,c]); r_max=max(a,b,c);
endfunction
N=10;
A=rand(1:N);B=rand(1:N);C=rand(1:N);
[Min,Med,Max]=parallel_run(A,B,C,"min_med_max");
除了使用结果,SciLab 在定义结果方面非常严格,只有列向量等。
也结账 the Scilab Wiki about parallel computing。
希望对您有所帮助。