[[ノート>ノート/ノート]]
訪問数 &counter();  最終更新 &lastmod();

***EPMRを読んでみる 〜 実行の流れ [#sd8bd328]

-main.cpp 39行 Epmr epmr( cout )でインスタンス作成、コンストラクタ?
--クラスEpmrはEpmr.h内44行目で宣言、IterativeOptimizer< int >のサブクラス。
--クラスIterativeOptimizerはIterativeOptimizer.h内30行目で宣言。
---IterativeOptimizerのコンストラクタはなさそう~
メソッドはpublicなOptimizeと~IterativeOptimizer(デストラクタ)、protectedなInitialize, Step, Convergedを宣言。
--epmrのメソッドは、Epmr.hで宣言、Epmr.cppで実体を定義。
---publicなものは、Epmr(コンストラクタ、Epmr.cppの54行目)、~Epmr(デストラクタ、Epmr.cppの64行目)、SetOption(Epmr.cppの682行目)
---protectedなものは、Initialize(Epmr.cppの168行目)、Step(479行目)、Converged(674行目)~
InitializeOptions(74行目), ReconcileOptions(697行目), GetDoubleOptionValue(), GetIntegerOptionvalue()~
WriteSolution(904行目), WriteAtoms(992行目), CompareToBest(1055行目)~
PrintProgramHeader(746行目), PrintOptionSummary(754行目), ReportSolutions(858行目), ReportSummary(1459行目)~
LoadCell(1173行目), LoadModel(文字ファイルから、1212行目), LoadModel(istreamから、1237行目), LoadReflections(1251行目),~
CreateGlobalOptimizer(1341行目), CreateLocalOptimizer(1357行目),~
CreateMutator(1366行目), CalcStaticStructureContribution(1433行目), CalcTransforms(934行目), CalcSegmentTransforms(969行目)~
StoreAtoms(1143行目), CalcPackingClashes(1560行目), SplitSegments(1505行目),~
SetSpacegroupOptions(1480行目), NormalizeSolution(1671行目)
--Epmrのコンストラクタ実行。スーパークラスのコンストラクタはEpmrのコンストラクタでオーバーライドされているから、Epmrのコンストラクタ(Epmr.cppの54-60行目)を使う。実質はいろいろな初期化。

-main.cpp 41-133行目で、epmrコマンドラインでのオプション指定を解析し、その指定に従ってepmr.SetOptionによってオプション値設定(たとえばepmr.SetOption( "optimize.assembly", "false" );)
-main.cpp 134-146行目で、オプション以外のパラメタ(ファイル名、cellsource, modelsource, datasource)の解析

-epmr.Optimize(0)の呼出し (=実行)

***epmr.Optimize(0)以降の動き [#h7efb793]
-この時呼び出されるepmr.Optimizeは、Epmr.cppやEpmr.hでは静的には何もされないようなので、スーパークラスのIterativeOptimizerの中のメソッドOptimizeの定義(IterativeOptimizer.hの54-60行目)
 template< class T >
 void IterativeOptimizer< T >::Optimize( T* solution ) {
     Initialize( solution );
     while ( ! Converged() ) {
         Step();
     }
 }
に従うと考えてよかろう。~
今の時点でのメソッドInitialize, Converged, Stepは、(静的に??)Epmrのメソッドでオーバーライドされていると思われる。つまりEpmr.cppの186-478行目のInitiazlie、674-681行目のConverged、476-673行目のStepを使うことになる。

-Initialize( solution )の実行~
この時のInitiazlizeはEpmrのものでオーバーライドされているから、Epmr.cppの186-478行目([[説明はここ>ノート/EPMRを見る1#Initialize]])を使う。

-Convergedが成り立たなければ~
EpmrのConverged(Epmr.cpp 674行目)の内容は
 bool Epmr::Converged() {
     return ( ( maximizing && bestScore > scoreThreshold ) ||
              ( ! maximizing && bestScore < scoreThreshold ) ||
              firstTargetIndex >= (int) cells.size() );
 }

-Stepを繰り返す~
EpmrのStep(Epmr.cpp 479行目〜)の内容は[[ここに説明>ノート/EPMRを見る1#Step]]~
ここで面倒なのは、
--Epmr::Step内506-518行目で、コマンドラインパラメタのoptimizer指定によって、変数optimizer=CreateGlobalOptimizer, 変数localOptimizer=CreateLocalOptimizerで書き換えておいて、(CreateGlobalOptimizerの中で新しいEvolutionaryOptimizerのインスタンスがnewされる。当然コンストラクタが呼び出されるはず?)
--Epmr::Step内の519-537行目で、optimizer->Optimize(&best) を呼ぶこと。
つまりOptimizeの中身がパラメタによって変わるので注意。
--ところで、OptimizeはたとえばEvolutionaryOptimizerのOptimize関数を使うことになる。
--実はよく見るとEvolutionaryOptimizerクラスの中でメソッドOptimizeはオーバーライドしていない。従って、CreateGlobalOptimizer関数の戻り値(=EvolutionaryOptimizerの新しいインスタンス)EvolutionaryOptimizerのメソッドoptimizer->Optimizeを実行すると、結局はIterativeOptimizerのOptimizeメソッドを実行することになるはず。~
--つまり
     Initialize( solution );
     while ( ! Converged() ) {
         Step();
     }
ということになる。
--InitializeはEvolutionaryOptimizerのInitialize(EvolutionaryOptimizer.hの99行目)を実行するはず。既にEpmrのInitializeは実行済みなので、EvolutionaryOptimizerのInitializeはかなり簡単。
 template < class T >
 void EvolutionaryOptimizer< T >::Initialize( T* aSolution ) {
     solution = aSolution;
     if ( members == 0 ) {
         members = new T[ nMembers ];
         scores = new double[ nMembers ];
         ranks = new double[ nMembers ];
         sortedIndices = new int[ nMembers ];
     }
     creator->Create( members, members + nMembers );
     for ( int i = 0; i < nMembers; i++ ) {
         sortedIndices[ i ] = i;
     }
     ScoreMembers( 0, nMembers - 1 );
     RankMembers();
     generation = 0;
 }
--while ( ! Converged() )もEvolutionaryOptimizer.hの131行目を実行するはずで
 template < class T >
 bool EvolutionaryOptimizer< T >::Converged() {
     return ( generation >= nSteps );
 }
--Stepは、EvolutionaryOptimizer.hの118行目で、
 template < class T >
 void EvolutionaryOptimizer< T >::Step() {
     int nSurvivors = selector->CalcNumberOfSurvivors( nMembers, generation, nSteps );
     generation++;
     Regenerate( nSurvivors, nMembers - 1 );
     ScoreMembers( nSurvivors, nMembers - 1 );
     RankMembers();
     // copy the best solution so the output is updated on each step
     *solution = members[ sortedIndices[ 0 ] ];
     if ( reporter != 0 ) reporter->Report( generation, scores, scores + nMembers );
 }
これをConvergedになるまで繰り返す。これが内側のループということになるのだろう。~
収束したらループ脱出して、Epmr::Stepに戻る。
---CalcNumberOfSurvivorsは、?
---CalcNumberOfSurvivorsは、LinearSelector.hとLinearSelector.cppで定義されており、Selector (LinearSelector)クラスのメソッド。
 int Optimization::LinearSelector::CalcNumberOfSurvivors( int nMembers, int generation, int maxGeneration ) {
     int numSurvivors = (int) ( ( startingSurvivalFraction + 
        ( ( endingSurvivalFraction - startingSurvivalFraction ) * 
          ( (double) generation / (double) maxGeneration ) ) ) * nMembers );
     if ( numSurvivors < 1 ) numSurvivors = 1;
     else if ( numSurvivors > nMembers ) numSurvivors = nMembers;
     return numSurvivors;
 }
---Regenerateは、EvolutionaryOptimizer.hの155-160行目で
 template< class T >
 void EvolutionaryOptimizer< T >::Regenerate( int firstIndex, int lastIndex ) {
     for ( int i = firstIndex; i <= lastIndex; i++ ) {
         mutator->Mutate( &members[ sortedIndices[ i ] ], firstIndex, this );
     }
 }
つまりfirstIndexからlastIndexまで、mutator->Mutateを呼び出すらしい。
---ScoreMembersは、EvolutionaryOptimizer.hの147-152行目で
 template< class T >
 void EvolutionaryOptimizer< T >::ScoreMembers( int firstIndex, int lastIndex ) {
     for ( int i = firstIndex; i <= lastIndex; i++ ) {
         scores[ sortedIndices[ i ] ] = scorer->Score( members[ sortedIndices[ i ] ] );
     }
 }
だが、scoresを計算している。
---RankMembersは、EvolutionaryOptimizer.hの139-144行目で
 template < class T >
 void EvolutionaryOptimizer< T >::RankMembers() {
     ranker->Rank( scores, scores + nMembers, ranks );
     EvCompare compare( ranks );
     std::sort( sortedIndices, sortedIndices + nMembers, compare );
 }
ranker->Rankを呼び出しておき(ranks上で計算?)、関数compare(比較「<」の代わり)を定義し、そのcompareを使ってstd::sortする?
---*solutionを置き換え
---reporter->Report

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS