<?
php
class GA{
public static $length ;
public static $count;
public static $population;
/**
* GA constructor.
* @param $length
* @param $count
* 长度
* 生成的数量
*/
public function __construct(
$length,
$count){
self::
$length =
$length;
self::
$count =
$count;
self::
$population = self::gen_population(
$length,
$count);
}
public static function gen_population(
$length,
$count){
$population =
[];
for(
$i=0;
$i<
$count;
$i++
){
$population[] = self::gen_chromosome(
$length);
}
return $population;
}
public static function gen_chromosome(
$length){
$str = 0
;
for(
$i=0;
$i<
$length;
$i++
){
$str |=(1<<
$i)*
mt_rand(0,1
);
}
return $str;
}
/**
* @param float $retain_rate
* @param float $random_select_rate
* @param float $mutation_rate
* 进化
*/
public function evolve(
$retain_rate = 0.2,
$random_select_rate = 0.5,
$mutation_rate = 0.01
){
$parents = self::selection(
$retain_rate,
$random_select_rate);
self::crossover(
$parents);
self::mutation(
$mutation_rate);
}
/**
* @param $retain_rate
* @param $random_select_rate
* @return array
* 选择
*/
public static function selection(
$retain_rate,
$random_select_rate){
$graded =
[];
foreach(self::
$population as $v){
$graded[] = [self::fitness(
$v),
$v];
}
rsort(
$graded);
$graded = array_column(
$graded,1
);
$retain_length =
intval(
count(
$graded)*
$retain_rate);
$parents =
array_slice(
$graded,0,
$retain_length);
foreach(
array_slice(
$graded,
$retain_length,
count(
$graded)-
$retain_length)
as $v){
//lcg_value()随机生成0-1浮点数
if(
lcg_value() <
$random_select_rate){
$parents[] =
$v;
}
}
return $parents;
}
public static function fitness(
$chromosome){
$x = self::decode(
$chromosome);
return $x + 10*
sin(5*
$x) + 7*
cos(4*
$x);
}
public static function decode(
$chromosome){
return $chromosome * 9.0 / (
pow(2,self::
$length)-1
);
}
/**
* @param $parents
* 交叉
*染色体的交叉、繁殖,生成新一代的种群
*/
public static function crossover(
$parents){
//新出生的孩子,最终会被加入存活下来的父母之中,形成新一代的种群。
$children =
[];
//需要繁殖的孩子的量
$target_count =
count(self::
$population)-
count(
$parents);
while(
count(
$children) <
$target_count){
$male =
rand(0,
count(
$parents)-1
);
$female =
rand(0,
count(
$parents)-1
);
if(
$male !=
$female){
$cross_pos =
rand(0,self::
$length);
//生成掩码,方便位操作
$mask = 0
;
for(
$i=0;
$i<
$cross_pos;
$i++
){
$mask |= (1<<
$i);
}
$male =
$parents[
$male];
$female =
$parents[
$female];
$child = ((
$male &
$mask) | (
$female & ~
$mask)) & ((1<<self::
$length)-1
);
$children[] =
$child;
}
}
self::
$population =
array_merge(
$parents,
$children);
}
/**
* @param $rate
* 变异
* 对种群中的所有个体,随机改变某个个体中的某个基因
*/
public static function mutation(
$rate){
foreach(self::
$population as $k =>
$v){
if(
lcg_value() <
$rate){
$j =
rand(0,self::
$length-1
);
self::
$population[
$k] ^= 1 <<
$j;
}
}
}
public function result(){
foreach(self::
$population as $v){
$graded[] = [self::fitness(
$v),
$v];
}
rsort(
$graded);
$graded = array_column(
$graded,1
);
return self::decode(
$graded[0
]);
}
public static function println(
$data){
echo "<br>".
$data."<br>"
;
}
}
if(!
function_exists("array_column"
))
{
function array_column(
$array=
array(),
$value="",
$key="",
$key_prefix=""
)
{
//模拟实现PHP5.5的array_column
$list=
array();
//初始化返回数组
$is_need_all=
$value==="*";
//是否需要获取整个数组
$is_need_key=
$key!=="";
//是否需要key
if(
$is_need_key)
{
//说明有key 直接取当前遍历的 value 字段 或者当前遍历元素
$key=
$key_prefix.
$key;
//拼接前缀
foreach(
$array as $v)
{
$tmp=
$is_need_all ?
$v : (
isset(
$v[
$value])?
$v[
$value]:""
);
$list[
$v[
$key]]=
$tmp;
}
}
else
{
//说明没有key直接把数组元素返回到数组中去
foreach(
$array as $v)
{
$tmp=
$is_need_all ?
$v : (
isset(
$v[
$value])?
$v[
$value]:""
);
$list[]=
$tmp;
}
}
return $list;
}
}
$t1 =
microtime(
true);
$ga =
new GA(17,100
);
for(
$i=1;
$i<=100;
$i++
){
$ga->
evolve();
}
//var_dump($ga::$population);
echo $ga->result()."<br>"
;
$t =
microtime(
true)-
$t1;
echo "time:".
$t;
转载于:https://www.cnblogs.com/lizhaoyao/p/8602270.html
转载请注明原文地址: https://win8.8miu.com/read-1499740.html