0

問題は$oldpop、関数の実行後にgetの内容が魔法のように変更さ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;
}
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であると仮定します)、それぞれの唯一のインスタンスを変更します。これは、とで参照されます。これが、変更されたと表示される理由です。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 に答える