GAの生成

Namespace: fvalgcli
Assembly: fvalgcli (in fvalgcli.dll) Version: 3.1.0.0 (3.1.0.11)

Syntax

C#
public static FHANDLE fnFIE_ga_open(
	f_ga_type gene_type,
	int gene_num,
	int chrom_num,
	F_GA_RANGE_PTR range,
	f_ga_select select,
	f_ga_cross crossover,
	double cross_rate,
	double mutat_rate,
	f_ga_alter alternate,
	F_GA_FUNC cost_func,
	f_ga_end rnd_cond,
	double thresh,
	int max_alter_cnt
)
Visual Basic
Public Shared Function fnFIE_ga_open ( 
	gene_type As f_ga_type,
	gene_num As Integer,
	chrom_num As Integer,
	range As F_GA_RANGE_PTR,
	select As f_ga_select,
	crossover As f_ga_cross,
	cross_rate As Double,
	mutat_rate As Double,
	alternate As f_ga_alter,
	cost_func As F_GA_FUNC,
	rnd_cond As f_ga_end,
	thresh As Double,
	max_alter_cnt As Integer
) As FHANDLE

Parameters

gene_type
Type: fvalgcli..::..f_ga_type
遺伝子の型を指定します。以下の内から指定してください。
  • F_GA_INT_TYPE 整数型
  • F_GA_FLOAT_TYPE 浮動小数点型
  • F_GA_ORDER_TYPE 順序型
gene_num
Type: System..::..Int32
1染色体当たりの遺伝子の個数(1以上)
chrom_num
Type: System..::..Int32
集団内の染色体数(偶数のみ)
range
Type: fvalgcli..::..F_GA_RANGE_PTR
遺伝子の値のレンジの配列。 gene_num で指定した個数分の遺伝子毎に、全て範囲を指定します。 gene_num の要素を確保した配列を渡してください。 ただし、 gene_type が F_GA_ORDER_TYPE の場合にはこの値は使用されません。
select
Type: fvalgcli..::..f_ga_select
選択淘汰の方式。 選択淘汰とは、適応度の高い染色体がより多くの子孫を残すための方法です。 以下の内から選択してください。
  • F_GA_PROPORT_SELECT 適応度比例戦略:各染色体の適応度に比例した確率で子孫を残すことができます
  • F_GA_EXPECT_SELECT 期待値戦略:各染色体の適応度に比例した確率で 子孫を残すことができるという点では「適応度比例」と同じですが、 1回選択されると次からはその確率を1/2にしてしまいます
  • F_GA_RANK_SELECT ランク戦略:各染色体の適応度によって、 染色体を1番から番号付けしてその順位に対して決められた確率で子孫を残します
  • F_GA_RANDOM_SELECT ランダム戦略: 乱数により選択します
crossover
Type: fvalgcli..::..f_ga_cross
交叉の方式。 交叉とは、選択された染色体の中から2つの染色体を使ってランダムな位置で部分的な入れ替えを行う方法です。 以下の内から選択して指定してください。
  • F_GA_ONE_POINT_CROSS 1点交叉:2つの染色体の遺伝子を、 ランダムに選択された点の後部で交換させて2つの子を作ります
  • F_GA_TWO_POINT_CROSS 2点交叉:2つの染色体の遺伝子を、 ランダムに選択された点の2点の間で交換させて2つの子を作ります。
  • F_GA_UNIFORM_CROSS 一様交叉:一様交叉 2つの染色体の遺伝子を、 各遺伝子ごとにランダムに交換させて2つの子を作ります。
  • F_GA_PARTIAL_CROSS 部分一致交叉:交叉位置と長さをランダムに選択し、 一方の親の選択された位置における遺伝子情報の順序をもう一方の親の対応する遺伝子情報と交換します。
gene_type の指定によって、選択できるパラメータが異なります。 遺伝子の型が整数型( F_GA_INT_TYPE )、浮動小数点型( F_GA_FLOAT_TYPE )の場合には F_GA_ONE_POINT_CROSS , F_GA_TWO_POINT_CROSS , F_GA_UNIFORM_CROSS が指定できます。 遺伝子の型が順序型( F_GA_ORDER_TYPE ) の場合には、 F_GA_PARTICAL_CROSS が指定できます。
cross_rate
Type: System..::..Double
交叉率(0.0〜1.0) 交叉率とは、交叉を生じさせる確率です。 0では交叉を行いませんし、1では必ず交叉を行います。0.9程度が一般的です。
mutat_rate
Type: System..::..Double
突然変異率(0.0〜1.0) 突然変異率とは、ランダムに選び出された染色体の遺伝子を強制的に他の値に変えてしまう比率のことです。 0では突然変異を行いませんし、1では必ず突然変異を行います。 0.03〜0.05程度が一般的です。
alternate
Type: fvalgcli..::..f_ga_alter
世代交代の方式 世代交代とは、「選択淘汰→交叉→突然変異」と遷移して生成された子の染色体集団を、 次の世代の親の染色体集団へ移行させる際の方式のことです。 次の内から選んで指定してください。
  • F_GA_NORMAL_ALTERNATE 通常戦略:子の染色体集団を そのまま新しい世代の親の染色体集団とします。
  • F_GA_ELITE_ALTERNATE エリート戦略:子の染色体集団の中の最小適応度を持つ染色体を、 親の染色体集団の中の最大適応度を持つ染色体と入れ替えます。
  • F_GA_MERGE_ALTERNATE マージ戦略:親の染色体集団と子の染色体集団とを合わせた集団の中から適応度の高い順に次の世代とします。
cost_func
Type: fvalgcli..::..F_GA_FUNC
適用度を算出するコスト関数(評価関数)
rnd_cond
Type: fvalgcli..::..f_ga_end
世代交代(進化)の終了条件 次の内から選んで指定してください。
  • F_GA_MAX_FITNESS_END 最大適応度による
  • F_GA_MEAN_FITNESS_END 平均適応度による
  • F_GA_STAGNATION_END 世代交代の停滞による
  • F_GA_NO_CONDITION_END なし(世代交代の回数によるのみ)
thresh
Type: System..::..Double
終了判定のための閾値 rnd_cond にて指定した条件により、意味が変わります。
  • F_GA_MAX_FITNESS_END 集団内の染色体の最大適応度がこの値より大きくなったときに終了します。
  • F_GA_MEAN_FITNESS_END 集団内の染色体の平均適応度がこの値より大きくなったときに終了します。
  • F_GA_STAGNATION_END 集団内の染色体の最近10回以内の集団平均適応度の標準偏差がこの値より小さくなったときに終了します。
  • F_GA_NO_CONDITION_END 終了しません。( max_alter_cnt パラメータの値で強制的に終了させるときにこれを使います。)
max_alter_cnt
Type: System..::..Int32
最大世代交代数 終了条件を満たさないときでも、この値分の世代交代(進化)を行ってから処理を終了します。

Return Value

Type: FHANDLE
正常に終了した場合は、GAのハンドルを返します。 ライセンスエラー、メモリ不足、またはパラメータ不正により異常終了した場合には、IntPtr.Zero を返します。

Remarks

Examples

C# Copy imageCopy
//    $Revision: 1.1 $

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

namespace TC
{
    public partial class FIE
    {
        [FvPluginExecute]
        public void fnFIE_ga_open()
        {
            int status = (int)fvalgcli.f_err.F_ERR_NONE;

            FHANDLE hGa = FHANDLE.Zero;                            // Descriptor of GA
            F_GA_RANGE_PTR taGeneRange = F_GA_RANGE_PTR.Zero;    // Range of value for every gene    
            INT_PTR iaChrom = INT_PTR.Zero;                        // Essence of chromosome
            DOUBLE_PTR daFitness = DOUBLE_PTR.Zero;                // Fitness
            PNT_T_PTR taCoord = PNT_T_PTR.Zero;                    // Set of coordinates   (positions of cities)

            double dExpArrage = 0.75;        // Expected fitness value (>0.75)

            const int GENE_N = 20;            // Maximal number of genes
            const int PICK_N = 3;            // Number of chrosomoses picked out

            try
            {
                // allocate memory    
                taGeneRange = F_GA_RANGE_PTR.alloc(GENE_N);
                iaChrom = INT_PTR.alloc(PICK_N * GENE_N);
                daFitness = DOUBLE_PTR.alloc(PICK_N);
                taCoord = PNT_T_PTR.alloc(GENE_N);

                /*****    Parameters of GA function    *****/
                int iGeneNum = GENE_N;
                int iMaxAlterCnt = 1000;
                f_ga_type tGeneType = f_ga_type.F_GA_ORDER_TYPE;
                for (int i = 0; i < iGeneNum; i++)
                {
                    F_GA_VALUE ga_min = F_GA_VALUE.init(0);
                    F_GA_VALUE ga_max = F_GA_VALUE.init(0);
                    taGeneRange[i] = F_GA_RANGE.init(ga_min, ga_max);
                }

                /* Cost function    */
                F_GA_FUNC fpCostFunc = cost_func;    // Cost function

                /* Set the fixed value      */
                int iChromNum = 200;                                        /* Number of chromosomes        */
                f_ga_select tSelect = f_ga_select.F_GA_PROPORT_SELECT;        /* Method of seletion            */
                f_ga_cross tCrossover = f_ga_cross.F_GA_PARTIAL_CROSS;        /* Method of crossover            */
                double dCrossRate = 0.9;                                    /* Rate of crossover            */
                double dMutatRate = 0.05;                                    /* Rate of mutation                */
                f_ga_alter tAlternate = f_ga_alter.F_GA_ELITE_ALTERNATE;    /* Method of alternation        */
                f_ga_end tEndCond = f_ga_end.F_GA_NO_CONDITION_END;            /* End condition                  */
                double dThresh = 0.001;                                        /* Threshold of end condition   */

                /* Create the coordinates of positions */
                for (int i = 0; i < iGeneNum; i++)
                    taCoord[i] = PNT_T.init(20*i+5, i);

                // generate table of distance
                generate_table( iGeneNum, taCoord );

                /****** GA Test begin ******/

                /* GA open */
                hGa = api.fnFIE_ga_open( tGeneType, iGeneNum, iChromNum, taGeneRange, tSelect, tCrossover,
                                      dCrossRate, dMutatRate, tAlternate, fpCostFunc, tEndCond, dThresh, iMaxAlterCnt );
                Assert.IsTrue(hGa != FHANDLE.Zero, "エラーが発生しました。");

                m_dMaxFitness = 0.0;

                /* GA execute */
                int iRet = 0;
                status = api.fnFIE_ga_execute(hGa, PICK_N, iaChrom, daFitness, ref iRet);
                Assert.IsTrue(status == (int)f_err.F_ERR_NONE, "エラーが発生しました。({0})", (f_err)status);

                for ( int i = 0; i < PICK_N; i++ )
                {
                    if ( daFitness[i] < dExpArrage )
                    {
                        Assert.Fail("エラーが発生しました。(daFitness[{0}]={1})", i, daFitness[i]);
                    }
                }
            }
            finally
            {
                hGa.Dispose();
                taGeneRange.Dispose();
                iaChrom.Dispose();
                daFitness.Dispose();
                taCoord.Dispose();
            }
        }

        /// <summary>
        /// Cost function of genetic algorithm
        /// </summary>
        /// <param name="tGeneType">Type of gene</param>
        /// <param name="iGeneNum">Number of gene</param>
        /// <param name="vpChrom">Descriptor of chromosome</param>
        /// <returns>
        /// </returns>
        private static double cost_func(f_ga_type tGeneType, int iGeneNum, IntPtr vpChrom)
        {
            double dFitness, dMax, dLength;
            int iLength = 0;
            INT_PTR iaChrom = vpChrom;

            for (int i = 0; i < iGeneNum; i++)
                iLength += m_waLength[iaChrom[i],iaChrom[(i+1)%iGeneNum]];

            dLength = (double)iLength;
            dMax = (double)(iGeneNum * 500);

            if( dMax < dLength )
                dFitness = 0.0;
            else
                dFitness = 1.0 - dLength / dMax;

            if( m_dMaxFitness < dFitness )
                m_dMaxFitness = dFitness;

            return dFitness;
        }

        /// <summary>
        /// Table of distance  (distance of cities)
        /// </summary>
        private static int[,] m_waLength = new int[20, 20];

        /// <summary>
        /// Maximal value of fitness
        /// </summary>
        private static double m_dMaxFitness = 0.0;

        /// <summary>
        /// Generate the distance table
        /// </summary>
        /// <param name="iDataNum">Input data num</param>
        /// <param name="taCoord">Coordinate of point</param>
        private static void generate_table(int iDataNum, PNT_T_PTR taCoord)
        {
            for( int i = 0; i < iDataNum; i++ )
                for( int j = 0; j < iDataNum; j++ )
                    m_waLength[i, j] = calc_length(taCoord[i].x, taCoord[i].y, taCoord[j].x, taCoord[j].y);
        }

        /// <summary>
        /// Calculate the diatance of two points
        /// </summary>
        /// <param name="iXs">X-coordinate of start point</param>
        /// <param name="iYs">Y-coordinate of start point</param>
        /// <param name="iXe">X-coordinate of end point</param>
        /// <param name="iYe">Y-coordinate of end point</param>
        /// <returns>
        /// </returns>
        private static int calc_length(int iXs, int iYs, int iXe, int iYe)
        {
            int iXd = iXe - iXs + 1;
            int iYd = iYe - iYs + 1;
            return ((int)System.Math.Sqrt((double)(iXd * iXd + iYd * iYd)));
        }
    }
}


Visual Basic Copy imageCopy
'    $Revision: 1.1 $

Imports System.Collections.Generic
Imports System.Text
Imports fvalgcli

Public Partial Class FIE
    <FvPluginExecute> _
    Public Sub fnFIE_ga_open()
        Dim status As Integer = CInt(fvalgcli.f_err.F_ERR_NONE)

        Dim hGa As FHANDLE = FHANDLE.Zero
        ' Descriptor of GA
        Dim taGeneRange As F_GA_RANGE_PTR = F_GA_RANGE_PTR.Zero
        ' Range of value for every gene    
        Dim iaChrom As INT_PTR = INT_PTR.Zero
        ' Essence of chromosome
        Dim daFitness As DOUBLE_PTR = DOUBLE_PTR.Zero
        ' Fitness
        Dim taCoord As PNT_T_PTR = PNT_T_PTR.Zero
        ' Set of coordinates   (positions of cities)
        Dim dExpArrage As Double = 0.75
        ' Expected fitness value (>0.75)
        Const  GENE_N As Integer = 20
        ' Maximal number of genes
        Const  PICK_N As Integer = 3
        ' Number of chrosomoses picked out
        Try
            ' allocate memory    
            taGeneRange = F_GA_RANGE_PTR.alloc(GENE_N)
            iaChrom = INT_PTR.alloc(PICK_N * GENE_N)
            daFitness = DOUBLE_PTR.alloc(PICK_N)
            taCoord = PNT_T_PTR.alloc(GENE_N)

            '****    Parameters of GA function    ****

            Dim iGeneNum As Integer = GENE_N
            Dim iMaxAlterCnt As Integer = 1000
            Dim tGeneType As f_ga_type = f_ga_type.F_GA_ORDER_TYPE
            For i As Integer = 0 To iGeneNum - 1
                Dim ga_min As F_GA_VALUE = F_GA_VALUE.init(0)
                Dim ga_max As F_GA_VALUE = F_GA_VALUE.init(0)
                taGeneRange(i) = F_GA_RANGE.init(ga_min, ga_max)
            Next

            ' Cost function    

            Dim fpCostFunc As F_GA_FUNC = AddressOf cost_func
            ' Cost function
            ' Set the fixed value      

            Dim iChromNum As Integer = 200
            ' Number of chromosomes        
            Dim tSelect As f_ga_select = f_ga_select.F_GA_PROPORT_SELECT
            ' Method of seletion            
            Dim tCrossover As f_ga_cross = f_ga_cross.F_GA_PARTIAL_CROSS
            ' Method of crossover            
            Dim dCrossRate As Double = 0.9
            ' Rate of crossover            
            Dim dMutatRate As Double = 0.05
            ' Rate of mutation                
            Dim tAlternate As f_ga_alter = f_ga_alter.F_GA_ELITE_ALTERNATE
            ' Method of alternation        
            Dim tEndCond As f_ga_end = f_ga_end.F_GA_NO_CONDITION_END
            ' End condition                  
            Dim dThresh As Double = 0.001
            ' Threshold of end condition   

            ' Create the coordinates of positions 

            For i As Integer = 0 To iGeneNum - 1
                taCoord(i) = PNT_T.init(20 * i + 5, i)
            Next

            ' generate table of distance
            generate_table(iGeneNum, taCoord)

            '***** GA Test begin *****


            ' GA open 

            hGa = api.fnFIE_ga_open(tGeneType, iGeneNum, iChromNum, taGeneRange, tSelect, tCrossover, _
                dCrossRate, dMutatRate, tAlternate, fpCostFunc, tEndCond, dThresh, _
                iMaxAlterCnt)
            Assert.IsTrue(hGa <> FHANDLE.Zero, "エラーが発生しました。")

            m_dMaxFitness = 0.0

            ' GA execute 

            Dim iRet As Integer = 0
            status = api.fnFIE_ga_execute(hGa, PICK_N, iaChrom, daFitness, iRet)
            Assert.IsTrue(status = CInt(f_err.F_ERR_NONE), "エラーが発生しました。({0})", CType(status, f_err))

            For i As Integer = 0 To PICK_N - 1
                If daFitness(i) < dExpArrage Then
                    Assert.Fail("エラーが発生しました。(daFitness[{0}]={1})", i, daFitness(i))
                End If
            Next
        Finally
            hGa.Dispose()
            taGeneRange.Dispose()
            iaChrom.Dispose()
            daFitness.Dispose()
            taCoord.Dispose()
        End Try
    End Sub

    ''' <summary>
    ''' Cost function of genetic algorithm
    ''' </summary>
    ''' <param name="tGeneType">Type of gene</param>
    ''' <param name="iGeneNum">Number of gene</param>
    ''' <param name="vpChrom">Descriptor of chromosome</param>
    ''' <returns>
    ''' </returns>
    Private Shared Function cost_func(tGeneType As f_ga_type, iGeneNum As Integer, vpChrom As IntPtr) As Double
        Dim dFitness As Double, dMax As Double, dLength As Double
        Dim iLength As Integer = 0
        Dim iaChrom As INT_PTR = vpChrom

        For i As Integer = 0 To iGeneNum - 1
            iLength += m_waLength(iaChrom(i), iaChrom((i + 1) Mod iGeneNum))
        Next

        dLength = CDbl(iLength)
        dMax = CDbl(iGeneNum * 500)

        If dMax < dLength Then
            dFitness = 0.0
        Else
            dFitness = 1.0 - dLength / dMax
        End If

        If m_dMaxFitness < dFitness Then
            m_dMaxFitness = dFitness
        End If

        Return dFitness
    End Function

    ''' <summary>
    ''' Table of distance  (distance of cities)
    ''' </summary>
    Private Shared m_waLength As Integer(,) = New Integer(19, 19) {}

    ''' <summary>
    ''' Maximal value of fitness
    ''' </summary>
    Private Shared m_dMaxFitness As Double = 0.0

    ''' <summary>
    ''' Generate the distance table
    ''' </summary>
    ''' <param name="iDataNum">Input data num</param>
    ''' <param name="taCoord">Coordinate of point</param>
    Private Shared Sub generate_table(iDataNum As Integer, taCoord As PNT_T_PTR)
        For i As Integer = 0 To iDataNum - 1
            For j As Integer = 0 To iDataNum - 1
                m_waLength(i, j) = calc_length(taCoord(i).x, taCoord(i).y, taCoord(j).x, taCoord(j).y)
            Next
        Next
    End Sub

    ''' <summary>
    ''' Calculate the diatance of two points
    ''' </summary>
    ''' <param name="iXs">X-coordinate of start point</param>
    ''' <param name="iYs">Y-coordinate of start point</param>
    ''' <param name="iXe">X-coordinate of end point</param>
    ''' <param name="iYe">Y-coordinate of end point</param>
    ''' <returns>
    ''' </returns>
    Private Shared Function calc_length(iXs As Integer, iYs As Integer, iXe As Integer, iYe As Integer) As Integer
        Dim iXd As Integer = iXe - iXs + 1
        Dim iYd As Integer = iYe - iYs + 1
        Return CInt(Math.Truncate(System.Math.Sqrt(CDbl(iXd * iXd + iYd * iYd))))
    End Function
End Class

See Also