问题是执行函数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
的副本"并添加副本,而是添加对原始副本的引用。因此,无论你对做什么,通过这种方法添加到$matepop
的individuals
的任何都将在$oldpop
中更新,因为它们是完全相同的对象。
因此,在您的func()
方法中,当您在$matepop
中设置individuals
的秩时(我假设这是您在该函数中执行的唯一individual
修改),您正在修改每个individual
的唯一实例,它恰好在$matepop
和$oldpop
中引用。这就是您看到$oldpop
被修改的原因。
要解决这样的问题,您需要实现某种类型的克隆/复制,而不是直接引用。