// <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;
using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Controller;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Tool;
using CommonMP.HYMCO.CoreImpl.Model;
using CommonMP.HYMCO.CoreImpl.Controller;

using CommonMP.HYMCO.OptionImple.GAModelSampleLIB.GACtlTools;


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 GAControlSample : McSubSystemCtl   // <-- McSubSystemCtl の派生である事に注意
    {
        /// <summary> 演算データ </summary>
        GAControlSampleCalInfo m_csMyInf = new GAControlSampleCalInfo();

        /// <summary>進化テスト用入力データファイル読み込み入力要素インスタンス </summary>
        GATestINFileModel m_csEVInputMdl = null;
        /// <summary>進化テスト用参照データファイル読み込み入力要素インスタンス </summary>
        GATestINFileModel m_csEVRefMdl = null;
        /// <summary>モデル進化を行うステージ（舞台）インスタンス </summary>
        GAEvolutionSample m_csEvlMdl = null;

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

        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Initialize( ref csInitialData,  ref csInputDataList, ref csOutputDataList)</para>
        /// </example>
        /// <param name="csInitialData">初期化設定情報</param>
        /// <param name="csInputDataList">前段接続要素からの伝送情報リスト</param>
        /// <param name="csOutputDataList">前段接続要素への伝送情報リスト</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool Initialize(ref McPropertyInfoRoot csInitialData, ref HySDataLinkedList csInputDataList, ref HySDataLinkedList csOutputDataList)
        {
            bool bRtn = true;
            m_csMyInf.m_lCalGeneration = 0; // 計算済み世代のリセット
            long lCalCnt = (long)((this.m_csFinalTgtTime.GetTime() - this.m_csStartTime.GetTime()) / this.m_csDltTime.GetTime());
            m_csMyInf.m_lGnrtnInclNum = (long)(lCalCnt / m_csMyInf.m_lEvGenerationNum);
            if (m_csMyInf.m_lGnrtnInclNum < 1) { m_csMyInf.m_lGnrtnInclNum = 1; }

            m_csEVInputMdl = this.GetModel(new HySString(m_csMyInf.m_csEVInputCalElmName)) as GATestINFileModel;
            m_csEVRefMdl = this.GetModel(new HySString(m_csMyInf.m_csEVRefCalElmName)) as GATestINFileModel;
            m_csEvlMdl = this.GetModel(new HySString(m_csMyInf.m_csEvolutionMdlName)) as GAEvolutionSample;
            if (m_csEvlMdl != null)
            {
                m_csEvlMdl.SetMode(m_csMyInf.m_bEvCalMode);
                if (m_csMyInf.m_bEvCalMode == true)
                {   // 進化中ならば
                    m_csEvlMdl.ResetGeneration();//世代数リセット
                    m_csEvlMdl.SetChromosomes(m_csMyInf.m_lCreatureNum, m_csMyInf.m_csChromosome);
                }
                else
                {
                    // Do Nothing
                }
            }
            bRtn = base.Initialize(ref csInitialData, ref csInputDataList, ref csOutputDataList);
            return bRtn;
        }

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

        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate( ref csInputDataList)</para>
        /// </example>
        /// <param name="csInputDataList">演算に必要な入力情報リスト</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override long Calculate(ref HySDataLinkedList csInputDataList)
        {
            if (m_csMyInf.m_bEvCalMode == false)
            {   // 通常計算中ならば
                return base.Calculate(ref csInputDataList);
            }
            // 進化計算中ならば
            int iLoop; // ループカウンター（速度アップのため、ループ内での変数のnew を控える）
            int iLp;

            long lRtn = McDefine.CALCULATION_NORMAL_RETURN; // リターンコード

            long lLclRtn = 0;// ローカル変数
            int iElmCnt = m_csElementList.Count;  // グループ内のエレメント数取得
            McGrElement csGrElementWork = null;
            HySTime csNextTargetTime = new HySTime(0);  // シミュレーション目標時刻
            HySTime csSimulationTime = new HySTime(0); // シミュレーション時刻

            if (m_csMyInf.m_lCalGeneration >= m_csMyInf.m_lEvGenerationNum)
            {
                return 0;
            }

            for (long lGenLp = 0; lGenLp < m_csMyInf.m_lGnrtnInclNum; lGenLp++)
            {   // 増加世代分繰り返す
                
                m_csEvlMdl.ResetFitness();  // 適合度リセット（１世代分の計算の前に必要）

                for (long lPtn = 0; lPtn < m_csMyInf.m_lEvPtnNum; lPtn++)
                {   // 入力パターン数繰り返す
                    csSimulationTime.SetTime(m_csMyInf.m_csEVStartTime[lPtn]); // パターン毎のシミュレーション開始時刻設定

                    this.InitModel(lPtn);  // モデルの初期化
                    for( long lEvlLp=0;lEvlLp<100000000;lEvlLp++)
                    {   // 進化計算（実質∞ループ）
                        if (csSimulationTime.After(m_csMyInf.m_csEVEndTime[lPtn]) == true)
                        {   // 予定した時刻まで計算したら
                            break;
                        }
                        m_csElmNode = m_csElementList.First;
                        for (iLp = m_iNodeItemNo; iLp < iElmCnt; iLp++)
                        {   // 個数分繰り返す
                            m_csElementWork = m_csElmNode.Value;    // エレメント取得
                            csGrElementWork = m_csElementWork as McGrElement;

                            // 各要素に演算時刻を設定する
                            csNextTargetTime.SetTime(csSimulationTime.GetTime() + m_csMyInf.m_csEVDltTime[lPtn].GetTime());
                            if (csGrElementWork == null && csNextTargetTime.Before(m_csMyInf.m_csEVEndTime[lPtn]) != true)
                            {
                                // 単体要素で次の演算目標時刻がシミュレーション終了時刻を越えていれば
                                //m_csElementWork.SetTargetTime(m_csFinalTgtTime);
                                m_csElementWork.SetTargetTime(m_csMyInf.m_csEVEndTime[lPtn]);
                            }
                            else
                            {
                                // Gr要素の場合は、終了時刻超過の確認はMcGrElementCtlで行われる
                                m_csElementWork.SetNextTargetTime(ref csSimulationTime, ref m_csDltTime);
                            }
                            // 2-2-4 一個の要素について演算を行う
                            for (iLoop = 0; iLoop < 1000000; iLoop++)
                            {   // 実質的∞：永遠に応答無しを防ぐ為、有限回に設定

                                // 2-2-4-1 個別要素の収束判別
                                if (m_csElementWork.IsConverged() == true)
                                {   // 収束していれば
                                    break;
                                    // 次の要素の演算へ移行
                                }

                                // 2-2-4-2 個別要素の演算計算
                                lLclRtn = m_csElementWork.Calculate(); // 内部の此処の要素に対して計算を行わせる
                                if (lLclRtn != McDefine.CALCULATION_NORMAL_RETURN)
                                {   // エラー有りならば
                                    lRtn = McDefine.CALCULATION_ABEND_RETURN;  // 全体の戻り値もエラー
                                    break;
                                }
                                // 2-2-4-3 個別要素の時刻を進める
                                m_csElementWork.GainSimulationTime(); // 要素内の時刻を進める

                                if (m_eDtFusionTiming == McDefine.DataFusionTiming.ASYNCHRONOUS)
                                {   // 非同期通信ならば
                                    lLclRtn = m_csElementWork.DataFusion();   // 演算結果公開(此処でDataFusionするとelementのδT が小さいときには非常に多くの情報が蓄積される)
                                    if (lLclRtn != 0)
                                    {
                                        lRtn = McDefine.CALCULATION_ABEND_RETURN;
                                        break;
                                    }
                                }
                            }   // end of for(∞)

                            if (lRtn != McDefine.CALCULATION_NORMAL_RETURN) { break; }
                            m_csElmNode = m_csElmNode.Next;
                        } // end of for(要素数)
                        if (lRtn != McDefine.CALCULATION_NORMAL_RETURN) { break; }

                        if (m_eDtFusionTiming == McDefine.DataFusionTiming.SYNCHRONOUS)
                        {   // 同期通信ならば
                            // 内部演算要素同士ののデータ交換
                            m_csElmNode = m_csElementList.First;
                            for (iLp = m_iNodeItemNo; iLp < iElmCnt; iLp++)
                            {   // 個数分繰り返す
                                m_csElementWork = m_csElmNode.Value;    // エレメント取得

                                m_csElementWork.DataFusion();   // 演算結果公開

                                m_csElmNode = m_csElmNode.Next;
                            } // end of for(要素数
                        }

                        csSimulationTime.Add(m_csMyInf.m_csEVDltTime[lPtn]);  // 系内の時刻を進める

                    } // end of 進化計算
                    if (lRtn != McDefine.CALCULATION_NORMAL_RETURN) { break; }

                    this.CompleteModel(lPtn);
                } // end of for(パターン)
                if (lRtn != McDefine.CALCULATION_NORMAL_RETURN) { break; }
                
                // １世代分の計算が終わったところで　交配が必要（計算してきた適合度に応じて子孫を残す）
                m_csEvlMdl.Breeding();

                m_csMyInf.m_lCalGeneration += 1; // 世代インクリメント
            }   // end of for(世代)

            return 0;
        }


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

        /// <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(McPropertyInfoRoot csCellMdlPropertyInfo)
        {
            bool bRtn = false;
            
            // プロパティ設定
            McCellModelPropertyInfo csPrptyInfo = csCellMdlPropertyInfo as McCellModelPropertyInfo;
            if (csPrptyInfo != null)
            {
                // 演算ステップ時刻設定
                this.m_csDltTime = new HySTime(csPrptyInfo.GetStepTime());

                bRtn = true;
                long lFlg = 0;
                csPrptyInfo.GetInfo("m_bEvCalMode", ref lFlg);
                if (lFlg == 0) { m_csMyInf.m_bEvCalMode = false; }
                else { m_csMyInf.m_bEvCalMode = true; }

                // 各種係数設定
                csPrptyInfo.GetInfo("m_lCreatureNum", ref m_csMyInf.m_lCreatureNum);
                csPrptyInfo.GetInfo("m_lEvGenerationNum", ref m_csMyInf.m_lEvGenerationNum);
                //csPrptyInfo.GetInfo("m_csEVPatternDefFileName", ref m_csMyInf.m_csEVPatternDefFileName);
                string sEvPtnFile = "";
                csPrptyInfo.GetInfo("m_csEVPatternDefFileName", ref sEvPtnFile);
                m_csMyInf.m_csEVPatternDefFileName = csPrptyInfo.GetProjectGroupDirectory().ToString() + "\\" + sEvPtnFile;

                // 進化用入力パターン読み込み
                this.ReadEvPattern();

                csPrptyInfo.GetInfo("m_csEVInputCalElmName", ref m_csMyInf.m_csEVInputCalElmName);
                csPrptyInfo.GetInfo("m_csEVRefCalElmName", ref m_csMyInf.m_csEVRefCalElmName);
                csPrptyInfo.GetInfo("m_csEvolutionMdlName", ref m_csMyInf.m_csEvolutionMdlName);

                csPrptyInfo.GetInfo("m_lCalElmNumber", ref m_csMyInf.m_lCalElmNumber);
                csPrptyInfo.GetInfo("m_lCelDivNumber", ref m_csMyInf.m_lCelDivNumber);

                //固体数
                m_csMyInf.m_csChromosome = new GAChromosomeSample[m_csMyInf.m_lCreatureNum];
                for( long lLp=0;lLp<m_csMyInf.m_lCreatureNum;lLp++)
                {
                    m_csMyInf.m_csChromosome[lLp] = new GAChromosomeSample();// 伝子情報を保持する染色体クラス生成
                    m_csMyInf.m_csChromosome[lLp].SetBoxNum(m_csMyInf.m_lCalElmNumber);
                    m_csMyInf.m_csChromosome[lLp].SetCelDivNumber(m_csMyInf.m_lCelDivNumber);
                }

            }
            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()
        {

            long lCalCnt = (long)((this.m_csFinalTgtTime.GetTime() - this.m_csStartTime.GetTime()) / this.m_csDltTime.GetTime());
            m_csMyInf.m_lGnrtnInclNum = (long)( m_csMyInf.m_lEvGenerationNum / lCalCnt)+1;
            if (m_csMyInf.m_lGnrtnInclNum < 1) { m_csMyInf.m_lGnrtnInclNum = 1; }

            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><para>method outline:</para>
        /// <para>進化処理に使用する各種データファイル読込</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = ReadEvPattern( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// 進化させる為に、進化の方向を示す為の参照データを読み込む
        /// </para>
        /// </remarks>
        protected bool ReadEvPattern()
        {
            bool bRtn = false;
            //m_csMyInf.m_csEVPatternDefFileName
             
            HySFile csPtnFile = new HySFile(m_csMyInf.m_csEVPatternDefFileName);
            if (csPtnFile.Exist() == false)
            {
                return bRtn;
            }
            HySXmlReader csXmlRead = new HySXmlReader(m_csMyInf.m_csEVPatternDefFileName);
            // ルート
            HySXmlNode csXmlRoot = csXmlRead.GetRootNode();
            HySXmlNodeList csXmlLst = csXmlRoot.GetChildNodeListByTagName("Pattern");
            m_csMyInf.m_lEvPtnNum = csXmlLst.GetCount();
            if (m_csMyInf.m_lEvPtnNum < 1)
            {
                return bRtn;
            }
            m_csMyInf.m_csEVStartTime = new HySTime[m_csMyInf.m_lEvPtnNum];
            m_csMyInf.m_csEVEndTime = new HySTime[m_csMyInf.m_lEvPtnNum];
            m_csMyInf.m_csEVDltTime = new HySTime[m_csMyInf.m_lEvPtnNum];
            m_csMyInf.m_csEVInputFileName = new HySString[m_csMyInf.m_lEvPtnNum];
            m_csMyInf.m_csEVRefFileName = new HySString[m_csMyInf.m_lEvPtnNum];
            HySXmlNode csXmlNode;
            HySXmlNodeList csXmlLstChild;
            HySXmlNode csXmlNodeChild;
            String sAttrb;
            for (long lLp = 0; lLp < m_csMyInf.m_lEvPtnNum; lLp++)
            {
                csXmlNode = csXmlLst.GetNode(lLp);
                csXmlLstChild = csXmlNode.GetChildNodeListByTagName("Time");
                csXmlNodeChild = csXmlLstChild.GetNode(0);
                sAttrb = csXmlNodeChild.GetAttribute("start");
                m_csMyInf.m_csEVStartTime[lLp] = HySCalendar.CreateTime(sAttrb);
                sAttrb = csXmlNodeChild.GetAttribute("goal");
                m_csMyInf.m_csEVEndTime[lLp] = HySCalendar.CreateTime(sAttrb);
                sAttrb = csXmlNodeChild.GetAttribute("delta");
                m_csMyInf.m_csEVDltTime[lLp] = new HySTime(double.Parse(sAttrb));

                csXmlLstChild = csXmlNode.GetChildNodeListByTagName("InputData");
                csXmlNodeChild = csXmlLstChild.GetNode(0);
                sAttrb = csXmlNodeChild.GetAttribute("FileName");
                //m_csMyInf.m_csEVInputFileName[lLp] = new HySString(sAttrb);  // パスが必要
                m_csMyInf.m_csEVInputFileName[lLp] = this.GetProjectGroupDirectory() +  new HySString("\\"+sAttrb);  // パスが必要

                csXmlLstChild = csXmlNode.GetChildNodeListByTagName("RefData");
                csXmlNodeChild = csXmlLstChild.GetNode(0);
                sAttrb = csXmlNodeChild.GetAttribute("FileName");
                //m_csMyInf.m_csEVRefFileName[lLp] = new HySString(sAttrb);  // パスが必要
                m_csMyInf.m_csEVRefFileName[lLp] = this.GetProjectGroupDirectory() + new HySString("\\" + sAttrb);  // パスが必要
            }

            bRtn = true;
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>名称で指定した要素モデルインスタンスを取得する</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>McCalModel csObj = GetModel(csElmName)</para>
        /// </example>
        /// <param name="csElmName">名称</param>
        /// <returns>McCalModel　内部の要素モデルインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>内部に含まれる要素モデルの名称はユニークである必要がある</para>
        /// </remarks>
        protected McCalModel GetModel(HySString csElmName)
        {
            McCalModel csRtn = null;

            int iElmNum = m_csElementList.Count;
            LinkedListNode<McElement> csElmNode = null;
            McCmnElement csElm = null;

            csElmNode= m_csElementList.First;

            for (int iLp = 0; iLp < iElmNum; iLp++)
            {
                csElm = csElmNode.Value as McCmnElement;
                if (csElmName.Equal(csElm.GetElementName()) == true)
                {
                    csRtn = csElm.GetCalModel();
                    break;
                }
                csElmNode = csElmNode.Next;
            }
            return csRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>指定した学習パターンでモデルを初期化</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = InitModel(lPrnNo)</para>
        /// </example>
        /// <param name="lPrnNo">パターン番号</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// 進化させる為に、進化の方向を示す為の参照データを指定してモデルを初期化する
        /// </para>
        /// </remarks>
        protected bool InitModel(long lPrnNo)
        {
            bool bRtn = true;
            bool bLclRtn = true;
            LinkedListNode<McElement> csElmNode = null;
            McElement csElementWork = null;

            m_csEVInputMdl.SetReadFileNameWithPath(m_csMyInf.m_csEVInputFileName[lPrnNo].ToString());
            m_csEVRefMdl.SetReadFileNameWithPath(m_csMyInf.m_csEVRefFileName[lPrnNo].ToString());
            int iElmCnt = m_csElementList.Count;
            csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElementWork = csElmNode.Value;

                csElementWork.SetSimulationTime(m_csMyInf.m_csEVStartTime[lPrnNo]); // シミュレーション時刻設定
                csElementWork.SetSimuGoalTime(m_csMyInf.m_csEVEndTime[lPrnNo]);
                bLclRtn = csElementWork.SimInitialize();

                csElmNode = csElmNode.Next;
            }
            csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElementWork = csElmNode.Value;

                bLclRtn = csElementWork.ReadyCalculation();

                csElmNode = csElmNode.Next;
            }
            return bRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>指定した学習パターンでの進化計算が終了したことを通知</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>bool bRtn = CompleteModel(lPrnNo)</para>
        /// </example>
        /// <param name="lPrnNo">パターン番号</param>
        /// <returns>true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// 進化させる為に、指定した　進化の方向を示す為の参照データの進化計算が終了した事を書く要素に通知する
        /// 各要素では、CompleteCalculation()メソッドがコールされる
        /// </para>
        /// </remarks>
        protected bool CompleteModel(long lPrnNo)
        {
            bool bRtn = true;
            bool bLclRtn = true;
            LinkedListNode<McElement> csElmNode = null;
            McElement csElementWork = null;

            int iElmCnt = m_csElementList.Count;
            csElmNode = m_csElementList.First;
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElementWork = csElmNode.Value;

                bLclRtn = csElementWork.CompleteCalculation();

                csElmNode = csElmNode.Next;
            }

            return bRtn;
        }
    }
    //
}
