优化不与 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

希望对您有所帮助。