// <summary>ソースコード：ＨＹＭＣＯ演算モデルクラス</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.Text;

using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;

using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Tool;

using CommonMP.HYMCO.OptionImple.GAModelSampleLIB.GACtlTools;

// ToDo namespace は　モデル開発者が変更して、ユニークな名称にして下さい
namespace CommonMP.HYMCO.OptionImple.GAModelSampleLIB
{
    // 進化の舞台
    /// <summary><para>class outline:</para>
    /// <para>モデル進化を行うステージ（舞台）の実装</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.3][2010/10/01][新規作成]</para>
    /// </remarks>
    public class GAEvolutionSample : McForecastModelBase, GAEvolutionIF  // ← GAEvolutionIF をインプリメントしている事に注意
    {
        /// <summary> 演算データ（キャスト用） </summary>
        GAEvolutionSampleCalInfo m_csEvKMdlInf = null;   // 便利の為、キャスト用に定義しておく


        //=========================
        // 演算実行前処理関連メソッド
        //=========================

        /// <summary><para>method outline:</para>
        /// <para>入力側の接続情報チェック</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = ReceiveConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>受信するデータが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool ReceiveConnectionCheck(ref McStructErrorInfo csErrorInf, long lInputDataNum, McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;
            if (lInputDataNum == 0)
            {
                // 入力が無い場合
                // エラー
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                     Properties.Resources.STATEMENT_NO_REC_DATA );
               // csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND, "No receive data.");
                bRtn = false;
            }
            m_lMdlInputDataNum = 0;
            m_csMdlInputCellData = new McReceiveCellDataIF[lInputDataNum];
            for (long lP = 0; lP < lInputDataNum; lP++)
            {   // 入力する伝送データ数分繰り返します。
                long lD1 = 0; long lD2 = 0; long lD3 = 0; long lCellDataNum = 0;
                long lCellDim = csInputCellData[lP].GetDimension(ref lD1, ref lD2, ref lD3, ref lCellDataNum);

                if (GeneticAlgorithmSampleDefine.IN_PATTERN_TOP.Equals(csInputCellData[lP].GetReceivePatternID()) == true)
                {   // 予測時＆進化時の上流端入力ならば
                    m_csEvKMdlInf.m_lEvTopInNo = lP;

                    if (lCellDim == 1 && lD1 == 1)
                    {   // 1次元の１セルでならば
                        m_csMdlInputCellData[m_lMdlInputDataNum] = csInputCellData[lP];
                        m_lMdlInputDataNum +=1;
                    }
                    else
                    {
                        //csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                        //    "Variable number in the Cells is too short. (Received from " + csInputCellData[lP].GetUpperElementID().ToString() + ")");
                        bRtn = false;
                    }
                }
                else if (GeneticAlgorithmSampleDefine.IN_EVOLUTION_REF_PTN.Equals(csInputCellData[lP].GetReceivePatternID()) == true)
                {   // 進化時の比較用データ入力端子ならば
                    m_csEvKMdlInf.m_lEvRefInNo = lP;

                    if (lCellDim == 1 && lD1 >= 1)
                    {   // 1次元の１セルでならば
                    }
                    else
                    {
                        //csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                        //    "Variable number in the Cells is too short. (Received from " + csInputCellData[lP].GetUpperElementID().ToString() + ")");
                        bRtn = false;
                    }
                }
                else
                {
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                         Properties.Resources.STATEMENT_UNEXPECT_REC_DATA_TYPE_R + csInputCellData[lP].GetUpperElementID().ToString() + ")");
                   // csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                   //     "Unexpected receive data type. (Received from " + csInputCellData[lP].GetUpperElementID().ToString() + ")");
                    bRtn = false;
                }

            } // end of for (lP)
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>出力側の接続情報チェック</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = SendConnectionCheck(ref csErrorInf)</para>
        /// </example>
        /// <param name="csErrorInf">エラー出力</param>
        /// <param name="lOutputDataNum">出力情報数</param>
        /// <param name="csOutputCellData">出力情報配列</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>送信端子に設定されている伝送データが自モデルが期待している情報か否かをチェックする</para>
        /// </remarks>
        protected override bool SendConnectionCheck(ref McStructErrorInfo csErrorInf, long lOutputDataNum, McSendCellDataIF[] csOutputCellData)
        {
            bool bRtn = true;
            if (lOutputDataNum == 0)
            {
                // 警告（エラーではない）
               // ver1.5 エラートレース日本語対応
                csErrorInf.AddCheckWarningData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND, 
                     Properties.Resources.STATEMENT_NO_SND_PORT );
               // csErrorInf.AddCheckWarningData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND, "No send port.");
            }
            m_lMdlOutputDataNum = 0;
            m_csMdlOutputCellData = new McSendCellDataIF[lOutputDataNum];
            for (long lP = 0; lP < lOutputDataNum; lP++)
            {   // 出力する伝送データ数分繰り返します。

                long lD1 = 0; long lD2 = 0; long lD3 = 0; long lCellDataNum = 0;
                long lCellDim = csOutputCellData[lP].GetDimension(ref lD1, ref lD2, ref lD3, ref lCellDataNum);
                if (GeneticAlgorithmSampleDefine.OUT_EVOLUTION_FITNESS_PTN.Equals(csOutputCellData[lP].GetSendPatternID()) == true)
                {   // 適合度出力ならば
                    if (lCellDim == 1 && lD1 == 1)
                    {   // １次元配列の１セルならば
                        m_csEvKMdlInf.m_lEvFitnessOutNo = lP;
                    }
                    else
                    {
                       // ver1.5 エラートレース日本語対応
                            csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                                 Properties.Resources.STATEMENT_VAL_NUM_SHORT_S + csOutputCellData[lP].GetLowerElementID().ToString() + ")");
                           // csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                           //     "Variable number in the Cells is too short. (Send To " + csOutputCellData[lP].GetLowerElementID().ToString() + ")");
                            bRtn = false;
                    }
                }
                else if (GeneticAlgorithmSampleDefine.OUT_PATTERN_BOTTOM.Equals(csOutputCellData[lP].GetSendPatternID()) == true)
                {   // 最終セルだけの出力ならば
                    if (lCellDim == 1 && lD1 == 1)
                    {   // １次元配列の１セルならば
                        m_csMdlOutputCellData[m_lMdlOutputDataNum] = csOutputCellData[lP];
                        m_lMdlOutputDataNum += 1;
                    }
                    else
                    {
                       // ver1.5 エラートレース日本語対応
                        csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                             Properties.Resources.STATEMENT_VAL_NUM_SHORT_S + csOutputCellData[lP].GetLowerElementID().ToString() + ")");
                       // csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                       //     "Variable number in the Cells is too short. (Send To " + csOutputCellData[lP].GetLowerElementID().ToString() + ")");
                        bRtn = false;
                    }
                }
                else if (GeneticAlgorithmSampleDefine.OUT_PATTERN_ALL.Equals(csOutputCellData[lP].GetSendPatternID()) == true)
                {   // 全セルの出力ならば
                    if (lCellDim == 1 && lD1 >= 1)
                    {   // １次元配列
                        m_csEvKMdlInf.m_lEvRefOutNo = lP;
                        m_csMdlOutputCellData[m_lMdlOutputDataNum] = csOutputCellData[lP];
                        m_lMdlOutputDataNum += 1;
                    }
                    else
                    {
                       // ver1.5 エラートレース日本語対応
                        csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                             Properties.Resources.STATEMENT_VAL_NUM_SHORT_S + csOutputCellData[lP].GetLowerElementID().ToString() + ")");
                       // csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                       //     "Variable number in the Cells is too short. (Send To " + csOutputCellData[lP].GetLowerElementID().ToString() + ")");
                        bRtn = false;
                    }
                }
                else
                {
                    // エラー
                   // ver1.5 エラートレース日本語対応
                    csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                         Properties.Resources.STATEMENT_UNEXPECT_DATA_TYPE );
                   // csErrorInf.AddCheckErrorData(this.GetID(), GeneticAlgorithmSampleDefine.GAKinematicWaveEvolutionModel_MODEL_KIND,
                   //     "Unexpected send data type.");
                    bRtn = false;
                }
            } // end of for (lP)
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>Initialize(csInitialData)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override bool Initialize(ref McPropertyInfoRoot csInitialData, long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            bool bRtn = true;

            if (m_csEvKMdlInf.m_bEvCalMode == true)
            {   // 進化計算中
                for (long lLp = 0; lLp < m_lNumIndividual; lLp++)
                {
                    m_csCreature[lLp].InitalCompetition(ref csInitialData, m_lMdlInputDataNum, ref m_csMdlInputCellData);
                }
            }
            else
            {   // 予測計算中
                m_csSuperEliteChromosome = new GAChromosomeSample();
                m_csSuperEliteChromosome.FileIn(m_csEvKMdlInf.m_sChromosomeFile);

                m_csSupperElite = m_csSuperEliteChromosome.Genesis();
                bRtn = m_csSupperElite.InitalCompetition(ref csInitialData, m_lMdlInputDataNum, ref m_csMdlInputCellData);
            }

            return bRtn;
        }

        //=======================
        // 演算実行処理関連メソッド
        //=======================

        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>long lRtn = Calculate(ref csInputCellData)</para>
        /// </example>
        /// <param name="lInputDataNum">入力情報数</param>
        /// <param name="csInputCellData">演算に必要な入力情報配列</param>
        /// <returns>0 :正常 , -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override long Calculate(long lInputDataNum, ref McReceiveCellDataIF[] csInputCellData)
        {
            long lRtn = 0;
            if (m_csEvKMdlInf.m_bEvCalMode == true)
            {   // 進化計算中
                m_lCallCalculateNum += 1;
                for (long lLp = 0; lLp < m_lNumIndividual; lLp++)
                {
                    // 内部状態計算
                    m_csCreature[lLp].Competition(m_lMdlInputDataNum, ref m_csMdlInputCellData);
                }
            }
            else
            {   // 予測計算中
                lRtn = m_csSupperElite.Competition(m_lMdlInputDataNum, ref m_csMdlInputCellData);
            }
            return lRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル演算結果を外部のエレメントに対して公開する</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>long lRtn = DataFusion( lOutputDataNum, ref csOutputCellData)</para>
        /// </example>
        /// <param name="lOutputDataNum">出力情報数</param>
        /// <param name="csOutputCellData">出力情報配列</param>
        /// <returns>0 :正常 , -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override long DataFusion(long lOutputDataNum, ref McSendCellDataIF[] csOutputCellData)
        {
            long lRtn = 0;

            if (m_csEvKMdlInf.m_bEvCalMode == true)
            {   // 進化計算中

                if( m_lCallCalculateNum > 0 )
                {   // 計算がされていなければ、フィットネス計算は無意味
                    // フィットネス計算用　比較データ取得
                    m_InputCellData[m_csEvKMdlInf.m_lEvRefInNo].SetCurrentTime(this.m_csSimTime);
                    HySCellData[] csCellDtArry = m_InputCellData[m_csEvKMdlInf.m_lEvRefInNo].GetInterpolatedCellD1();

                    for (long lLp = 0; lLp < m_lNumIndividual; lLp++)
                    {
                        // フィットネス計算
                        m_csCreature[lLp].CalFitness(ref csCellDtArry);
                        //m_csFitValueTable.SetFitVal(lLp, dFitDt);
                    }  
                }
                m_lCallCalculateNum = 0;
            }
            else
            {   // 予測計算中
                lRtn = m_csSupperElite.OutCompetition(m_lMdlOutputDataNum, ref m_csMdlOutputCellData);
            }
            return lRtn;
        }


        //====================
        // その他必要なメソッド
        //====================

        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報を設定する</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>SetProperty(csCellMdlPropertyInfo)</para>
        /// </example>
        /// <param name="csCellMdlPropertyInfo">セル型プロパティ情報</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SetProperty(McCellModelPropertyIF csCellMdlPropertyInfo)
        {
            bool bRtn = false;
            // 使用しやすいようにキャストしておく
            m_csEvKMdlInf = (GAEvolutionSampleCalInfo)m_csCalInfo;

            // プロパティ設定
            McCellModelPropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McCellModelPropertyInfo;
            if (csPrptyInfo != null)
            {
                // 演算ステップ時刻設定
                this.m_csDltTime = new HySTime(csPrptyInfo.GetStepTime());

                bRtn = true;

                // 各種係数設定
                csPrptyInfo.GetInfo("m_lCreatureNum", ref m_csEvKMdlInf.m_lCreatureNum);
                csPrptyInfo.GetInfo("m_lCalElmNumber", ref m_csEvKMdlInf.m_lCalElmNumber);
                csPrptyInfo.GetInfo("m_lCelDivNumber", ref m_csEvKMdlInf.m_lCelDivNumber);
                string sSuperElite = "";
                csPrptyInfo.GetInfo("m_sChromosomeFile", ref sSuperElite);
                m_csEvKMdlInf.m_sChromosomeFile = this.GetProjectGroupDirectory().ToString() + "\\" + sSuperElite;
                //csPrptyInfo.GetInfo("m_sChromosomeFile", ref m_csEvKMdlInf.m_sChromosomeFile);
            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>計算開始時に動作する処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = ReadyCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>計算開始の　最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public override bool ReadyCalculation()
        {
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>計算中断時に動作する処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = SuspendCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>オペレーター操作等により計算中断時に　コールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public override bool SuspendCalculation()
        {
            //McLog.DebugOut(GetSimulationTime(), GetID(), "MyModel", "SuspendCalculation", "in");

            // ToDo
            // オペレーター操作等により計算中断時に　コールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。
            // （メソッド自身を削除してください）

            //McLog.DebugOut(GetSimulationTime(), GetID(), "MyModel", "SuspendCalculation", "out");
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>計算終了時に動作する処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = CompleteCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>計算終了時　最後の最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。</para>
        /// </remarks>
        public override bool CompleteCalculation()
        {
            //McLog.DebugOut(GetSimulationTime(), GetID(), "MyModel", "CompleteCalculation", "in");

            // ToDo
            // 計算終了時　最後の最初に１回だけコールされるメソッドです。不要ならば、本メソッドをオーバーライドする必要はありません。
            // （メソッド自身を削除してください）

            //McLog.DebugOut(GetSimulationTime(), GetID(), "MyModel", "CompleteCalculation", "out");
            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>演算用刻み時間を自動的に変更する</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>ChangeDeltaTimeAutomatically()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void ChangeDeltaTimeAutomatically()
        {
            //McLog.DebugOut(GetSimulationTime(), GetID(), "MyModel", "ChangeDeltaTimeAutomatically", "in");

            // ToDo
            // 演算中条件によって　自身のδTを(this.m_csDltTime) を変更するメソッドです。
            // 不要ならば、本メソッドをオーバーライドする必要はありません。（メソッド自身を削除してください）

            //McLog.DebugOut(GetSimulationTime(), GetID(), "MyModel", "ChangeDeltaTimeAutomatically", "out");
        }

        // ==================================================================================================
        // ↓↓↓　以下は、遺伝子アルゴリズムを動作させるための　ステージ（舞台）としての情報／メソッドを記述　↓↓↓
        // ==================================================================================================

        /// <summary>世代</summary>
        long m_lGeneration = 1;
        /// <summary> 遺伝子交鎖率</summary>
        double m_dCrossOverRatio = 0.01;
        /// <summary>突然変異発生率 </summary>
        double m_dMutationRatio = 0.02;

        /// <summary>固体数</summary>
        long m_lNumIndividual=0;
        /// <summary>各固体の染色体 </summary>
        GAChromosomeIF[] m_csChromosome;
        /// <summary>進化固体 </summary>
        GACreatureIF[] m_csCreature;
        /// <summary>各個体の適合度表 </summary>
        GAFitValueTable m_csFitValueTable;
        /// <summary>ルーレット</summary>
        GARoulette m_csRoulette;

        /// <summary>スーパーエリート遺伝子 </summary>
        GAChromosomeIF m_csSuperEliteChromosome=null;
        /// <summary>スーパーエリート </summary>
        GACreatureIF m_csSupperElite=null;

        /// <summary>ワーク用の染色体 </summary>
        GAChromosomeIF[] m_csNextChromosome;

        /// <summary>Calculate（）メソッドコールフラグ </summary>
        long m_lCallCalculateNum = 0;

        /// <summary>内部の固体への入力伝送データ数 </summary>
        long m_lMdlInputDataNum = 0;
        /// <summary>内部の固体への入力伝送データ </summary>
        McReceiveCellDataIF[] m_csMdlInputCellData;
        /// <summary>内部の固体からの出力伝送データ数 </summary>
        long m_lMdlOutputDataNum = 0;
        /// <summary>内部の固体からの出力伝送データ </summary>
        McSendCellDataIF[] m_csMdlOutputCellData;

        /// <summary><para>method outline:</para>
        /// <para>動作モード設定</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>SetMode(bSW)</para>
        /// </example>
        /// <param name="bSW">進化計算モード：true=進化計算中、false=通常計算</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// 進化モード：true  の時には進化計算を行わせる。
        /// 進化モード：false の時には進化後のスーパーエリートが動作する
        /// </para>
        /// </remarks>
        public virtual void SetMode(bool bSW)
        {
            m_csEvKMdlInf.m_bEvCalMode = bSW;
        }
        /// <summary><para>method outline:</para>
        /// <para>遺伝子設定</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>SetChromosomes(lNumIndividual,csChromosome)</para>
        /// </example>
        /// <param name="lNumIndividual">遺伝子の数</param>
        /// <param name="csChromosome">遺伝子情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// ステージ（舞台）内に　これから進化する固体の遺伝子を設定する
        /// </para>
        /// </remarks>
        public virtual void SetChromosomes(long lNumIndividual, GAChromosomeIF[] csChromosome)
        {
            m_lNumIndividual = lNumIndividual;

            m_dMutationRatio = 5.0 / ((double)lNumIndividual+0.01);  // １世代で５個程度の固体に突然変異が起こる程度の値
            m_dCrossOverRatio = 5.0 / ((double)lNumIndividual + 0.01);  // １世代で５個程度の固体に交差が起こる程度の値

            // 染色体配列確保
            m_csChromosome = new GAChromosomeIF[m_lNumIndividual];
            m_csNextChromosome = new GAChromosomeIF[m_lNumIndividual];
            // 染色体から固体を発生させる
            m_csCreature = new GACreatureIF[m_lNumIndividual];
            for (long lLp = 0; lLp < m_lNumIndividual; lLp++)
            {
                m_csChromosome[lLp] = csChromosome[lLp];
                m_csCreature[lLp] = csChromosome[lLp].Genesis();
            }
            // 適合度表生成
            m_csFitValueTable = new GAFitValueTable(lNumIndividual);
            // ルーレットツール
            m_csRoulette = new GARoulette(lNumIndividual);
        }

        // 世代リセット
        /// <summary><para>method outline:</para>
        /// <para>進化世代数のリセット</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>ResetGeneration( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void ResetGeneration()
        {
            m_lGeneration = 1;
        }

        // 適合度リセット
        /// <summary><para>method outline:</para>
        /// <para>各個体の環境適合度のリセット</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>ResetFitness( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>１世代毎にリセットを行う</para>
        /// </remarks>
        public virtual void ResetFitness()
        {
            for (long lLp = 0; lLp < m_lNumIndividual; lLp++)
            {
                m_csCreature[lLp].ResetFitness();
            }
        }

        // 繁殖
        /// <summary><para>method outline:</para>
        /// <para>繁殖</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>Breeding( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// 適合度に応じて、次世代の遺伝子を残す
        /// （適合度の高い固体ほど、多くの遺伝子を残す）
        /// 繁殖は、１世代の計算が終了の後、行う
        /// </para>
        /// </remarks>
        public virtual void Breeding()
        {

            // 各個体の適合度を設定する
            for (long lLp = 0; lLp < m_lNumIndividual; lLp++)
            {
                m_csFitValueTable.SetFitVal(lLp, m_csCreature[lLp].GetFitValue());
            }
            // 適合度に応じた不均一ルーレットを生成する
            m_csRoulette.MakeRoulette(m_csFitValueTable);

            // スーパーエリート遺伝子のファイル保存（進化終了後に使用する）
            m_csSuperEliteChromosome = m_csChromosome[m_csRoulette.GetElite()].Copy();
            m_csSuperEliteChromosome.FileOut(m_csEvKMdlInf.m_sChromosomeFile);
            // 進化の過程を調査するため　スーパーエリートの遺伝子を化石として残す
            String sGname = m_csEvKMdlInf.m_sChromosomeFile + "G" + m_lGeneration.ToString();
            m_csSuperEliteChromosome.FileOut(sGname);

            double dSperFit = m_csCreature[m_csRoulette.GetElite()].GetFitValue(); // スーパーエリートの適合度
           // ver1.5 エラートレース日本語対応
            McLog.DebugOut(new HySTime(m_lGeneration), GetID(), "GAEvolutionSample", "Breeding",
                Properties.Resources.STATEMENT_FITNESS + dSperFit.ToString());
           // McLog.DebugOut(new HySTime(m_lGeneration), GetID(), "GAEvolutionSample", "Breeding", "Fitness=" + dSperFit.ToString());
            

            long lNumChild = 0; // 子供の数

            // スーパーエリートの遺伝子は必ず１個残す
            m_csNextChromosome[lNumChild] = m_csChromosome[m_csRoulette.GetElite()].Copy();
            lNumChild += 1;

            // 残りの繁殖を行う
            // 突然変異率等は、最初は大きく、次第に小さくさせる
            //    （シミュレーティッド・アニーリングに近い効果を発生させるため）
            double dMutationRatio = m_dMutationRatio * (1.0 + 25.0/(25.0+(double)(m_lGeneration)));
            double dCrossOverRatio = m_dCrossOverRatio;
            long lFatherNo = 0;
            GAChromosomeIF csFather = null;
            long lMotherNo = 0;
            GAChromosomeIF csMother = null;
            for (long lLp = 1; lLp < m_lNumIndividual; lLp++)
            {
                // 不均一ルーレットを使用して両親の選択
                lFatherNo = m_csRoulette.Bet();
                csFather = m_csChromosome[lFatherNo].Copy();
                lMotherNo = m_csRoulette.Bet();
                csMother = m_csChromosome[lMotherNo].Copy();

                // 突然変異と遺伝子交差を行わせる
                csMother.CrossOver(ref csFather, dCrossOverRatio);  // CrossOver
                csMother.Mutation(dMutationRatio);  // Mutation

                // 母方の遺伝子を残す
                m_csNextChromosome[lNumChild] = csMother.Copy();
                lNumChild += 1;
            }

            // ワーク領域から本領域へ代入　＆　固体発生
            for (long lLp = 0; lLp < m_lNumIndividual; lLp++)
            {
                m_csChromosome[lLp] = m_csNextChromosome[lLp];
                m_csCreature[lLp] = m_csChromosome[lLp].Genesis();
            }
            m_lGeneration+=1; // 世代をインクリメント

            this.ResetFitness();

            // 此処で、適合状況を出力する
            for (long lLp = 0; lLp < m_lOutputDataNum; lLp++)
            {   // 出力する伝送データ数分繰り返します。
                if (GeneticAlgorithmSampleDefine.OUT_EVOLUTION_FITNESS_PTN.Equals(m_OutputCellData[lLp].GetSendPatternID()) == true)
                {   // 適合度の出力ならば

                    m_OutputCellData[lLp].SetCurrentTime(new HySTime(m_lGeneration));
                    HySCellData[] csSndCellData = m_OutputCellData[lLp].PrepareSendCellD1();

                    csSndCellData[0].m_dData[0] = dSperFit*(1.0);

                    m_OutputCellData[lLp].SendData();
                }
            }
        }

    }
}
