EgtNumKernel :
- Aggiunta classe di calcolo per ottimizzazione ordine delle lavorazioni - Aggiunti vincoli obbligatori e dipendenze suggerite a ShortestPath.
This commit is contained in:
+99
-39
@@ -54,7 +54,7 @@ ShortestPath::Tsp( void)
|
||||
m_Dists = new(nothrow) unsigned[ m_nNumPnts * m_nNumPnts] ;
|
||||
if ( m_Dists == nullptr)
|
||||
return false ;
|
||||
// alloco la matrice ausiliaria
|
||||
// alloco la matrice ausiliaria
|
||||
if ( m_Available != nullptr)
|
||||
delete m_Available ;
|
||||
m_Available = new(nothrow) bool[ m_nNumPnts * m_nNumPnts] ;
|
||||
@@ -72,6 +72,10 @@ ShortestPath::Tsp( void)
|
||||
m_pDupl = new(nothrow) NODE[ m_nNumPnts] ;
|
||||
if ( m_pDupl == nullptr)
|
||||
return false ;
|
||||
// alloco la copia del path per controllo dipendenze
|
||||
if ( m_pCheckDep != nullptr)
|
||||
delete m_pCheckDep ;
|
||||
m_pCheckDep = new(nothrow) NODE[ m_nNumPnts] ;
|
||||
|
||||
// calcolo la matrice delle distanze
|
||||
CalcDistances() ;
|
||||
@@ -79,6 +83,7 @@ ShortestPath::Tsp( void)
|
||||
// organizzo percorsi
|
||||
PreparePath( m_pMain) ;
|
||||
PreparePath( m_pDupl) ;
|
||||
PreparePath( m_pCheckDep) ;
|
||||
|
||||
// inizializzo minimo costo
|
||||
m_nMinCost = LLONG_MAX ;
|
||||
@@ -87,6 +92,7 @@ ShortestPath::Tsp( void)
|
||||
long long unsigned nMinNN = NearNeighbor() ;
|
||||
string sOut = "-- NearNeighbor : TotalCost = " + to_string( nMinNN) ;
|
||||
MY_LOG( sOut.c_str()) ;
|
||||
_printPath( m_pMain, ToString( "NN : ")) ;
|
||||
// se migliora, salvo l'ordinamento
|
||||
if ( nMinNN < m_nMinCost) {
|
||||
MY_LOG( " Improve") ;
|
||||
@@ -101,38 +107,42 @@ ShortestPath::Tsp( void)
|
||||
// ---- Applico percorso invertito, se risultato precedente scarso ----
|
||||
const double COEFF_INVERTED = 1.2 ;
|
||||
const int MIN_PNTS_INVERTED = 128 ;
|
||||
if ( m_nMinCost > COEFF_INVERTED * m_nTotMin || m_nNumPnts < MIN_PNTS_INVERTED) {
|
||||
// inverto il percorso
|
||||
NODE* pCurr = m_pDupl->pPrev ;
|
||||
NODE* pPath = m_pMain ;
|
||||
for ( unsigned i = 0 ; i < m_nNumPnts ; ++ i) {
|
||||
pPath->nPos = pCurr->nPos ;
|
||||
pPath = pPath->pNext ;
|
||||
pCurr = pCurr->pPrev ;
|
||||
if ( ! ExistConstraints()) {
|
||||
if ( m_nMinCost > COEFF_INVERTED * m_nTotMin || m_nNumPnts < MIN_PNTS_INVERTED) {
|
||||
// inverto il percorso
|
||||
NODE* pCurr = m_pDupl->pPrev ;
|
||||
NODE* pPath = m_pMain ;
|
||||
for ( unsigned i = 0 ; i < m_nNumPnts ; ++ i) {
|
||||
pPath->nPos = pCurr->nPos ;
|
||||
pPath = pPath->pNext ;
|
||||
pCurr = pCurr->pPrev ;
|
||||
}
|
||||
// ne calcolo il risultato
|
||||
long long unsigned nMinInv = TotalCost( m_pMain) ;
|
||||
_printPath( m_pMain, "Inverted NN : ") ;
|
||||
string sOut = "-- Inverted NN : TotalCost = " + to_string( nMinInv) ;
|
||||
MY_LOG( sOut.c_str()) ;
|
||||
// se migliora, salvo l'ordinamento
|
||||
if ( nMinInv < m_nMinCost) {
|
||||
MY_LOG( " Improve") ;
|
||||
m_nMinCost = nMinInv ;
|
||||
UpdateOrder( m_pMain) ;
|
||||
}
|
||||
// salvo il percorso in un duplicato
|
||||
SavePath( m_pMain) ;
|
||||
// miglioramenti aggiuntivi
|
||||
CalculateImprovements( m_pMain) ;
|
||||
}
|
||||
// ne calcolo il risultato
|
||||
long long unsigned nMinInv = TotalCost( m_pMain) ;
|
||||
string sOut = "-- Inverted NN : TotalCost = " + to_string( nMinInv) ;
|
||||
MY_LOG( sOut.c_str()) ;
|
||||
// se migliora, salvo l'ordinamento
|
||||
if ( nMinInv < m_nMinCost) {
|
||||
MY_LOG( " Improve") ;
|
||||
m_nMinCost = nMinInv ;
|
||||
UpdateOrder( m_pMain) ;
|
||||
}
|
||||
// salvo il percorso in un duplicato
|
||||
SavePath( m_pMain) ;
|
||||
// miglioramenti aggiuntivi
|
||||
CalculateImprovements( m_pMain) ;
|
||||
else
|
||||
MY_LOG( "-- Inverted NN : Not necessary") ;
|
||||
}
|
||||
else
|
||||
MY_LOG( "-- Inverted NN : Not necessary") ;
|
||||
|
||||
// ---- Applico pessima partenza, se risultato precedente scarso ----
|
||||
const double COEFF_FARNEIG = 1.4 ;
|
||||
const int MIN_PNTS_FARNEIG = 128 ;
|
||||
if ( m_nMinCost > COEFF_FARNEIG * m_nTotMin || m_nNumPnts < MIN_PNTS_FARNEIG) {
|
||||
long long unsigned nMinFN = FarNeighbor() ;
|
||||
_printPath( m_pMain, "FN : ") ;
|
||||
string sOut = "-- FarNeighbor : TotalCost = " + to_string( nMinFN) ;
|
||||
MY_LOG( sOut.c_str()) ;
|
||||
// se migliora, salvo l'ordinamento
|
||||
@@ -159,6 +169,7 @@ ShortestPath::CalculateImprovements( NODE* pPath)
|
||||
// Ottimizzazione con movimento di singolo punto
|
||||
RestorePath( pPath) ;
|
||||
long long unsigned nPntOpt = PointOpt( pPath) ;
|
||||
_printPath( pPath, "PointOpt : ") ;
|
||||
string sOut = " PointOpt : TotalCost = " + to_string( nPntOpt) ;
|
||||
MY_LOG( sOut.c_str()) ;
|
||||
// se migliora, salvo l'ordinamento
|
||||
@@ -173,6 +184,7 @@ ShortestPath::CalculateImprovements( NODE* pPath)
|
||||
if ( m_nNumPnts <= MAX_NODES_2OPT) {
|
||||
RestorePath( pPath) ;
|
||||
long long unsigned nTwoOpt = TwoOpt( pPath) ;
|
||||
_printPath( pPath, "TwoOpt : ") ;
|
||||
string sOut = " TwoOpt : TotalCost = " + to_string( nTwoOpt) ;
|
||||
MY_LOG( sOut.c_str()) ;
|
||||
// se migliora, salvo l'ordinamento
|
||||
@@ -188,6 +200,7 @@ ShortestPath::CalculateImprovements( NODE* pPath)
|
||||
if ( m_nNumPnts <= MAX_NODES_HYBRID) {
|
||||
RestorePath( pPath) ;
|
||||
long long unsigned nHybOpt = Hybrid( pPath) ;
|
||||
_printPath( pPath, "Hybrid : ") ;
|
||||
string sOut = " Hybrid : TotalCost = " + to_string( nHybOpt) ;
|
||||
MY_LOG( sOut.c_str()) ;
|
||||
// se migliora, salvo l'ordinamento
|
||||
@@ -342,29 +355,40 @@ ShortestPath::CalcDistances( void)
|
||||
}
|
||||
|
||||
// ciclo per calcolare le distanze tra tutte le coppie di nodi
|
||||
bool bCalcDistances = ( m_ExtDistMat.empty()) ;
|
||||
for ( unsigned i = 0 ; i < nLimit ; ++ i) {
|
||||
unsigned nRowMinDist = INT_MAX ;
|
||||
for ( unsigned j = 0 ; j < nLimit ; ++ j) {
|
||||
if ( i != j) {
|
||||
// calcolo distanza i -> j
|
||||
float dDx = float( m_Points[i].dXf - m_Points[j].dXi) ;
|
||||
float dDy = float( m_Points[i].dYf - m_Points[j].dYi) ;
|
||||
float dDz = float( m_Points[i].dZf - m_Points[j].dZi) ;
|
||||
float dDh = float( m_Points[i].dHf - m_Points[j].dHi) ;
|
||||
float dDv = float( m_Points[i].dVf - m_Points[j].dVi) ;
|
||||
unsigned nDist = min( GetDistance( dDx, dDy, dDz, dDh, dDv), MAXDIST) ;
|
||||
m_Dists[ Index( i, j)] = nDist ;
|
||||
// verifico se nuovo minimo di linea
|
||||
if ( nDist < nRowMinDist)
|
||||
nRowMinDist = nDist ;
|
||||
// se ho già impostato una matrice delle distanze, allora uso quella
|
||||
if ( ! bCalcDistances)
|
||||
m_Dists[Index( i, j)] = m_ExtDistMat[i][j] ;
|
||||
// altrimenti calcolo le rispettive distanze
|
||||
else {
|
||||
if ( i != j) {
|
||||
// calcolo distanza i -> j
|
||||
float dDx = float( m_Points[i].dXf - m_Points[j].dXi) ;
|
||||
float dDy = float( m_Points[i].dYf - m_Points[j].dYi) ;
|
||||
float dDz = float( m_Points[i].dZf - m_Points[j].dZi) ;
|
||||
float dDh = float( m_Points[i].dHf - m_Points[j].dHi) ;
|
||||
float dDv = float( m_Points[i].dVf - m_Points[j].dVi) ;
|
||||
unsigned nDist = min( GetDistance( dDx, dDy, dDz, dDh, dDv), MAXDIST) ;
|
||||
m_Dists[ Index( i, j)] = nDist ;
|
||||
// verifico se nuovo minimo di linea
|
||||
if ( nDist < nRowMinDist)
|
||||
nRowMinDist = nDist ;
|
||||
}
|
||||
else
|
||||
m_Dists[ Index( i, j)] = MAXDIST ;
|
||||
}
|
||||
else
|
||||
m_Dists[ Index( i, j)] = MAXDIST ;
|
||||
}
|
||||
// aggiorno il totale delle minime distanze
|
||||
m_nTotMin += nRowMinDist ;
|
||||
}
|
||||
|
||||
// nel caso di dipendenze suggerite, calcolo il coefficiente di costo massimo associato
|
||||
if ( ExistSuggDependences())
|
||||
m_nMaxDistSuggDep = CalcMaxDist() ;
|
||||
|
||||
// nel caso di percorso aperto senza vincoli, il numero delle distanze è uno meno di quello dei veri nodi
|
||||
if ( m_nType == SP_OPEN &&
|
||||
m_ObStart.nF == OB_NONE && m_ObEnd.nF == OB_NONE)
|
||||
@@ -423,6 +447,38 @@ ShortestPath::RestorePath( NODE* pPath)
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
ShortestPath::CopyPath( NODE* pPath, NODE* pPathCopy)
|
||||
{
|
||||
NODE* pCurr = pPathCopy ;
|
||||
for ( unsigned i = 0 ; i < m_nNumPnts ; ++ i) {
|
||||
pCurr->nPos = pPath->nPos ;
|
||||
pPath = pPath->pNext ;
|
||||
pCurr = pCurr->pNext ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
ShortestPath::CopyPathAdv( NODE* pPath, NODE* pPathCopy, NODE* pLast, NODE* pFirst, NODE* pKth,
|
||||
NODE** pLastCopy, NODE** pFirstCopy, NODE** pKthCopy)
|
||||
{
|
||||
CopyPath( pPath, pPathCopy) ;
|
||||
NODE* pCurr = pPath ;
|
||||
NODE* pCurrCopy = pPathCopy ;
|
||||
for ( unsigned i = 0 ; i < m_nNumPnts ; ++ i) {
|
||||
if ( pCurr == pLast)
|
||||
*pLastCopy = pCurrCopy ;
|
||||
if ( pCurr == pKth)
|
||||
*pKthCopy = pCurrCopy ;
|
||||
if ( pCurr == pFirst)
|
||||
*pFirstCopy = pCurrCopy ;
|
||||
pCurr = pCurr->pNext ;
|
||||
pCurrCopy = pCurrCopy->pNext ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
long long unsigned
|
||||
ShortestPath::TotalCost( NODE* pPath)
|
||||
@@ -438,6 +494,10 @@ ShortestPath::TotalCost( NODE* pPath)
|
||||
nCost += ArcCost( pCurr->nPos, pCurr->pNext->nPos) ;
|
||||
pCurr = pCurr->pNext ;
|
||||
}
|
||||
// se sono presenti delle dipendenze suggerite violate, aumento il costo
|
||||
int nBreak = 0 ;
|
||||
if ( ! IsPathRespectingSuggestedDependences( pPath, nBreak))
|
||||
nCost += m_nMaxDistSuggDep * nBreak ;
|
||||
return nCost ;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user