最近学习了一下遗传算法,于是参考了一篇论文,采用浮点数编码写了一个算法,运行了一下,发布收敛很慢,遗传了几百代与几十代相比,只是略显稳定,随机性比较强。而且容易限入局部极值中。例如,我以求函数xsin(10PI*x)+2.0为例,最大值大约在x=1.85附近,在x=1.65附近有一个局部极值。我写的算法大约70%的机会取得1.85附近的值,30%机会取得1.65附近的值。总之效果不理想。不知有没有朋友有兴趣帮我看一下。
初始化种群
public
List
<
PopUnit
>
InitPop()
{
if (CalculateFitnessHanler == null )
throw new Exception( " 未设置计算表达式的事件CalculateHanler " );
if (m_Parameters.PopSize <= 10 )
throw new Exception( " 种群数太小 " );
List < PopUnit > pool = new List < PopUnit > ();
for ( int i = 0 ; i <= m_Parameters.PopSize - 1 ; i ++ )
{
double d = m_Random.NextDouble();
d = m_Parameters.L + (m_Parameters.R - m_Parameters.L) * d;
double val = CalculateFitnessHanler( new double [] { d });
PopUnit unit = new PopUnit(d, val);
pool.Add(unit);
}
return pool;
}
{
if (CalculateFitnessHanler == null )
throw new Exception( " 未设置计算表达式的事件CalculateHanler " );
if (m_Parameters.PopSize <= 10 )
throw new Exception( " 种群数太小 " );
List < PopUnit > pool = new List < PopUnit > ();
for ( int i = 0 ; i <= m_Parameters.PopSize - 1 ; i ++ )
{
double d = m_Random.NextDouble();
d = m_Parameters.L + (m_Parameters.R - m_Parameters.L) * d;
double val = CalculateFitnessHanler( new double [] { d });
PopUnit unit = new PopUnit(d, val);
pool.Add(unit);
}
return pool;
}
选择操作
public
List
<
PopUnit
>
Select(List
<
PopUnit
>
data)
{
int dropoutCount = ( int )(m_Parameters.DropoutRate * data.Count);
List < PopUnit > newpool = new List < PopUnit > ();
for ( int i = 0 ; i <= dropoutCount - 1 ; i ++ )
{
newpool.Add(data[i].Clone() as PopUnit);
newpool.Add(data[i].Clone() as PopUnit);
}
int tmpCount = data.Count - newpool.Count;
for ( int i = dropoutCount; i <= dropoutCount + tmpCount - 1 ; i ++ )
{
newpool.Add(data[i].Clone() as PopUnit);
}
return newpool;
}
{
int dropoutCount = ( int )(m_Parameters.DropoutRate * data.Count);
List < PopUnit > newpool = new List < PopUnit > ();
for ( int i = 0 ; i <= dropoutCount - 1 ; i ++ )
{
newpool.Add(data[i].Clone() as PopUnit);
newpool.Add(data[i].Clone() as PopUnit);
}
int tmpCount = data.Count - newpool.Count;
for ( int i = dropoutCount; i <= dropoutCount + tmpCount - 1 ; i ++ )
{
newpool.Add(data[i].Clone() as PopUnit);
}
return newpool;
}
交叉操作:
public
void
CrossOver(
double
a,
double
b,
out
double
a1,
out
double
b1)
{
if (m_Random.NextDouble() > m_Parameters.CrossOverRate)
{
a1 = a;
b1 = b;
return ;
}
double r = 0.1 ;
double a2 = m_Random.NextDouble() * r;
double b2 = m_Random.NextDouble() * r;
a1 = ( 1 - a2) * a + b2 * b;
b1 = ( 1 - b2) * b + a2 * a;
if (a1 < m_Parameters.L)
a1 = m_Parameters.L;
if (b1 < m_Parameters.L)
b1 = m_Parameters.L;
if (a1 > m_Parameters.R)
a1 = m_Parameters.R;
if (b1 > m_Parameters.R)
b1 = m_Parameters.R;
// Console.WriteLine("crossover a1={0},b1={1} -> a2={2},b2={3}", a, b, a1, b1);
}
{
if (m_Random.NextDouble() > m_Parameters.CrossOverRate)
{
a1 = a;
b1 = b;
return ;
}
double r = 0.1 ;
double a2 = m_Random.NextDouble() * r;
double b2 = m_Random.NextDouble() * r;
a1 = ( 1 - a2) * a + b2 * b;
b1 = ( 1 - b2) * b + a2 * a;
if (a1 < m_Parameters.L)
a1 = m_Parameters.L;
if (b1 < m_Parameters.L)
b1 = m_Parameters.L;
if (a1 > m_Parameters.R)
a1 = m_Parameters.R;
if (b1 > m_Parameters.R)
b1 = m_Parameters.R;
// Console.WriteLine("crossover a1={0},b1={1} -> a2={2},b2={3}", a, b, a1, b1);
}
变异操作:
public
double
Mutation(
double
c)
{
double tmpd = m_Random.NextDouble();
if (tmpd > m_Parameters.MutateRate)
{
return c;
}
double k = 0.2 ;
// k = (m_Parameters.MaxGenerations-T)/ (m_Parameters.MaxGenerations + 2D) * 0.4D;
double res;
if (m_Random.Next( 2 ) == 1 )
{
res = c + k * (m_Parameters.R - c) * m_Random.NextDouble();
}
else
{
res = c - k * (c - m_Parameters.L) * m_Random.NextDouble();
}
// Console.WriteLine("mutation: {0} -> {1}", c, res);
return res;
}
{
double tmpd = m_Random.NextDouble();
if (tmpd > m_Parameters.MutateRate)
{
return c;
}
double k = 0.2 ;
// k = (m_Parameters.MaxGenerations-T)/ (m_Parameters.MaxGenerations + 2D) * 0.4D;
double res;
if (m_Random.Next( 2 ) == 1 )
{
res = c + k * (m_Parameters.R - c) * m_Random.NextDouble();
}
else
{
res = c - k * (c - m_Parameters.L) * m_Random.NextDouble();
}
// Console.WriteLine("mutation: {0} -> {1}", c, res);
return res;
}
种群大小=100,交叉概率=0.7,变异概率=0.1