const setting = {
length : 8,
count : 200,
}
var population = gen_population(setting.length, setting.count)
;(function () {
for (let i = 0; i < 200; i++) {
evolve()
}
let rst = result()
console.log(`
函数f(x)=xcosx的最优解为:${rst}
所取到的最大值为:${rst * Math.cos(rst)}
`)
})()
* 进化,对当前一代种群依次进行选择、交叉并生成新一代种群,然后对新一代种群进行变异
* @param {Number} param
* @return {String} return
*/
function evolve(retain_rate = 0.2, random_select_rate = 0.6, mutation_rate = 0.01) {
let parents = selection(retain_rate, random_select_rate)
crossover(parents)
mutation(mutation_rate)
}
* 随机生成长度为length的染色体,每个基因的取值是0或1,这里用一个bit表示一个基因
* @param {Number} length 随机生成长度为length的染色体
* @return {String} return 长度为length的染色体
*/
function gen_chromosome(length) {
let chromosome = 0
for (let i = 0; i <= length; i++)
chromosome |= (1 << i) * Math.random()
return chromosome
}
* 获取初始种群(一个含有count个长度为length的染色体的列表)
* @param {Number} length 长度为length的染色体
* @param {Number} count个染色体
* @return {String} return 染色体数组
*/
function gen_population(length, count) {
let population_array = []
for (let i = 0; i < count; i++)
population_array.push(gen_chromosome(length))
return population_array
}
* 计算适应值函数(也是我们需要求解的函数)
* @param {Number} x 自变量
* @return {String} 因变量
*/
function fitness(chromosome){
let x = decode(chromosome)
return x * Math.cos(x)
}
* 染色体选择
* @param {Number} param
* @return {String} return
*/
function selection(retain_rate, random_select_rate) {
let graded = []
for (let i of population) {
graded.push({
fitness: fitness(i),
chromosome: i
})
}
graded.sort( function(a, b){return b.fitness - a.fitness} )
for(let i = 0; i<graded.length; i++) {
graded[i] = graded[i].chromosome
}
let retain_length = Math.floor(graded.length * retain_rate)
let parents = graded.slice( 0, retain_length )
for (let i of graded.slice( retain_length, graded.length )) {
if (Math.random() < random_select_rate) {
parents.push(i)
}
}
return parents
}
* 染色体的交叉、繁殖,生成新一代的种群
* @param {Number} parents 父代
* @return {String} return
*/
function crossover(parents) {
let children = []
let children_num = population.length - parents.length
while (children.length < children_num) {
let male = Math.round( Math.random() * (parents.length - 1) )
let female = Math.round( Math.random() * (parents.length - 1) )
if (male != female) {
let cross_pos = Math.round( Math.random() * setting.length )
let mask = 0
for (let i = 0; i < cross_pos; i++) {
mask |= (1 << i)
}
male = parents[male]
female = parents[female]
let child = ((male & mask) | (female & ~mask)) & ((1 << setting.length) - 1)
children.push(child)
}
}
population = parents.concat(children)
}
* 变异,对种群中的所有个体,随机改变某个个体中的某个基因
* @param {Number} param
* @return {String} return
*/
function mutation(rate) {
for(let i = 0; i < population.length; i++) {
if (Math.random() < rate) {
let j = Math.round( Math.random() * (setting.length - 1) )
population[i] ^= 1 << j
}
}
}
* 解码染色体,将二进制转化为属于[0, pi/4]的实数
* @param {Number} chromosome
* @return {String} 属于[0, pi/4]的实数
*/
function decode(chromosome) {
return chromosome * (Math.PI / 4) / (2 ** setting.length - 1)
}
* 获得当前代的最优值,这里取的是函数取最大值时x的值。
* @param {Number} param
* @return {String} return
*/
function result() {
let graded = []
for (let i of population) {
graded.push({
fitness: fitness(i),
chromosome: i
})
}
graded.sort( function(a, b){return b.fitness - a.fitness} )
for(let i = 0; i<graded.length; i++) {
graded[i] = graded[i].chromosome
}
return decode(graded[0])
}