0

问题是$oldpopget 的内容在执行函数后神奇地改变了func,而funcis的输入$matepop。内部func,$oldpop未使用(我添加了注释行以显示该位置 - 请参见MAIN.PHP代码片段的末尾)。下面我只提供代码的一些主要部分。也许,有人可以提出问题的原因?

我应该提到我不使用静态变量。

文件 MAIN.PHP

include_once 'func.php';
include_once 'select.php';

class Individual {
    private $genes;
    private $rank;

    public function __construct() {
          $this->genes = array();
          $this->rank = 0;
    }

    public function setRank($val){
            $this->rank = $val;
    }

    public function setGene($i,$val){
        $this->genes[$i] = $val;
    }
}

class Population {
    private $ind;

    public function __construct()
    {
        $this->ind = array();
    }

    public function addIndividual(Individual $ind)
    {
        $this->ind[] = $ind;
    }

    public function getIndividual($i){
        return $this->ind[$i];
    }
  }


    $oldpop = new Population();

  for($i=0; $i<$popsize; $i++) {
    $oldpop->addIndividual(new Individual());
  }

    $oldpop = func($oldpop,$popsize); 

    for ($i = 0; $i < $gener; $i++) 
    {        
        $matepop = new Population();
        $matepop = nselect($matepop,$oldpop,$popsize);

        // !!! Here the $oldpop content is correct (original)
        $matepop = func($matepop,$popsize);
        // !!!! Here the original content of $oldpop is magically changed

    }

文件 SELECT.PHP

function nselect($matepop,$oldpop,$popsize) { 
  $select = array();
  //...
  $select[] = $oldpop->getIndividual($i);
  //...
  for ($i=0; $i < $popsize; $i++) {
       $matepop->addIndividual($select[$i]);
  }
  return $matepop;
}

文件 FUNC.PHP

function func($pop,$popsize) { 
  //...
  $pop->getIndividual($i)->setRank($val);
  //...
  return $pop;
}
4

2 回答 2

1

在您的nselect()功能中,您从以下位置获取个人$oldpop,然后将其添加到$matepop

$select[] = $oldpop->getIndividual($i);
//...
for ($i=0; $i < $popsize; $i++) {
    $matepop->addIndividual($select[$i]);
}

当您这样做时,这不会“创建副本”individual并添加副本 - 它会添加对原始文件的引用。因此,无论您对通过此方法添加的任何内容所做的任何事情都将随之更新,因为它们是完全相同的对象。individuals$matepop$oldpop

因此,在您的方法中,当您在infunc()上设置排名时(我假设这是您在该函数中执行的唯一 -modification),您正在修改 each 的一个也是唯一一个实例,该实例恰好在. 这就是你看到修改的原因。individuals$matepopindividualindividual$matepop $oldpop$oldpop

要解决此类问题,您需要实现某种类型的克隆/复制,而不是直接引用。

于 2012-09-10T21:38:10.943 回答
1

PHP 对象变量不包含对象的完整副本;相反,它们包含对对象的引用。这意味着当您使用

$select[] = $oldpop->getIndividual($i);

在您的代码中,您没有制作对象的新副本$i;您只需将对象的引用复制$i到数组$select中。这意味着两者都$oldpop包含$matepop对它们数组中相同对象的引用。$ind然后,当你后来使用

$pop->getIndividual($i)->setRank($val);

Individual为了在 中设置每个类对象的等级$matepop,它们也更改为$oldpop

于 2012-09-10T21:38:26.327 回答