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++; } } }
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; }