遗传算法(GA)求解TSP问题(golang实现)
warning:
这篇文章距离上次修改已过188天,其中的内容可能已经有所变动。
package main
import (
"fmt"
"math/rand"
"time"
)
// 定义城市坐标结构体
type City struct {
x, y float64
}
// 定义遗传算法解决旅行商问题的结构体
type GA struct {
population [][]City
nextCity []City
best []City
fitness float64
size int
mutation float64
crossover float64
elitism bool
}
// 初始化遗传算法
func (ga *GA) Init(size int, mutation, crossover float64, elitism bool) {
ga.size = size
ga.mutation = mutation
ga.crossover = crossover
ga.elitism = elitism
ga.population = make([][]City, size)
ga.best = make([]City, len(cities))
for i := range ga.population {
ga.population[i] = make([]City, len(cities))
for j := range ga.population[i] {
ga.population[i][j] = cities[j]
}
rand.Shuffle(len(ga.population[i]), func(i, j int) {
ga.population[i][i], ga.population[i][j] = ga.population[i][j], ga.population[i][i]
})
}
}
// 计算适应度函数
func (ga *GA) Fitness() {
var total float64
for i := range ga.population {
var distance float64
for j := 1; j < len(ga.population[i]); j++ {
distance += Distance(ga.population[i][j-1], ga.population[i][j])
}
distance += Distance(ga.population[i][len(ga.population[i])-1], ga.population[i][0])
if distance < ga.fitness || ga.fitness == 0 {
copy(ga.best, ga.population[i])
ga.fitness = distance
}
total += distance
}
fmt.Println("Best fitness:", ga.fitness)
}
// 交叉操作
func (ga *GA) Crossover() {
for len(ga.population) < cap(ga.population) {
parent1 := rand.Intn(len(ga.population))
parent2 := rand.Intn(len(ga.population))
if rand.Float64() < ga.crossover {
crossPoint := rand.Intn(len(ga.population[parent1])-1) + 1
ga.population = append(ga.population, append(ga.population[parent1][crossPoint:], ga.population[parent2][:crossPoint]...))
}
}
}
// 变异操作
func (ga *GA) Mutation() {
for i := range ga.population {
for j := range ga.population[i] {
if rand.Float64() < ga.mutation {
rand.Shuffle(len(ga.population), func(i, j int) {
ga.population[i][j], ga.population[i][j] = ga.population[i][j], ga.population[i][i]
})
}
}
}
}
// 选择操作
func (ga *GA) Selection() {
newPopulation := make(
评论已关闭