반응형
시뮬레이티드 어닐링 (Simulated Annealing)
시뮬레이티드 어닐링(Simulated Annealing, SA)은 금속의 냉각 및 결정화 과정에서 영감을 받은 확률적 최적화 알고리즘입니다. 이 알고리즘은 전역 최적해를 찾기 위해 국부 최적해에서 탈출할 수 있도록 고안되었습니다.
시뮬레이티드 어닐링의 주요 단계
- 초기화: 초기 해와 초기 온도를 설정합니다.
- 이웃 해 생성: 현재 해의 이웃 해를 무작위로 생성합니다.
- 해 수용: 새로운 해가 더 나은 해이면 수용합니다. 그렇지 않으면, 확률적으로 수용합니다.
- 온도 감소: 온도를 점진적으로 낮춥니다.
- 종료 조건 확인: 종료 조건(예: 온도가 충분히 낮아지거나 최대 반복 횟수에 도달)을 확인합니다.
문제 예시: 여행하는 외판원 문제 (TSP)
시뮬레이티드 어닐링을 사용하여 여행하는 외판원 문제(TSP)를 해결합니다. TSP는 주어진 도시들을 모두 한 번씩 방문하고 처음 도시로 돌아오는 최소 경로를 찾는 문제입니다.
시뮬레이티드 어닐링 구현
다음은 C++로 시뮬레이티드 어닐링을 사용하여 TSP를 해결하는 예제입니다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <limits>
const int NUM_CITIES = 10;
const double INITIAL_TEMPERATURE = 1000.0;
const double FINAL_TEMPERATURE = 1e-3;
const double COOLING_RATE = 0.995;
const int ITERATIONS_PER_TEMP = 100;
// 도시 좌표
std::vector<std::pair<int, int>> cities = {
{0, 0}, {1, 2}, {2, 4}, {3, 6}, {5, 8}, {6, 7}, {7, 5}, {8, 3}, {9, 1}, {10, 0}
};
// 경로 거리 계산 함수
double calculateDistance(const std::vector<int>& path) {
double distance = 0.0;
for (int i = 0; i < path.size() - 1; ++i) {
int x1 = cities[path[i]].first;
int y1 = cities[path[i]].second;
int x2 = cities[path[i + 1]].first;
int y2 = cities[path[i + 1]].second;
distance += std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
// 시작 도시로 돌아오기
int x1 = cities[path.back()].first;
int y1 = cities[path.back()].second;
int x2 = cities[path.front()].first;
int y2 = cities[path.front()].second;
distance += std::sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
return distance;
}
// 이웃 해 생성 함수
std::vector<int> generateNeighbor(const std::vector<int>& path) {
std::vector<int> newPath = path;
int i = rand() % path.size();
int j = rand() % path.size();
std::swap(newPath[i], newPath[j]);
return newPath;
}
// 시뮬레이티드 어닐링 함수
std::vector<int> simulatedAnnealing() {
std::vector<int> currentPath(NUM_CITIES);
for (int i = 0; i < NUM_CITIES; ++i) {
currentPath[i] = i;
}
std::random_shuffle(currentPath.begin(), currentPath.end());
double currentDistance = calculateDistance(currentPath);
std::vector<int> bestPath = currentPath;
double bestDistance = currentDistance;
double temperature = INITIAL_TEMPERATURE;
while (temperature > FINAL_TEMPERATURE) {
for (int i = 0; i < ITERATIONS_PER_TEMP; ++i) {
std::vector<int> newPath = generateNeighbor(currentPath);
double newDistance = calculateDistance(newPath);
if (newDistance < currentDistance || exp((currentDistance - newDistance) / temperature) > static_cast<double>(rand()) / RAND_MAX) {
currentPath = newPath;
currentDistance = newDistance;
if (newDistance < bestDistance) {
bestPath = newPath;
bestDistance = newDistance;
}
}
}
temperature *= COOLING_RATE;
}
return bestPath;
}
int main() {
srand(time(0));
std::vector<int> bestPath = simulatedAnnealing();
double bestDistance = calculateDistance(bestPath);
std::cout << "최적 경로: ";
for (int city : bestPath) {
std::cout << city << " ";
}
std::cout << std::endl;
std::cout << "최적 경로의 거리: " << bestDistance << std::endl;
return 0;
}
설명
- 입력:
cities
: 도시 좌표 리스트NUM_CITIES
: 도시의 수INITIAL_TEMPERATURE
: 초기 온도FINAL_TEMPERATURE
: 최종 온도COOLING_RATE
: 온도 감소율ITERATIONS_PER_TEMP
: 각 온도에서 반복할 횟수
- 경로 거리 계산:
calculateDistance
함수는 주어진 경로의 총 거리를 계산합니다.
- 이웃 해 생성:
generateNeighbor
함수는 현재 경로의 두 도시를 무작위로 교환하여 새로운 경로를 생성합니다.
- 시뮬레이티드 어닐링 수행:
simulatedAnnealing
함수는 초기 해와 초기 온도를 설정하고, 각 온도에서 새로운 경로를 생성하여 현재 경로와 비교합니다.- 새로운 경로가 더 나은 해이면 수용하고, 그렇지 않으면 확률적으로 수용합니다.
- 온도를 점진적으로 감소시켜 최적해를 찾습니다.
시뮬레이티드 어닐링의 기본 개념과 구현 방법을 이해했습니다. 질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "Day 29: 병렬 알고리즘(Parallel Algorithms)"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++ 심화 알고리즘과 자료구조 시리즈' 카테고리의 다른 글
[C++로 배우는 알고리즘과 자료구조 심화] Day 30: 양자 알고리즘 (Quantum Algorithms) 소개 (0) | 2024.08.01 |
---|---|
[C++로 배우는 알고리즘과 자료구조 심화] Day 27: 유전 알고리즘 (Genetic Algorithms) (0) | 2024.08.01 |
[C++로 배우는 알고리즘과 자료구조 심화] Day 25: 임의화 알고리즘 (Randomized Algorithms) (0) | 2024.08.01 |
[C++로 배우는 알고리즘과 자료구조 심화] Day 26: 선형 계획법 (Linear Programming) (0) | 2024.08.01 |
[C++로 배우는 알고리즘과 자료구조 심화] Day 23: 분할 상환 분석 (Amortized Analysis) (0) | 2024.08.01 |