Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GraphUtils.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GraphUtils.cpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "BoardUtils.hpp"
00007 #include "BitsetIterator.hpp"
00008 #include "GraphUtils.hpp"
00009 
00010 using namespace benzene;
00011 
00012 //----------------------------------------------------------------------------
00013 
00014 void GraphUtils::ComputeDigraph(const Groups& groups, HexColor color, 
00015                                 PointToBitset& nbs)
00016 {
00017     nbs.clear();
00018 
00019     // Copy adjacent nbs
00020     HexColorSet not_other = HexColorSetUtil::ColorOrEmpty(color);
00021     for (GroupIterator g(groups, not_other); g; ++g)
00022         nbs[g->Captain()] = groups.Nbs(*g, EMPTY);
00023 
00024     // Go through groups of color
00025     for (GroupIterator g(groups, EMPTY); g; ++g) 
00026     {
00027         for (BitsetIterator nb(groups.Nbs(*g, color)); nb; ++nb) 
00028         {
00029             nbs[g->Captain()] |= nbs[groups.CaptainOf(*nb)];
00030             nbs[g->Captain()].reset(g->Captain());
00031         }
00032     }
00033 }
00034 
00035 //----------------------------------------------------------------------------
00036 
00037 bitset_t GraphUtils::BFS(HexPoint p, PointToBitset& group_nbs,
00038              bitset_t stopSet, int* distFromStart,
00039              int* numShortestPathsThru)
00040 {
00041     // Initialize distances from BFS starting point and number of shortest
00042     // paths through a location (if these values are desired).
00043     bool recordDistance = (distFromStart != NULL);
00044     bool computeFrequency = (numShortestPathsThru != NULL);
00045     HexAssert(recordDistance || !computeFrequency);
00046     
00047     if (recordDistance) {
00048     for (int i=0; i<BITSETSIZE; i++)
00049         distFromStart[i] = NOT_REACHED;
00050     distFromStart[p] = 0;
00051     
00052     if (computeFrequency) {
00053         for (int i=0; i<BITSETSIZE; i++)
00054         numShortestPathsThru[i] = 0;
00055         numShortestPathsThru[p] = 1;
00056     }
00057     }
00058     
00059     // Initialize queue to starting point and alter stop set to exclude start.
00060     bitset_t visited;
00061     std::queue<HexPoint> q;
00062     q.push(p);
00063     visited.set(p);
00064     bitset_t stop = stopSet;
00065     stop.reset(p);
00066     
00067     // Continue BFS until all reachable cells have been visited.
00068     while (!q.empty()) {
00069     // Get next cell on queue
00070     HexPoint curCell = q.front();
00071     q.pop();
00072     
00073     // Do not add this cell's neighbours if it is marked as a stop cell.
00074     if (stop.test(curCell)) continue;
00075     
00076     // Compute current cell's neighbours, and update number of paths this
00077     // cell's neighbours are on.
00078     bitset_t nbs = group_nbs[curCell];
00079     if (computeFrequency) {
00080         for (int i=0; i<BITSETSIZE; i++) {
00081         if (!nbs.test(i)) continue;
00082         if (distFromStart[i] == NOT_REACHED ||
00083             distFromStart[i] > distFromStart[curCell])
00084             numShortestPathsThru[i] += numShortestPathsThru[curCell];
00085         }
00086     }
00087     
00088     // Add previously-unvisited neighbours to queue and mark as visited.
00089     nbs = nbs - visited;
00090     visited |= nbs;
00091         for (BitsetIterator i(nbs); i; ++i) {
00092         q.push(*i);
00093         if (recordDistance)
00094         distFromStart[*i] = distFromStart[curCell] + 1;
00095     }
00096     }
00097     
00098     return visited;
00099 }
00100 
00101 //----------------------------------------------------------------------------


6 Jan 2011 Doxygen 1.6.3