问题
The problem is that the content of $oldpop
get magically changed after executing the function func
, whereas the input of func
is $matepop
. Inside func
, $oldpop
is not used (I added the comment line to show the place - see the end of the code snippet of MAIN.PHP). Below I provide just some principal parts of the code. Maybe, someone could suggest the reason of the problem?
I should mention I don't use static variables.
File 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
}
File 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;
}
File FUNC.PHP
function func($pop,$popsize) {
//...
$pop->getIndividual($i)->setRank($val);
//...
return $pop;
}
回答1:
PHP object variables don't contain a full copy of the object; rather, they contain a reference to the object. This means that when you used
$select[] = $oldpop->getIndividual($i);
in your code, you didn't make a new copy of the object $i
; you simply copied the reference to the object $i
into the array $select
. This means that both $oldpop
and $matepop
contain references to the same objects in their $ind
arrays. Then, when you later used
$pop->getIndividual($i)->setRank($val);
to set the rank of each Individual
-class object in $matepop
, they also changed for $oldpop
.
回答2:
In your nselect()
function, you're getting individuals from $oldpop
and then adding them to $matepop
:
$select[] = $oldpop->getIndividual($i);
//...
for ($i=0; $i < $popsize; $i++) {
$matepop->addIndividual($select[$i]);
}
When you do this, this does not "create a copy" of the individual
and add the copy - it adds a reference to the original. So, whatever you do to any of the individuals
added to $matepop
through this method will consequently be updated in $oldpop
as well because, well, they're the exact same object.
So, in your func()
method, when you set the rank on the individuals
in $matepop
(and I'm assuming that's the only individual
-modification you perform in that function) you're modifying the one and only instance of each individual
, which happens to be referenced in $matepop
and $oldpop
. This is why you see $oldpop
modified.
To resolve an issue like this, you'll need to implement some type of cloning/copying instead of a direct reference.
来源:https://stackoverflow.com/questions/12359554/code-the-content-of-an-object-is-changed-after-executing-a-function