优化不会与Scilab中的parallel_run函数收敛

时间:2015-04-09 06:02:49

标签: parallel-processing scilab differential-evolution

我试图在Scilab上执行优化,我想使用parallel_run函数并行运行差分进化代码。

代码的原始版本包含我要并行化的部分的for循环,它工作得很好。当我使用parallel_run函数修改代码并在Windows机器上运行时,它再次工作,但据我所知,此功能不适用于Windows,它只能在单个核心上运行。最后,我尝试在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列的列。我在if语句之前和之后打印了第i列。我是一个从1到40的向量。我可以从Scilab控制台看到这些打印中的前10个,并且从终端看到最后30个(我的机器有四个核心,我认为它与此有关)。然后我在并行运行完成其工作后打印整个pop矩阵。从pop的最终版本开始,我意识到只有我在Scilab控制台上观察到的变化才生效,而且我在终端上观察到的变化都没有。

原始代码的完整版本位于http://www1.icsi.berkeley.edu/~storn/code.html#scil

我认为这些损失是我得到的糟糕结果的原因。有没有人知道可能会发生什么?感谢。

1 个答案:

答案 0 :(得分:0)

快点回答,但你应该通过结果变量导出结果。如parallel_run docs中所述:

  

此外,Scilab中没有可用的锁定原语来处理   并发访问共享变量。出于这个原因,   Scilab宏的并发执行在共享中是不安全的   内存环境和每个并行执行必须在一个   单独的内存空间。 因此,不应该依赖于一方   从外部范围修改变量的效果:仅限数据   存储到结果变量中将被复制回调用   环境。

同时检查所有并行计算是否完全独立。通过参数获取所有输入。

查看您的代码,声明为全局的所有内容将在所有进程之间共享。所以将它们全部放在参数列表中。您不应该假设执行单独计算的任何顺序。

the Scilab docs中的示例实际上非常适合解释返回值。例如以下示例。

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

希望这会对你有所帮助。