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()); }
void Magnusson::updateNode(Node* n) { // do not try to find best in arc of source as there is none (yields -inf score otherwise) if(n != &graph_->getSourceNode()) n->updateBestInArcAndScore(); if(motionModelScoreFunction_) { Node* predecessor = nullptr; double motionModelScoreDelta = 0.0; Arc* a = n->getBestInArc(); if(a) { predecessor = a->getSourceNode(); } for(Node::ArcIt outArc = n->getOutArcsBegin(); outArc != n->getOutArcsEnd(); ++outArc) { if((*outArc)->getType() == Arc::Move) { Node *predecessorParam = graph_->isSpecialNode(predecessor) ? nullptr : predecessor; Node *nParam = graph_->isSpecialNode(n) ? nullptr : n; Node *targetParam = graph_->isSpecialNode((*outArc)->getTargetNode()) ? nullptr : (*outArc)->getTargetNode(); motionModelScoreDelta = motionModelScoreFunction_(predecessorParam, nParam, targetParam); (*outArc)->update(motionModelScoreDelta); } else { (*outArc)->update(); } } } else { for(Node::ArcIt outArc = n->getOutArcsBegin(); outArc != n->getOutArcsEnd(); ++outArc) { (*outArc)->update(); } } }
void Arc::updateEnabledState() { switch(type_) { case Division: { assert(dependsOnCellInNode_ != nullptr); if(used_ > 0) { // std::cout << "!!!!!!!!!!!!!!!!!!!!!!!! disabling division because it was already used!" << std::endl; enabled_ = false; } else { enabled_ = dependsOnCellInNode_->getCellCount() == 1 && (dependsOnCellInNode_->getDisappearanceArc() == nullptr || dependsOnCellInNode_->getDisappearanceArc()->getUseCount() == 0) && (targetNode_->getAppearanceArc() == nullptr || targetNode_->getAppearanceArc()->getUseCount() == 0) && dependsOnCellInNode_->getNumActiveDivisions() == 0 && dependsOnCellInNode_->getMoveOutArcUsedSum() == 1; if(enabled_) { // make sure that there is no active arc between the mother and daughter candidates yet for(Node::ConstArcIt outArcIt = dependsOnCellInNode_->getOutArcsBegin(); outArcIt != dependsOnCellInNode_->getOutArcsEnd(); ++outArcIt) { if((*outArcIt)->getTargetNode() == targetNode_) { if((*outArcIt)->getUseCount() > 0) { // std::cout << "!!!!!!!!!!!!!!!!!!!!!!!! disabling division because the very same link has been used as transition!" << std::endl; enabled_ = false; } return; } } } } } break; case Swap: { // check that the link that this swap should exchange with is still used: Arc* arcToCut = std::static_pointer_cast<MagnussonSwapArcUserData>(this->getUserData())->getCutArc(); enabled_ = arcToCut->used_ > 0 && arcToCut->getSourceNode()->getNumActiveDivisions() == 0; // check that replacement arcs are enabled enabled_ &= std::static_pointer_cast<MagnussonSwapArcUserData>(this->getUserData())->getReplacementAArc()->isEnabled() && std::static_pointer_cast<MagnussonSwapArcUserData>(this->getUserData())->getReplacementBArc()->isEnabled(); } break; case Appearance: { enabled_ = targetNode_->getMoveInArcUsedSum() == 0; } break; case Disappearance: { enabled_ = sourceNode_->getMoveOutArcUsedSum() == 0 && sourceNode_->getNumActiveDivisions() == 0; } break; case Move: { enabled_ = (targetNode_->getAppearanceArc() == nullptr || targetNode_->getAppearanceArc()->getUseCount() == 0) && (sourceNode_->getDisappearanceArc() == nullptr || sourceNode_->getDisappearanceArc()->getUseCount() == 0) && sourceNode_->getNumActiveDivisions() == 0; } break; default: { enabled_ = true; } } }
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 }