#include "stdafx.h" #include "AnnealingTSP.h" #include #include CAnnealingTSP::CAnnealingTSP(void) { Reset(); } CAnnealingTSP::~CAnnealingTSP(void) { Reset(); } void CAnnealingTSP::Reset() { m_vecPathCurrent.clear(); m_dTemperature = 1000.0; // * The current temperature. m_dTotalDistanceCurrent = DBL_MAX; // * The length of the current path. } void CAnnealingTSP::SetPathData(const VectorPathData& vecPathData, const SPathData& ptStart) { if ((int)vecPathData.size()<1) return; Reset(); CGreedyTSP::SetPathData(vecPathData, ptStart); m_vecPathCurrent.resize(m_nPathCount); } bool CAnnealingTSP::anneal(double d) { if (m_dTemperature < 1.0E-4) { if (d > 0.0) return true; else return false; } double random = double(rand())/(1.0*RAND_MAX); if (random < exp(d / m_dTemperature)) return true; else return false; } double CAnnealingTSP::getLength(int i, int j) { int c1 = m_vecPathCurrent[i % m_nPathCount]; int c2 = m_vecPathCurrent[j % m_nPathCount]; return m_pPathGraph[c1][c2]; } double CAnnealingTSP::CalculateTSP() { if (m_nPathCount<1) return -1.0; if (m_nPathCount<2) { return (m_dTotalDistance=GetTotalDistance()); } srand((unsigned)time(NULL)); int nCycle = 1; int nSameCount = 0; // copy path result m_vecPathCurrent = m_vecPathResult; m_dTotalDistanceCurrent = m_dTotalDistance; while (nSameCount<50) { // make adjustments to city order(annealing) for (int j2 = 0; j2 < m_nPathCount * m_nPathCount; j2++) { int i1 = rand() % m_nPathCount; int j1 = rand() % m_nPathCount; double d = getLength(i1, i1 + 1) + getLength(j1, j1 + 1) - getLength(i1, j1) - getLength(i1 + 1, j1 + 1); if (anneal(d)) { if (j1 < i1) { int k1 = i1; i1 = j1; j1 = k1; } for (; j1 > i1; j1--) { int i2 = m_vecPathCurrent[i1 + 1]; m_vecPathCurrent[i1 + 1] = m_vecPathCurrent[j1]; m_vecPathCurrent[j1] = i2; i1++; } } } // See if this improved anything m_dTotalDistanceCurrent = GetTotalDistance(m_vecPathCurrent); if (m_dTotalDistanceCurrent < m_dTotalDistance) { m_vecPathResult = m_vecPathCurrent; m_dTotalDistance = m_dTotalDistanceCurrent; nSameCount = 0; } else { nSameCount++; } m_dTemperature = m_dDelta * m_dTemperature; nCycle++; } SortingPathResult(); return m_dTotalDistance; }