//Alt. version of buildPath() std::list< std::list<Node>::iterator > Graph::buildPath2(std::list<Node>::iterator pbaseNode, std::list<Node>::iterator ptargetNode) { std::list< std::list<Node>::iterator > emptyPath; std::list< std::list<Node>::iterator > path; path.push_back(pbaseNode); //make sure iterators are valid std::list<Node>::iterator pnull = std::list<Node>::iterator(NULL); if (pbaseNode == pnull || ptargetNode == pnull) { std::cout << "\nFALSE BUILD2 RETURN (null iterators)"; return path; } std::vector<short> baseWord = pbaseNode->getElemName(); std::vector<short> targetWord = ptargetNode->getElemName(); //target word must be longer than or equal length as base word if (targetWord.size() < baseWord.size()) return emptyPath; //should never touch the identity; this is a special case which is handled in initial step if (baseWord[0] == 0 || targetWord[0] == 0) return emptyPath; //if words are identical there's nothing to do if (baseWord == targetWord) return path; //At this point we know the nodes exist, their words have appropriate sizes, they're not the identity, //and they're not equal. But we could still have the problem that the base word is not contained //in the leftmost portion of the target word, so we check for that. bool baseContained = true; int i; for (i = 0; i < baseWord.size() - 1; i++) //up until the last letter, each exponent identical if (baseWord[i] != targetWord[i]) baseContained = false; if (baseWord[i] > targetWord[i]) //on the last letter, the exponent in base may be less or equal baseContained = false; if (baseContained == false) return emptyPath; //Now we know that we can build a valid path from the base node to the target node. //this first part handles the first exponent on baseWord if it doesn't match targetWord std::list<Node>::iterator pcurrentNode = pbaseNode; //will be updated to point to the farthest node in the path if (baseWord[i] < targetWord[i]) { if (i % 2 == 0) //if baseWord[i] is an exponent of x for (int j = baseWord[i]; j <= targetWord[i]; j++) { pcurrentNode = buildXprod(pcurrentNode); path.push_back(pcurrentNode); } else //if baseWord[i] is an exponent of y for (int j = baseWord[i]; j <= targetWord[i]; j++) { pcurrentNode = buildYprod(pcurrentNode); path.push_back(pcurrentNode); } } //now build the path up to the last exponent of targetWord (handled specially below) //note: i currently points to the last letter in baseWord, so it must be incremented to start one after that i++; for (i = i; i < targetWord.size() - 1; i++) { if (i % 2 == 0) //if targetWord[i] is an exponent of x for (int j = 1; j <= targetWord[i]; j++) { pcurrentNode = buildXprod(pcurrentNode); path.push_back(pcurrentNode); } else //if targetWord[i] is an exponent of y for (int j = 1; j <= targetWord[i]; j++) { pcurrentNode = buildYprod(pcurrentNode); path.push_back(pcurrentNode); } } //now build the last exponent, up to the last product. since using buildXprod, it's safe //to "build" the targetWord, but we won't do it anyway if (i % 2 == 0) { for (int j = 1; j < targetWord[i]; j++) { pcurrentNode = buildXprod(pcurrentNode); path.push_back(pcurrentNode); } //link final setXedge(pcurrentNode, ptargetNode); } else //if targetWord[i] is an exponent of y { for (int j = 1; j < targetWord[i]; j++) { pcurrentNode = buildYprod(pcurrentNode); path.push_back(pcurrentNode); } //link final setYedge(pcurrentNode, ptargetNode); } //place final node, targetNode, at the end of the path path.push_back(ptargetNode); return path; }
//Set nodes in path to OPEN void Graph::preservePath(std::list<Node>::iterator pbaseNode, std::list<Node>::iterator ptargetNode) { //make sure iterators are valid std::list<Node>::iterator pnull = std::list<Node>::iterator(NULL); if (pbaseNode == pnull || ptargetNode == pnull) { //std::cout << "\nNULL ITERATORS PASSED TO preservePath()\n"; return; } std::vector<short> baseWord = pbaseNode->getElemName(); std::vector<short> targetWord = ptargetNode->getElemName(); //target word must be longer than or equal length as base word if (targetWord.size() < baseWord.size()) { //std::cout << "\nPRESERVE PATH BAD RETURN1\n"; return; } //should never touch the identity; this is a special case which is handled in initial step if (baseWord[0] == 0 || targetWord[0] == 0) { //std::cout << "\nPRESERVE PATH BAD RETURN2\n"; return; } //if words are identical there's nothing to do if (baseWord == targetWord) { //std::cout << "\nPRESERVE PATH BAD RETURN3\n"; return; } //return; //At this point we know the nodes exist, their words have appropriate sizes, they're not the identity, //and they're not equal. But we could still have the problem that the base word is not contained //in the leftmost portion of the target word, so we check for that. bool baseContained = true; int i; for (i = 0; i < baseWord.size() - 1; i++) //up until the last letter, each exponent identical if (baseWord[i] != targetWord[i]) baseContained = false; if (baseWord[i] > targetWord[i]) //on the last letter, the exponent in base may be less or equal baseContained = false; if (baseContained == false) { std::cout << "\nPRESERVE PATH not contained:\n"; pbaseNode->printWord(); std::cout << "\n"; ptargetNode->printWord(); std::cout << "\n"; return; } //nodes have been checked std::list<Node>::iterator psetNode = ptargetNode; while (targetWord.size() != baseWord.size()) //stop at last exponent of baseWord { int i = targetWord.size() - 1; //always index of last exponent in targetWord int exp = targetWord[i]; //last exponent on targetWord while (exp > 0) { targetWord[i] = exp; psetNode = searchNodes(&targetWord); if (psetNode == std::list<Node>::iterator(NULL)) { std::cout << "\nAttempt to set node via null iterator in preservePath()\n"; return; } if (psetNode->getNodeType() != Node::TEMP && psetNode != ptargetNode) { //it's okay to hit a preserved node, this means the nodes before this one will also //be preserved return; } psetNode->setNodeType(Node::OPEN); exp--; } targetWord.pop_back(); //remove exponent just cleared } int d = targetWord.size() - 1; if (targetWord[d] == baseWord[d]) { if(pbaseNode->isOpen()) psetNode->setNodeType(Node::OPEN); else psetNode->setNodeType(Node::CLOSED); return; } int exp = targetWord[d]; //last exponent on targetWord while (exp > baseWord[d]) { targetWord[d] = exp; psetNode = searchNodes(&targetWord); if (psetNode == std::list<Node>::iterator(NULL)) { std::cout << "\nAttempt to set node via null iterator in preservePath()\n"; return; } if (psetNode->getNodeType() != Node::TEMP) { //again this is not a problem return; } psetNode->setNodeType(Node::OPEN); } if(pbaseNode->isOpen()) psetNode->setNodeType(Node::OPEN); else psetNode->setNodeType(Node::CLOSED); return; }