예제 #1
0
파일: magnusson.cpp 프로젝트: chaubold/dpct
void Magnusson::backtrack(Node* start, TrackingAlgorithm::Path& p, TrackingAlgorithm::VisitorFunction nodeVisitor)
{
	p.clear();
	Node* current = start;

    while(current != &(graph_->getSourceNode()))
	{
        nodeVisitor(current);
        Arc* bestArc = nullptr;
        if(current == start)
            bestArc = selectorFunction_(current);
        else
            bestArc = current->getBestInArc();

		assert(bestArc != nullptr);
        assert(bestArc->isEnabled());

        if(bestArc->getType() != Arc::Dummy)
            bestArc->markUsed();
		p.push_back(bestArc);
		current = bestArc->getSourceNode();
	}

    nodeVisitor(current);
	std::reverse(p.begin(), p.end());
}
예제 #2
0
파일: magnusson.cpp 프로젝트: chaubold/dpct
void Magnusson::cleanUpUsedSwapArcs(TrackingAlgorithm::Path &p, std::vector<Path>& paths)
{
    std::vector<Arc*> usedSwapArcs;

    // if a swap arc was used, we can find the path that was affected by this and create the two paths after swapping
    bool foundSwapArc = true;
    while(foundSwapArc)
    {
        foundSwapArc = false;
        for(std::vector<Arc*>::reverse_iterator p_it = p.rbegin(); p_it != p.rend(); ++p_it)
        {
            // FIXME: sometimes points to free'd memory location?
            Arc* arc = *p_it;
            if(arc->getType() == Arc::Swap)
            {
                assert(arc->getUserData());
                Arc* arcToRemove = std::static_pointer_cast<MagnussonSwapArcUserData>(arc->getUserData())->getCutArc();
                Arc* replacementP = std::static_pointer_cast<MagnussonSwapArcUserData>(arc->getUserData())->getReplacementAArc();
                Arc* replacementPath = std::static_pointer_cast<MagnussonSwapArcUserData>(arc->getUserData())->getReplacementBArc();
                assert(arcToRemove != nullptr);
                assert(replacementP != nullptr);
                assert(replacementPath != nullptr);

                DEBUG_MSG("Trying to remove swap arc between " << arc->getSourceNode()->getUserData()->toString() << " and " << arc->getTargetNode()->getUserData()->toString());

                for(Path& path : paths)
                {
                    for(Node::ArcIt path_it = path.begin(); path_it != path.end(); ++path_it)
                    {
                        Arc* a = *path_it;

                        if(a == arcToRemove)
                        {
                            // found candidate. store part of original path that will be used by new path
                            Path temp(path_it+1, path.end());

                            for(Node::ArcIt temp_it = temp.begin(); temp_it != temp.end(); ++temp_it)
                            {
                                assert((*temp_it)->getType() != Arc::Swap);
                            }

                            // update original path by appending the replacement arc and the remainder of path P
                            path.erase(path_it, path.end());
                            path.push_back(replacementPath);
                            path.insert(path.end(), p_it.base(), p.end());

                            // update path p
                            p.erase(p_it.base()-1, p.end());
                            p.push_back(replacementP);
                            p.insert(p.end(), temp.begin(), temp.end());

                            if(usedArcsScoreZero_)
                            {
                                replacementPath->markUsed();
                                replacementP->markUsed();
                                // "unuse" the arc that was previously used
                                arcToRemove->markUsed(false);
                            }

                            // remove all this swap arc
                            usedSwapArcs.push_back(arc);
 
#if DEBUG_LOG
                            DEBUG_MSG("updated two paths. removed swap arc between " << arc->getSourceNode()->getUserData()->toString() << " and " << arc->getTargetNode()->getUserData()->toString());
                            graph_->print();
#endif

                            foundSwapArc = true;
                            break;
                        }
                    }

                    if(foundSwapArc)
                        break;
                }

                assert(foundSwapArc);
                break;
            }
        }
    }

    for(Arc* a: usedSwapArcs)
    {
        removeSwapArc(a);
    }

#ifdef DEBUG_LOG
    DEBUG_MSG("Paths after removing swaps:");
    printPath(p);
    for(Path& path : paths)
        printPath(path);

    for(Node::ArcIt p_it = p.begin(); p_it != p.end(); ++p_it)
    {
        assert((*p_it)->getType() != Arc::Swap);
    }
#endif
}