Advertisement
Shaktal

Dijikstra's Algorithm for FlashKiller

Jan 1st, 2012
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.52 KB | None | 0 0
  1. #include <string>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <map>
  5. #include <cmath>
  6. #include <iostream>
  7.  
  8. struct Node;
  9. struct Arc {
  10.     Node *pN1, *pN2;
  11.     double dbWeight;
  12. };
  13.  
  14. struct Node {
  15.     double x, y;
  16.     std::vector<Arc*> vecArcs;
  17.     std::string szName;
  18. };
  19.  
  20. std::vector<Node*> g_vecNodes;
  21.  
  22. void CalculateWeightOfArc( Arc* pArc )
  23. {
  24.     double distance = std::sqrt( std::pow( pArc->pN1->x - pArc->pN2->x, 2 ) + std::pow( pArc->pN1->y - pArc->pN2->y, 2 ) );
  25.     pArc->dbWeight = distance;
  26. }
  27.  
  28. double Dijikstra( std::vector<Arc*>& vecArcs /* Our vector of arcs which we will traverse */, Node* pStart, Node* pEnd )
  29. {
  30.     // For Dijikstra's algorithm, we associate each node with a temporary distance:
  31.     std::map<Node*, std::pair<double, Node*>> mapNodeDistance;
  32.     std::vector<Node*> vecGraphCopy = g_vecNodes;
  33.     Node* pCurrNode = pStart;
  34.     for( auto it = vecGraphCopy.begin(); it != vecGraphCopy.end(); ++it )
  35.     {
  36.         if( (*it) == pStart )
  37.         {
  38.             mapNodeDistance.insert( std::make_pair( (*it), std::make_pair(0.0, nullptr) ) );
  39.             continue;
  40.         }
  41.  
  42.         mapNodeDistance.insert( std::make_pair( (*it), std::make_pair(DBL_MAX, nullptr) ) );
  43.     }
  44.  
  45.     vecGraphCopy.erase( std::find( vecGraphCopy.begin(), vecGraphCopy.end(), pStart ) );
  46.  
  47.     while( pCurrNode != pEnd )
  48.     {
  49.         // Go through and update the temporary distances:
  50.         for( auto it = pCurrNode->vecArcs.begin(); it != pCurrNode->vecArcs.end(); ++it )
  51.         {
  52.             Node* pNext = ((*it)->pN1 != pCurrNode) ? (*it)->pN1 : (*it)->pN2;
  53.             if( pNext == nullptr )
  54.                 continue;
  55.  
  56.             if( mapNodeDistance.find( pNext )->second.first > mapNodeDistance.find( pCurrNode )->second.first + (*it)->dbWeight )
  57.             {
  58.                 mapNodeDistance.find( pNext )->second.first = mapNodeDistance.find( pCurrNode )->second.first + (*it)->dbWeight;
  59.                 mapNodeDistance.find( pNext )->second.second = pCurrNode;
  60.             }
  61.         }
  62.  
  63.         // Find the node with the smallest temporary value:
  64.         double currSmallest = DBL_MAX;
  65.         Node* pOldNode = pCurrNode;
  66.         for( auto it = vecGraphCopy.begin(); it != vecGraphCopy.end(); ++it )
  67.         {
  68.             if( mapNodeDistance.find( (*it) )->second.first < currSmallest )
  69.             {
  70.                 currSmallest = mapNodeDistance.find( (*it) )->second.first;
  71.                 pCurrNode = (*it);
  72.             }
  73.         }
  74.  
  75.         // Remove this node from the vector:
  76.         vecGraphCopy.erase( std::find( vecGraphCopy.begin(), vecGraphCopy.end(), pCurrNode ) );
  77.  
  78.     }
  79.  
  80.     // Go from the end node to the start node using the previous node we've associated
  81.     // with each node:
  82.     Node *pCurr = pCurrNode, *pNext = nullptr;
  83.     while( pCurr != pStart )
  84.     {
  85.         pNext = mapNodeDistance.find( pCurr )->second.second;
  86.  
  87.         Arc* pArc = nullptr;
  88.         double dbCurrShortest = DBL_MAX;
  89.         for( auto it = pCurr->vecArcs.begin(); it != pCurr->vecArcs.end(); ++it )
  90.         {
  91.             if( ((*it)->pN1 == pCurr || (*it)->pN1 == pNext) && ((*it)->pN2 == pCurr || (*it)->pN2 == pNext) && (*it)->dbWeight < DBL_MAX )
  92.             {
  93.                 pArc = (*it);
  94.                 dbCurrShortest = (*it)->dbWeight;
  95.             }
  96.         }
  97.  
  98.         // Add the arc to the vector:
  99.         vecArcs.insert( vecArcs.begin(), pArc );
  100.  
  101.         pCurr = pNext;
  102.  
  103.     }
  104.  
  105.     return mapNodeDistance.find( pEnd )->second.first;
  106. }
  107.  
  108. int main() {
  109.     Node A, B, C, D, E, F;
  110.     Arc AB, AC, CD, BD, BE, EF, DF;
  111.  
  112.     AB.pN1 = &A;
  113.     AB.pN2 = &B;
  114.     AC.pN1 = &A;
  115.     AC.pN2 = &C;
  116.     CD.pN1 = &C;
  117.     CD.pN2 = &D;
  118.     BD.pN1 = &B;
  119.     BD.pN2 = &D;
  120.     BE.pN1 = &B;
  121.     BE.pN2 = &E;
  122.     EF.pN1 = &E;
  123.     EF.pN2 = &F;
  124.     DF.pN1 = &D;
  125.     DF.pN2 = &F;
  126.  
  127.     AB.dbWeight = 9.0;
  128.     AC.dbWeight = 11.0;
  129.     CD.dbWeight = 5.0;
  130.     DF.dbWeight = 2.0;
  131.     BE.dbWeight = 7.0;
  132.     BD.dbWeight = 6.0;
  133.     EF.dbWeight = 3.0;
  134.  
  135.     A.szName = "A";
  136.     B.szName = "B";
  137.     C.szName = "C";
  138.     D.szName = "D";
  139.     E.szName = "E";
  140.     F.szName = "F";
  141.  
  142.     A.vecArcs.push_back( &AB );
  143.     A.vecArcs.push_back( &AC );
  144.     B.vecArcs.push_back( &AB );
  145.     B.vecArcs.push_back( &BD );
  146.     B.vecArcs.push_back( &BE );
  147.     C.vecArcs.push_back( &AC );
  148.     C.vecArcs.push_back( &CD );
  149.     D.vecArcs.push_back( &BD );
  150.     D.vecArcs.push_back( &CD );
  151.     D.vecArcs.push_back( &DF );
  152.     E.vecArcs.push_back( &BE );
  153.     E.vecArcs.push_back( &EF );
  154.     F.vecArcs.push_back( &EF );
  155.     F.vecArcs.push_back( &DF );
  156.  
  157.     g_vecNodes.push_back( &A );
  158.     g_vecNodes.push_back( &B );
  159.     g_vecNodes.push_back( &C );
  160.     g_vecNodes.push_back( &D );
  161.     g_vecNodes.push_back( &E );
  162.     g_vecNodes.push_back( &F );
  163.  
  164.     std::vector<Arc*> vecArcs;
  165.     std::cout << "The shortest distace is: " << Dijikstra( vecArcs, &A, &F ) << " going along: " << std::endl;
  166.  
  167.     for( auto it = vecArcs.begin(); it != vecArcs.end(); ++it )
  168.     {
  169.         std::cout << (*it)->pN1->szName << (*it)->pN2->szName << std::endl;
  170.     }
  171.  
  172.     std::cin.ignore( 256, '\n' );
  173.     std::cin.get();
  174.  
  175.     return 0;
  176.  
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement