void addLiveNode(int theWeight, int theLevel)
{// Add node whose weight is theWeight to live node queue if not at leaf.
   if (theLevel == numberOfContainers)
   {// feasible leaf
      if (theWeight > maxWeightSoFar)  // better leaf reached
         maxWeightSoFar = theWeight;
    }
   else  // not a leaf
      liveNodeQueue.push(theWeight);
}
void addLiveNode(int theWeight, int theLevel,
                 qNode* theParent, bool leftChild)
{   // Add a live node at level theLevel and having weight theWeight
// to liveNodeQueue if not a leaf. If feasible leaf, set
// bestLoading[numberOfContainers] = 1 iff leftChild is true.
// theParent = parent of new node.
// leftChild is true iff new node is left child of theParent.
    if (theLevel == numberOfContainers)
    {   // feasible leaf
        if (theWeight == maxWeightSoFar)
        {   // best leaf so far
            bestENodeSoFar = theParent;
            bestLoading[numberOfContainers] = (leftChild) ? 1 : 0;
        }
        return;
    }

    // not a leaf, add to queue
    qNode *b = new qNode(theParent, leftChild, theWeight);
    liveNodeQueue.push(b);
}
int maxLoading(int *weight, int theNumberOfContainers, int capacity)
{// FIFO branch-and-bound search of solution space.
 // weight[1:theNumberOfContainers] = container weights
 // capacity = ship capacity
 // Return weight of best loading.
   // initialize global variables
   numberOfContainers = theNumberOfContainers;
   maxWeightSoFar = 0;
   liveNodeQueue.push(-1);  // end-of-level marker

   // initialize for level 1 E-node
   int eNodeLevel = 1;
   int eNodeWeight = 0;

   // search subset space tree
   while (true)
   {
      // check left child of E-node
      if (eNodeWeight + weight[eNodeLevel] <= capacity) 
         // left child
         addLiveNode(eNodeWeight + weight[eNodeLevel], eNodeLevel);

      // right child is always feasible
      addLiveNode(eNodeWeight, eNodeLevel);

      // get next E-node
      eNodeWeight = liveNodeQueue.front();
      liveNodeQueue.pop();
      if (eNodeWeight == -1)
      {// end of level
         if (liveNodeQueue.empty())            // no more live nodes
            return maxWeightSoFar;
         liveNodeQueue.push(-1);               // end-of-level marker
         // get next E-node
         eNodeWeight = liveNodeQueue.front();
         liveNodeQueue.pop();
         eNodeLevel++;
      }
   }
}
示例#4
0
bool findPath()
{// Find a shortest path from start to finish.
 // Return true if successful, false if impossible.

   if ((start.row == finish.row) && (start.col == finish.col))
   {// start == finish
       pathLength = 0;
       return true;
   }

   // initialize offsets
   position offset[4];
   offset[0].row = 0; offset[0].col = 1;   // right
   offset[1].row = 1; offset[1].col = 0;   // down
   offset[2].row = 0; offset[2].col = -1;  // left
   offset[3].row = -1; offset[3].col = 0;  // up
   
   // initialize wall of blocks around the grid
   for (int i = 0; i <= size + 1; i++)
   {
      grid[0][i] = grid[size + 1][i] = 1; // bottom and top
      grid[i][0] = grid[i][size + 1] = 1; // left and right
   }

   position here = start;
   grid[start.row][start.col] = 2; // block
   int numOfNbrs = 4; // neighbors of a grid position
   
   // label reachable grid positions
   arrayQueue<position> q;
   position nbr;
   do 
   {// label neighbors of here
       for (int i = 0; i < numOfNbrs; i++)
       {// check out neighbors of here
          nbr.row = here.row + offset[i].row;
          nbr.col = here.col + offset[i].col;
          if (grid[nbr.row][nbr.col] == 0)
          {// unlabeled nbr, label it
             grid[nbr.row][nbr.col]
                = grid[here.row][here.col] + 1;
             if ((nbr.row == finish.row) &&
                (nbr.col == finish.col)) break; // done
             // put on queue for later expansion
   	        q.push(nbr);
          }
       }
      
      // have we reached finish?
      if ((nbr.row == finish.row) &&
          (nbr.col == finish.col)) break;     // done

      // finish not reached, can we move to a nbr?
      if (q.empty())
         return false;          // no path
      here = q.front();         // get next position
      q.pop();
   } while(true);
            
   // construct path
   pathLength = grid[finish.row][finish.col] - 2;
   path = new position [pathLength];

   // trace backwards from finish
   here = finish;
   for (int j = pathLength - 1; j >= 0; j--)
   {
      path[j] = here;
      // find predecessor position
      for (int i = 0; i < numOfNbrs; i++)
      {
         nbr.row = here.row + offset[i].row;
         nbr.col = here.col + offset[i].col;
         if (grid[nbr.row][nbr.col] == j + 2) break;
      }
      here = nbr;  // move to predecessor
   }

   return true;
}
int maxLoading(int *weight, int theNumberOfContainers, int capacity,
               int *theBestLoading)
{   // FIFO branch-and-bound search of solution space.
// weight[1:theNumberOfContainers] = container weights
// capacity = ship capacity
// theBestLoading[1:theNumberOfContainers] is set to best loading.
// Return weight of best loading.
    // initialize globals
    numberOfContainers = theNumberOfContainers;
    maxWeightSoFar = 0;
    liveNodeQueue.push(NULL);      // end-of-level marker
    qNode *eNode = NULL;
    bestENodeSoFar = NULL;
    bestLoading = theBestLoading;

    // initialize for level 1 E-node
    int eNodeLevel = 1;
    int eNodeWeight = 0;
    int remainingWeight = 0;
    for (int j = 2; j <= numberOfContainers; j++)
        remainingWeight += weight[j];

    // search subset space tree
    while (true)
    {
        // check left child of E-node
        int leftChildWeight = eNodeWeight + weight[eNodeLevel];
        if (leftChildWeight <= capacity)
        {   // feasible left child
            if (leftChildWeight > maxWeightSoFar)
                maxWeightSoFar = leftChildWeight;
            addLiveNode(leftChildWeight, eNodeLevel, eNode, true);
        }

        // check right child
        if (eNodeWeight + remainingWeight > maxWeightSoFar)
            addLiveNode(eNodeWeight, eNodeLevel, eNode, false);

        eNode = liveNodeQueue.front();
        liveNodeQueue.pop();
        if (eNode == NULL)
        {   // end of level
            if (liveNodeQueue.empty()) break;    // no more live nodes
            liveNodeQueue.push(NULL);             // end-of-level pointer
            eNode = liveNodeQueue.front();
            liveNodeQueue.pop();
            eNodeLevel++;
            remainingWeight -= weight[eNodeLevel];
        }

        eNodeWeight = eNode->weight;
    }

    // construct bestLoading[] by following path from
    // bestENodeSoFar to root, bestLoading[numberOfContainers]
    // is set by addLiveNode
    for (int j = numberOfContainers - 1; j > 0; j--)
    {
        bestLoading[j] = (bestENodeSoFar->leftChild) ? 1 : 0;
        bestENodeSoFar = bestENodeSoFar->parent;
    }

    return maxWeightSoFar;
}