问题是$oldpop
的内容在执行函数func
后神奇地改变了,而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;
}
答案 0 :(得分:1)
在nselect()
函数中,您将从$oldpop
获取个人,然后将其添加到$matepop
:
$select[] = $oldpop->getIndividual($i);
//...
for ($i=0; $i < $popsize; $i++) {
$matepop->addIndividual($select[$i]);
}
执行此操作时,这不会“创建individual
的副本”并添加副本 - 它会在原始文件中添加reference。因此,无论您对通过此方法添加到individuals
的{{1}} 的任何所做的事情都将在$matepop
中更新,因为它们是完全相同的对象。
因此,在您的$oldpop
方法中,当您在func()
中的individuals
上设置排名时(我假设这是唯一的$matepop
- 您执行的修改在该函数中)您正在修改每个individual
的唯一实例,该实例恰好在individual
和 $matepop
中引用。这就是您看到$oldpop
已修改的原因。
要解决此类问题,您需要实施某种类型的cloning/copying而不是直接引用。
答案 1 :(得分:1)
$select[] = $oldpop->getIndividual($i);
在您的代码中,您没有制作对象$i
的新副本;您只需将对象$i
的引用复制到数组$select
中。这意味着$oldpop
和$matepop
都包含对$ind
数组中相同对象的引用。然后,当你以后使用
$pop->getIndividual($i)->setRank($val);
要设置Individual
中每个$matepop
- 类对象的排名,它们也会更改为$oldpop
。