CODE-对象的内容在执行一个函数后发生更改


CODE - The content of an object is changed after executing a function

问题是执行函数func后,$oldpop的内容发生了神奇的变化,而func的输入是$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;
}

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

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

在您的代码中,您没有创建对象$i的新副本;您只需将对对象CCD_ 8的引用复制到数组CCD_。这意味着$oldpop$matepop在其$ind数组中都包含对相同对象的引用。然后,当你后来使用时

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

为了设置$matepop中每个Individual-类对象的秩,它们也为$oldpop进行了更改。

nselect()函数中,您从$oldpop中获取个体,然后将它们添加到$matepop:

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

执行此操作时,不会"创建individual的副本"并添加副本,而是添加对原始副本的引用。因此,无论你对做什么,通过这种方法添加到$matepopindividuals的任何都将在$oldpop中更新,因为它们是完全相同的对象。

因此,在您的func()方法中,当您在$matepop中设置individuals的秩时(我假设这是您在该函数中执行的唯一individual修改),您正在修改每个individual的唯一实例,它恰好在$matepop$oldpop中引用。这就是您看到$oldpop被修改的原因。

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