Files
EgtNumKernel/TwoOpt.cpp
T
SaraP ec9e4b4c76 EgtNumKernel 2.3k1 :
- in ShortestPath aumentato il numero max di punti consentiti.
2021-11-18 09:34:24 +01:00

81 lines
3.0 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : TwoOpt.cpp Data : 22.12.15 Versione : 1.6l4
// Contenuto : Miglioramento del percorso spezzandolo in 2 parti e
// ricollegando con una delle due parti invertite.
//
// K Last K Last
// o o--<- o--o--<-
// |\/ |
// |/\ |
// o o---> o--o--->
// First K+1 First K+1
//
// Modifiche : 22.12.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "ShortestPath.h"
// ----------------------------------------------------------------------------
long long unsigned
ShortestPath::TwoOpt( NODE* pPath)
{
const int MAX_TRY = 2048 ;
unsigned nTry = 1 ;
unsigned nCount = 1 ;
NODE* pFirst = pPath ;
do {
NODE* pLast = pFirst->pPrev ;
NODE* pKth = pFirst->pNext ;
do {
// lunghezza originale dei tratti da scambiare
unsigned nEXIST = ArcCost( pLast->nPos, pFirst->nPos) +
ArcCost( pKth->nPos, pKth->pNext->nPos) ;
// nuova lunghezza dei tratti da scambiare
unsigned nTEST = ArcCost( pFirst->nPos, pKth->pNext->nPos) +
ArcCost( pLast->nPos, pKth->nPos) ;
// lunghezze originali e nuova del tratto intermedio che viene invertito
for ( NODE* pCurr = pFirst ; pCurr != pKth ; pCurr = pCurr->pNext) {
nEXIST += ArcCost( pCurr->nPos, pCurr->pNext->nPos) ;
nTEST += ArcCost( pCurr->pNext->nPos, pCurr->nPos) ;
}
// se lo scambio fa risparmiare
if ( nTEST < nEXIST) {
// inverto il tratto intermedio
for ( NODE* pCurr = pFirst ; pCurr != pKth ;) {
NODE* pSave = pCurr->pNext ;
pCurr->pNext = pCurr->pPrev ;
pCurr->pPrev = pSave ;
pCurr = pSave ;
}
// sistemo gli estremi
pFirst->pNext = pKth->pNext ;
pKth->pNext->pPrev = pFirst ;
pKth->pNext = pKth->pPrev ;
pKth->pPrev = pLast ;
pLast->pNext = pKth ;
pFirst = pLast->pNext ;
pKth = pFirst->pNext ;
// faccio ripartire il conto
nCount = 0 ;
}
// altrimenti passo al nodo successivo
else
pKth = pKth->pNext ;
} while ( pKth != pLast->pPrev->pPrev && nCount != 0) ;
if ( nCount != 0)
pFirst = pFirst->pNext ;
nCount ++ ;
nTry ++ ;
} while ( nCount < m_nNumPnts && nTry < MAX_TRY) ;
// ricalcolo il costo del percorso
return TotalCost( pPath) ;
}