유전 알고리즘 - 줄리아를 동반한 여행 세일즈맨
50409 단어 juliamachinelearningpythonbeginners
유전 알고리즘
유전 알고리즘(GA)은 자연 선택 과정에 의해 계발된 알고리즘으로 문제를 생성하는 고품질 해결 방안에 사용된다. 그렇지 않으면 이런 문제들은 해결하기 어려울 것이다.
여행 세일즈맨 문제
여행 세일즈맨 문제(TSP)는 악명 높은 문제로 여행 세일즈맨은 반드시 이미 알고 있는 거리의 각 도시를 여행하고 가능한 한 짧은 시간/경로 내에 출발 도시로 돌아가야 한다.
아래 그림에서 보듯이 모든 동그라미는 하나의 도시이고 푸른 선은 그것들을 참관하는 노선이다.
왜 폭력을 쓰지 않습니까?
좋아, 폭력으로 이 문제를 해결해 보자.
우선 5개 도시를 예로 들자. 즉, 우리는 5!
개 노선, 즉 120개 노선을 계산해서 우리가 가장 짧은 경로를 확보해야 한다.
지금 우리가 50
개 도시를 위해 이렇게 한다면,
여행 세일즈맨 문제(TSP)는 악명 높은 문제로 여행 세일즈맨은 반드시 이미 알고 있는 거리의 각 도시를 여행하고 가능한 한 짧은 시간/경로 내에 출발 도시로 돌아가야 한다.
아래 그림에서 보듯이 모든 동그라미는 하나의 도시이고 푸른 선은 그것들을 참관하는 노선이다.
왜 폭력을 쓰지 않습니까?
좋아, 폭력으로 이 문제를 해결해 보자.
우선 5개 도시를 예로 들자. 즉, 우리는
5!
개 노선, 즉 120개 노선을 계산해서 우리가 가장 짧은 경로를 확보해야 한다.지금 우리가
50
개 도시를 위해 이렇게 한다면,5!
= 120 10!
= 3628800 15!
= 1307674368000 20!
= 2432902008176640000 50!
= 30414093201713378043612608166064768844377641568960512000000000000 우리 한번 해보자.
따라서 우리는
Genetic Algorithm
이 우리가 가장 짧은 경로를 찾을 수 있도록 어떻게 도와주는지 보게 될 것이다.간단하게 말하면 유전 알고리즘의 작업 원리는 다음과 같다.
Initial Population
또는 염색체라고 함) crossover
(혼합 쌍둥이 염색체/용액을 통해 새로운 용액 또는 염색체 생성) mutate
(작은 솔루션 변경) fitness
(해결 방안이 유용하거나 우리의 요구를 충족시키는지 검사), 만약에 우리가 그것을 사용하여 새로운 후손(다음 세대의 부모)을 창설한다면 이 순환은 많은 세대가 우리가 원하는 것을 지속할 것이다.TSP
과 관련하여 다음을 수행합니다.생성 도시
function generate_cities(number_of_cities, map_limit)
cities = []
for city_counter in 1:number_of_cities
push!(cities,
Dict(
"id" => city_counter,
"x" => round(rand() * map_limit),
"y" => round(rand() * map_limit)
)
)
end
println("Cities Generated:", size(cities)[1])
return cities
end
# calling generate_cities method to create cities
generate_cities(5,500)
우리는 이 도시를 사전으로 저장하고 있다.도시당
id
및 (x,y)
위치 ("id" => 1,"x" => 480.0,"y" => 157.0)
("id" => 2,"x" => 4.0,"y" => 465.0)
("id" => 3,"x" => 57.0,"y" => 25.0)
("id" => 4,"x" => 411.0,"y" => 322.0)
("id" => 5,"x" => 44.0,"y" => 460.0)
용액을 염색체로 표시하다.
우리 문제를 해결하는 방법은 한 도시에서 다른 도시로 가는 노선이다.우리는 그것을 하나의 정수 그룹으로 쓸 수 있는데, 그 중 모든 숫자는 하나의 도시 id를 대표한다.
[1,2,5,4,3,1]
그러므로 상술한 노선이나 염색체에 대해 우리는 도시 1->도시 2에서 시작하여 이와 같이 유추한다...드디어 도시 1로 돌아왔다.교차 함수
여기서 우리는 두 개의 부염색체에서 값을 추출함으로써 새로운 염색체를 생성한다.
이 문제에 대해 우리는 유전자/도시 id가 중복되지 않고 새로운 염색체를 생성하는 것을 확보하기만 하면 된다.
여러 가지 방법으로 교차를 실현할 수 있다. 예를 들어 단점 교차, 다점 교차 등이다.
우리는 염색체에 있는 무작위 점을 선택하고 간단한 교환을 통해 새로운 염색체를 만들 것이다.
function crossover(parent_one_chromosome, parent_two_chromosome, crossover_point)
offspring_part_one = parent_one_chromosome[1:crossover_point]
for gene in offspring_part_one
if gene in parent_two_chromosome
gene_loc = findfirst(el -> el == gene, parent_two_chromosome)
splice!(parent_two_chromosome, gene_loc)
end
end
return vcat(offspring_part_one, parent_two_chromosome)
end
돌연변이 함수
간단하게 말하면 돌연변이는 염색체의 무작위 변화로 정의할 수 있다.
여기서 우리는 두 유전자의 위치를 간단하게 교환할 것이다.
function mutate(offspring)
random_mutation_point1 = rand(1:length(offspring))
random_mutation_point2 = rand(1:length(offspring))
offspring[random_mutation_point1], offspring[random_mutation_point2] = offspring[random_mutation_point2], offspring[random_mutation_point1]
return offspring
end
적응도 함수
적응도 함수의 직책은 모든 염색체의 점수를 계산하는 것이다. 그러면 우리는 그것을 사용할지 말지를 결정할 수 있다
염색체는 다음 세대에 있거나 버려진다.
우리의 문제에 있어서 점수는 노선/염색체를 정하는 여행 거리이다.여행 거리는 짧을수록 좋다.
여행 거리를 계산하기 위해서 우리는 간단하게 첫 번째 도시부터 다음 도시, 그리고 다음 도시로 간다. 그래서...그리고 출발 도시로 돌아와 우리가 주행하는 거리를 더하면 우리는 이 특정 노선의 점수를 얻게 된다.
function calculate_distance_between_two_points(point1, point2)
return sqrt((((point2[1] - point1[1]))^2) + (((point2[2] - point1[2]))^2))
end
function calculate_chromosome_travel_distance(chromosome)
travel_distance = 0
chromosome = vcat(1, chromosome, 1)
for geneId in 1:length(chromosome) - 1
point1 = (
cities[chromosome[geneId]]["x"],
cities[chromosome[geneId]]["y"]
)
point2 = (
cities[chromosome[geneId + 1]]["x"],
cities[chromosome[geneId + 1]]["y"]
)
travel_distance += calculate_distance_between_two_points(point1, point2)
end
println("travel distance:", chromosome, " : ", travel_distance)
return travel_distance
end
발생 초기 인구:
우리는 초기의 전체적인 함수를 생성할 수 있도록 정의할 것이다.
# We shuffle the chromosome here
function shuffle_chromosome(chromosome)
for i in 1:size(chromosome)[1]
random_point = rand(1:5, 1)[1]
chromosome[i], chromosome[random_point] = chromosome[random_point], chromosome[i]
end
println("Created chromosome", chromosome)
return chromosome
end
function generate_initial_population(initial_population_size)
chromosomes = []
for population_counter in 1:initial_population_size
chromosome = shuffle_chromosome(copy(initial_chromosome))
push!(chromosomes,
Dict(
"chromosome" => chromosome,
"distance" => calculate_chromosome_travel_distance(chromosome)
)
)
end
return chromosomes
end
[3, 9, 4, 8, 10, 5, 1, 2, 7, 6]
[8, 1, 6, 9, 10, 5, 2, 4, 3, 7]
[2, 9, 10, 8, 5, 4, 6, 1, 3, 7]
[5, 6, 10, 7, 4, 3, 1, 2, 8, 9]
[2, 10, 9, 4, 6, 5, 1, 3, 8, 7]
주요 부분
여기서 우리는 함수를 정의했다. 함수는 주어진 대수에서 GA를 실행하고, 세대마다 주어진 수량의 자대를 만들고, 그 적용성을 검사하며, 세대마다 계속 순환한다.
function evolve(generation_count, offsprings_count, crossover_point)
for generation in 1:generation_count
for offspring_count in 1:offsprings_count
println("generation: ", generation, " offspring: ", offspring_count)
random_parent_one_id = rand(1:size(chromosomes)[1])
random_parent_two_id = rand(1:size(chromosomes)[1])
random_parent_one = copy(chromosomes[random_parent_one_id]["chromosome"])
random_parent_two = copy(chromosomes[random_parent_two_id]["chromosome"])
offspring = crossover(random_parent_one, random_parent_two, crossover_point)
offspring = mutate(offspring)
push!(chromosomes,
Dict(
"chromosome" => offspring,
"distance" => calculate_chromosome_travel_distance(offspring)
)
)
end
sort!(chromosomes, by=x -> x["distance"], rev=false)
splice!(chromosomes, 6:size(chromosomes)[1])
end
end
이제 GA를 실행하도록 하겠습니다.# creating 10 cities randomly
cities = generate_cities(10, 500)
initial_chromosome = [2:length(cities);]
# generating 10 initial chromosomes
chromosomes = generate_initial_population(10)
# we are running GA for
# 5 generations
# 5 offsprings per generation
# random crossover point as 2
evolve(5, 5, 2)
println("--------------------------------------------------------")
println("Optimal route:", vcat(1, chromosomes[1]["chromosome"], 1))
println("travel_distance:", chromosomes[1]["distance"])
만약 우리가 실행한다면, 우리는 아래의 출력을 얻을 것이다.출력:
generation: 1 offspring: 1
travel distance:[1, 3, 9, 10, 7, 5, 4, 6, 8, 2, 1] : 2780.551726305925
generation: 1 offspring: 2
travel distance:[1, 5, 10, 6, 9, 3, 2, 4, 7, 8, 1] : 2236.035984494435
generation: 1 offspring: 3
travel distance:[1, 10, 7, 3, 9, 5, 4, 6, 8, 2, 1] : 2627.3533869849102
generation: 1 offspring: 4
travel distance:[1, 7, 6, 4, 10, 3, 5, 2, 8, 9, 1] : 3078.2871083508203
generation: 1 offspring: 5
travel distance:[1, 3, 9, 10, 7, 2, 4, 5, 8, 6, 1] : 3074.581278954089
generation: 2 offspring: 1
travel distance:[1, 9, 8, 5, 10, 4, 3, 2, 6, 7, 1] : 2882.8847896850843
generation: 2 offspring: 2
travel distance:[1, 5, 10, 6, 2, 3, 9, 4, 7, 8, 1] : 1864.9566066991729
generation: 2 offspring: 3
travel distance:[1, 9, 8, 5, 10, 2, 3, 4, 6, 7, 1] : 2889.200659672017
generation: 2 offspring: 4
travel distance:[1, 4, 10, 6, 9, 3, 2, 5, 7, 8, 1] : 2520.4527035595024
generation: 2 offspring: 5
travel distance:[1, 9, 10, 6, 3, 5, 2, 4, 7, 8, 1] : 2443.441192706744
generation: 3 offspring: 1
travel distance:[1, 2, 10, 6, 9, 8, 5, 7, 4, 3, 1] : 2177.1886229349225
generation: 3 offspring: 2
travel distance:[1, 2, 10, 5, 6, 9, 8, 7, 4, 3, 1] : 1745.6328718972204
generation: 3 offspring: 3
travel distance:[1, 5, 4, 2, 6, 9, 8, 7, 10, 3, 1] : 2491.210252809206
generation: 3 offspring: 4
travel distance:[1, 7, 5, 6, 9, 3, 2, 4, 10, 8, 1] : 2867.790574182069
generation: 3 offspring: 5
travel distance:[1, 10, 6, 5, 9, 3, 2, 7, 4, 8, 1] : 2158.331962819929
generation: 4 offspring: 1
travel distance:[1, 4, 10, 6, 2, 3, 9, 5, 7, 8, 1] : 2375.395804596975
generation: 4 offspring: 2
travel distance:[1, 4, 10, 2, 6, 9, 8, 5, 7, 3, 1] : 2696.2819714580255
generation: 4 offspring: 3
travel distance:[1, 5, 3, 6, 9, 10, 2, 7, 4, 8, 1] : 2585.1841206421177
generation: 4 offspring: 4
travel distance:[1, 4, 6, 2, 9, 8, 5, 7, 10, 3, 1] : 2927.589295286965
generation: 4 offspring: 5
travel distance:[1, 5, 3, 10, 6, 9, 7, 2, 4, 8, 1] : 2610.376635133937
generation: 5 offspring: 1
travel distance:[1, 3, 10, 5, 6, 9, 8, 7, 4, 2, 1] : 1919.461172591361
generation: 5 offspring: 2
travel distance:[1, 10, 6, 8, 9, 3, 2, 7, 4, 5, 1] : 2488.399757690674
generation: 5 offspring: 3
travel distance:[1, 6, 10, 3, 5, 9, 8, 7, 4, 2, 1] : 1962.725547491429
generation: 5 offspring: 4
travel distance:[1, 10, 6, 8, 9, 4, 2, 7, 3, 5, 1] : 2626.455096698985
generation: 5 offspring: 5
travel distance:[1, 2, 6, 5, 10, 3, 9, 4, 7, 8, 1] : 1631.463753062698
--------------------------------------------------------
Optimal route:[1, 2, 6, 5, 10, 3, 9, 4, 7, 8, 1]
travel_distance:1631.463753062698
저는 Typescript로 TSP-GA 놀이공원을 만들었습니다. 놀고 싶으면 https://dillir07.github.io/Genetic-Algorithm-TSP/에 서명하세요.
Julia- 소스 코드는 Github에서 사용 가능
감사합니다.평론을 환영합니다.
Reference
이 문제에 관하여(유전 알고리즘 - 줄리아를 동반한 여행 세일즈맨), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/dillir07/genetic-algorithm-travelling-salesman-with-julia-477a
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
generation: 1 offspring: 1
travel distance:[1, 3, 9, 10, 7, 5, 4, 6, 8, 2, 1] : 2780.551726305925
generation: 1 offspring: 2
travel distance:[1, 5, 10, 6, 9, 3, 2, 4, 7, 8, 1] : 2236.035984494435
generation: 1 offspring: 3
travel distance:[1, 10, 7, 3, 9, 5, 4, 6, 8, 2, 1] : 2627.3533869849102
generation: 1 offspring: 4
travel distance:[1, 7, 6, 4, 10, 3, 5, 2, 8, 9, 1] : 3078.2871083508203
generation: 1 offspring: 5
travel distance:[1, 3, 9, 10, 7, 2, 4, 5, 8, 6, 1] : 3074.581278954089
generation: 2 offspring: 1
travel distance:[1, 9, 8, 5, 10, 4, 3, 2, 6, 7, 1] : 2882.8847896850843
generation: 2 offspring: 2
travel distance:[1, 5, 10, 6, 2, 3, 9, 4, 7, 8, 1] : 1864.9566066991729
generation: 2 offspring: 3
travel distance:[1, 9, 8, 5, 10, 2, 3, 4, 6, 7, 1] : 2889.200659672017
generation: 2 offspring: 4
travel distance:[1, 4, 10, 6, 9, 3, 2, 5, 7, 8, 1] : 2520.4527035595024
generation: 2 offspring: 5
travel distance:[1, 9, 10, 6, 3, 5, 2, 4, 7, 8, 1] : 2443.441192706744
generation: 3 offspring: 1
travel distance:[1, 2, 10, 6, 9, 8, 5, 7, 4, 3, 1] : 2177.1886229349225
generation: 3 offspring: 2
travel distance:[1, 2, 10, 5, 6, 9, 8, 7, 4, 3, 1] : 1745.6328718972204
generation: 3 offspring: 3
travel distance:[1, 5, 4, 2, 6, 9, 8, 7, 10, 3, 1] : 2491.210252809206
generation: 3 offspring: 4
travel distance:[1, 7, 5, 6, 9, 3, 2, 4, 10, 8, 1] : 2867.790574182069
generation: 3 offspring: 5
travel distance:[1, 10, 6, 5, 9, 3, 2, 7, 4, 8, 1] : 2158.331962819929
generation: 4 offspring: 1
travel distance:[1, 4, 10, 6, 2, 3, 9, 5, 7, 8, 1] : 2375.395804596975
generation: 4 offspring: 2
travel distance:[1, 4, 10, 2, 6, 9, 8, 5, 7, 3, 1] : 2696.2819714580255
generation: 4 offspring: 3
travel distance:[1, 5, 3, 6, 9, 10, 2, 7, 4, 8, 1] : 2585.1841206421177
generation: 4 offspring: 4
travel distance:[1, 4, 6, 2, 9, 8, 5, 7, 10, 3, 1] : 2927.589295286965
generation: 4 offspring: 5
travel distance:[1, 5, 3, 10, 6, 9, 7, 2, 4, 8, 1] : 2610.376635133937
generation: 5 offspring: 1
travel distance:[1, 3, 10, 5, 6, 9, 8, 7, 4, 2, 1] : 1919.461172591361
generation: 5 offspring: 2
travel distance:[1, 10, 6, 8, 9, 3, 2, 7, 4, 5, 1] : 2488.399757690674
generation: 5 offspring: 3
travel distance:[1, 6, 10, 3, 5, 9, 8, 7, 4, 2, 1] : 1962.725547491429
generation: 5 offspring: 4
travel distance:[1, 10, 6, 8, 9, 4, 2, 7, 3, 5, 1] : 2626.455096698985
generation: 5 offspring: 5
travel distance:[1, 2, 6, 5, 10, 3, 9, 4, 7, 8, 1] : 1631.463753062698
--------------------------------------------------------
Optimal route:[1, 2, 6, 5, 10, 3, 9, 4, 7, 8, 1]
travel_distance:1631.463753062698
Reference
이 문제에 관하여(유전 알고리즘 - 줄리아를 동반한 여행 세일즈맨), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dillir07/genetic-algorithm-travelling-salesman-with-julia-477a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)