Пример #1
0
//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;
}
Пример #2
0
//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;
}