EgtNumKernel :

- Aggiunta classe di calcolo per ottimizzazione ordine delle lavorazioni
- Aggiunti vincoli obbligatori e dipendenze suggerite a ShortestPath.
This commit is contained in:
Riccardo Elitropi
2025-04-23 10:09:41 +02:00
parent d9818970e7
commit 558b590810
13 changed files with 1552 additions and 172 deletions
+120 -37
View File
@@ -17,6 +17,36 @@
#include "stdafx.h"
#include "ShortestPath.h"
// ----------------------------------------------------------------------------
static void
SwapNodesForHybrid1( NODE* pLast, NODE* pFirst, NODE* pKth)
{
NODE* pSave = pKth->pNext ;
pKth->pNext = pKth->pNext->pNext ;
pKth->pNext->pPrev = pKth ;
pLast->pNext = pSave ;
pFirst->pPrev = pSave ;
pSave->pNext = pFirst ;
pSave->pPrev = pLast ;
}
// ----------------------------------------------------------------------------
static void
SwapNodesForHybrid2( NODE* pLast, NODE* pFirst, NODE* pKth)
{
for ( NODE* pReverse = pFirst ; pReverse != pKth ;) {
NODE* pSave = pReverse->pNext ;
pReverse->pNext = pReverse->pPrev ;
pReverse->pPrev = pSave ;
pReverse = pSave ;
}
pFirst->pNext = pKth->pNext ;
pKth->pNext->pPrev = pFirst ;
pKth->pNext = pKth->pPrev ;
pKth->pPrev = pLast ;
pLast->pNext = pKth ;
}
// ----------------------------------------------------------------------------
long long unsigned
ShortestPath::Hybrid( NODE* pPath)
@@ -24,56 +54,109 @@ ShortestPath::Hybrid( NODE* pPath)
const int MAX_TRY = 2048 ;
unsigned count = 1 ;
NODE* pFirst = pPath ;
NODE* pFirstDep = m_pCheckDep ;
unsigned nTry = 1 ;
do {
NODE* pLast = pFirst->pPrev ;
NODE* pKth = pFirst->pNext ;
NODE* pLastDep = pFirstDep->pPrev ;
NODE* pKthDep = pFirstDep->pNext ;
do {
// Point-Opt ( D1=new, D3=original)
unsigned D1 = ArcCost( pKth->nPos, pKth->pNext->pNext->nPos) +
ArcCost( pKth->pNext->nPos, pFirst->nPos) +
ArcCost( pLast->nPos, pKth->pNext->nPos) ;
unsigned D3 = ArcCost( pLast->nPos, pFirst->nPos) +
ArcCost( pKth->nPos, pKth->pNext->nPos) +
ArcCost( pKth->pNext->nPos, pKth->pNext->pNext->nPos) ;
// Two-Opt ( D2=new, D4=original)
unsigned D2 = ArcCost( pFirst->nPos, pKth->pNext->nPos) +
ArcCost( pLast->nPos, pKth->nPos) ;
unsigned D4 = ArcCost( pLast->nPos, pFirst->nPos) +
ArcCost( pKth->nPos, pKth->pNext->nPos) ;
// Lunghezze originali e nuova del tratto intermedio che viene invertito
for ( NODE* pCurr = pFirst ; pCurr != pKth ; pCurr = pCurr->pNext) {
D4 += ArcCost( pCurr->nPos, pCurr->pNext->nPos) ;
D2 += ArcCost( pCurr->pNext->nPos, pCurr->nPos) ;
unsigned D1 = 0 ;
unsigned D2 = 0 ;
unsigned D3 = 0 ;
unsigned D4 = 0 ;
// se non esistono dipendenze suggerite
if ( ! ExistSuggDependences()) {
// Point-Opt ( D1=new, D3=original)
D1 = ArcCost( pKth->nPos, pKth->pNext->pNext->nPos) +
ArcCost( pKth->pNext->nPos, pFirst->nPos) +
ArcCost( pLast->nPos, pKth->pNext->nPos) ;
D3 = ArcCost( pLast->nPos, pFirst->nPos) +
ArcCost( pKth->nPos, pKth->pNext->nPos) +
ArcCost( pKth->pNext->nPos, pKth->pNext->pNext->nPos) ;
// Two-Opt ( D2=new, D4=original)
D2 = ArcCost( pFirst->nPos, pKth->pNext->nPos) +
ArcCost( pLast->nPos, pKth->nPos) ;
D4 = ArcCost( pLast->nPos, pFirst->nPos) +
ArcCost( pKth->nPos, pKth->pNext->nPos) ;
// Lunghezze originali e nuova del tratto intermedio che viene invertito
for ( NODE* pCurr = pFirst ; pCurr != pKth ; pCurr = pCurr->pNext) {
D4 += ArcCost( pCurr->nPos, pCurr->pNext->nPos) ;
D2 += ArcCost( pCurr->pNext->nPos, pCurr->nPos) ;
}
}
// se esistono dipendenze suggerite
else {
D3 = static_cast<unsigned>( TotalCost( pPath)) ;
D4 = D3 ;
D1 = MAXDIST ;
D2 = MAXDIST ;
CopyPathAdv( pPath, m_pCheckDep, pLast, pFirst, pKth, &pLastDep, &pFirstDep, &pKthDep) ;
SwapNodesForHybrid1( pLastDep, pFirstDep, pKthDep) ;
bool bOkD1 = ( IsPathRespectingContraints( m_pCheckDep)) ;
if ( bOkD1)
D1 = static_cast<unsigned>( TotalCost( m_pCheckDep)) ;
CopyPathAdv( pPath, m_pCheckDep, pLast, pFirst, pKth, &pLastDep, &pFirstDep, &pKthDep) ;
SwapNodesForHybrid2( pLastDep, pFirstDep, pKthDep) ;
bool bOkD2 = ( IsPathRespectingContraints( m_pCheckDep)) ;
if ( bOkD2)
D2 = static_cast<unsigned>( TotalCost( m_pCheckDep)) ;
}
// controllo se ci sono miglioramenti nei persorsi
if ( D1 < D3 || D2 < D4) {
if ( D1 < D3 &&
( D2 >= D4 || ( D3 - D1) >= ( D4 - D2))) {
NODE* pSave = pKth->pNext ;
pKth->pNext = pKth->pNext->pNext ;
pKth->pNext->pPrev = pKth ;
pLast->pNext = pSave ;
pFirst->pPrev = pSave ;
pSave->pNext = pFirst ;
pSave->pPrev = pLast ;
// nel caso di assenza di dipendenze
if ( ! ExistConstraints()) {
SwapNodesForHybrid1( pLast, pFirst, pKth) ;
count = 0 ;
pFirst = pLast->pNext ;
pKth = pFirst->pNext ;
}
// nel caso di dipendeze, controllo se il nuovo percorso le rispetta
else {
CopyPathAdv( pPath, m_pCheckDep, pLast, pFirst, pKth, &pLastDep, &pFirstDep, &pKthDep) ;
// effettuo i cambi dei nodi sul path di test per le dipendenze
SwapNodesForHybrid1( pLastDep, pFirstDep, pKthDep) ;
// se il path di test rispetta i vincoli, allora effettuo i cambi sul percorso vero
if ( IsPathRespectingContraints( m_pCheckDep)) {
SwapNodesForHybrid1( pLast, pFirst, pKth) ;
count = 0 ;
pFirst = pLast->pNext ;
pKth = pFirst->pNext ;
}
// altrimenti passo al nodo successivo
else
pKth = pKth->pNext ;
}
}
else {
for ( NODE* pReverse = pFirst ; pReverse != pKth ;) {
NODE* pSave = pReverse->pNext ;
pReverse->pNext = pReverse->pPrev ;
pReverse->pPrev = pSave ;
pReverse = pSave ;
// nel caso di assenza di dipendenze
if ( ! ExistConstraints()) {
SwapNodesForHybrid2( pLast, pFirst, pKth) ;
count = 0 ;
pFirst = pLast->pNext ;
pKth = pFirst->pNext ;
}
// nel caso di dipendeze, controllo se il nuovo percorso le rispetta
else {
CopyPathAdv( pPath, m_pCheckDep, pLast, pFirst, pKth, &pLastDep, &pFirstDep, &pKthDep) ;
// effettuo i cambi dei nodi sul path di test per le dipendenze
SwapNodesForHybrid2( pLastDep, pFirstDep, pKthDep) ;
// se il path di test rispetta i vincoli, allora effettuo i cambi sul percorso vero
if ( IsPathRespectingContraints( m_pCheckDep)) {
SwapNodesForHybrid2( pLast, pFirst, pKth) ;
count = 0 ;
pFirst = pLast->pNext ;
pKth = pFirst->pNext ;
}
// altrimenti passo al nodo successivo
else
pKth = pKth->pNext ;
}
pFirst->pNext = pKth->pNext ;
pKth->pNext->pPrev = pFirst ;
pKth->pNext = pKth->pPrev ;
pKth->pPrev = pLast ;
pLast->pNext = pKth ;
}
count = 0 ;
pFirst = pLast->pNext ;
pKth = pFirst->pNext ;
}
}
else
pKth = pKth->pNext ;
} while ( pKth != pLast->pPrev->pPrev && count != 0) ;