38 #ifndef VIGRA_HIERARCHICAL_CLUSTERING_HXX 
   39 #define VIGRA_HIERARCHICAL_CLUSTERING_HXX 
   48 #include "priority_queue.hxx" 
   49 #include "metrics.hxx" 
   50 #include "merge_graph_adaptor.hxx" 
   58 namespace cluster_operators{
 
   62         class EDGE_INDICATOR_MAP,
 
   69     typedef EdgeWeightedUcm<
 
   79     typedef typename EDGE_INDICATOR_MAP::Value ValueType;
 
   80     typedef ValueType WeightType;
 
   81     typedef MERGE_GRAPH MergeGraph;
 
   82     typedef typename MergeGraph::Graph Graph;
 
   83     typedef typename Graph::Edge BaseGraphEdge;
 
   84     typedef typename Graph::Node BaseGraphNode;
 
   85     typedef typename MergeGraph::Edge Edge;
 
   86     typedef typename MergeGraph::Node Node;
 
   87     typedef typename MergeGraph::EdgeIt EdgeIt;
 
   88     typedef typename MergeGraph::NodeIt NodeIt;
 
   89     typedef typename MergeGraph::IncEdgeIt IncEdgeIt;
 
   90     typedef typename MergeGraph::index_type index_type;
 
   91     typedef MergeGraphItemHelper<MergeGraph,Edge> EdgeHelper;
 
   92     typedef MergeGraphItemHelper<MergeGraph,Node> NodeHelper;
 
   94     typedef typename MergeGraph::MergeNodeCallBackType MergeNodeCallBackType;
 
   95     typedef typename MergeGraph::MergeEdgeCallBackType MergeEdgeCallBackType;
 
   96     typedef typename MergeGraph::EraseEdgeCallBackType EraseEdgeCallBackType;
 
   98     typedef typename EDGE_INDICATOR_MAP::Reference EdgeIndicatorReference;
 
  101         MergeGraph & mergeGraph,
 
  102         EDGE_INDICATOR_MAP edgeIndicatorMap,
 
  103         EDGE_SIZE_MAP edgeSizeMap,
 
  104         NODE_SIZE_MAP nodeSizeMap,
 
  105         MIN_WEIGHT_MAP minWeightEdgeMap,
 
  106         const ValueType wardness=1.0
 
  108     :   mergeGraph_(mergeGraph),
 
  109         edgeIndicatorMap_(edgeIndicatorMap),
 
  110         edgeSizeMap_(edgeSizeMap),
 
  111         nodeSizeMap_(nodeSizeMap),
 
  112         minWeightEdgeMap_(minWeightEdgeMap),
 
  113         pq_(mergeGraph.maxEdgeId()+1),
 
  116         MergeNodeCallBackType cbMn(MergeNodeCallBackType:: template from_method<SelfType,&SelfType::mergeNodes>(
this));
 
  117         MergeEdgeCallBackType cbMe(MergeEdgeCallBackType:: template from_method<SelfType,&SelfType::mergeEdges>(
this));
 
  118         EraseEdgeCallBackType cbEe(EraseEdgeCallBackType:: template from_method<SelfType,&SelfType::eraseEdge>(
this));
 
  120         mergeGraph_.registerMergeNodeCallBack(cbMn);
 
  121         mergeGraph_.registerMergeEdgeCallBack(cbMe);
 
  122         mergeGraph_.registerEraseEdgeCallBack(cbEe);
 
  124         for(EdgeIt e(mergeGraph_);e!=lemon::INVALID;++e){
 
  125             const Edge 
edge = *e;
 
  126             const BaseGraphEdge graphEdge=EdgeHelper::itemToGraphItem(mergeGraph_,edge);
 
  127             const index_type edgeId = mergeGraph_.id(edge);
 
  128             const ValueType currentWeight = this->getEdgeWeight(edge);
 
  129             pq_.push(edgeId,currentWeight);
 
  130             minWeightEdgeMap_[graphEdge]=currentWeight;
 
  134     void setWardness(
const float w){
 
  141         MergeNodeCallBackType cbMn(MergeNodeCallBackType:: template from_method<SelfType,&SelfType::mergeNodes>(
this));
 
  142         MergeEdgeCallBackType cbMe(MergeEdgeCallBackType:: template from_method<SelfType,&SelfType::mergeEdges>(
this));
 
  143         EraseEdgeCallBackType cbEe(EraseEdgeCallBackType:: template from_method<SelfType,&SelfType::eraseEdge>(
this));
 
  145         mergeGraph_.registerMergeNodeCallBack(cbMn);
 
  146         mergeGraph_.registerMergeEdgeCallBack(cbMe);
 
  147         mergeGraph_.registerEraseEdgeCallBack(cbEe);
 
  150         for(EdgeIt e(mergeGraph_);e!=lemon::INVALID;++e){
 
  151             const Edge edge = *e;
 
  152             const BaseGraphEdge graphEdge=EdgeHelper::itemToGraphItem(mergeGraph_,edge);
 
  153             const index_type edgeId = mergeGraph_.id(edge);
 
  154             const ValueType currentWeight = this->getEdgeWeight(edge);
 
  155             pq_.push(edgeId,currentWeight);
 
  156             minWeightEdgeMap_[graphEdge]=currentWeight;
 
  161     void mergeEdges(
const Edge & a,
const Edge & b){
 
  163         const BaseGraphEdge aa=EdgeHelper::itemToGraphItem(mergeGraph_,a);
 
  164         const BaseGraphEdge bb=EdgeHelper::itemToGraphItem(mergeGraph_,b);
 
  165         EdgeIndicatorReference va=edgeIndicatorMap_[aa];
 
  166         EdgeIndicatorReference vb=edgeIndicatorMap_[bb];
 
  167         va*=edgeSizeMap_[aa];
 
  168         vb*=edgeSizeMap_[bb];
 
  171         edgeSizeMap_[aa]+=edgeSizeMap_[bb];
 
  172         va/=(edgeSizeMap_[aa]);
 
  173         vb/=edgeSizeMap_[bb];
 
  175         pq_.deleteItem(b.id());
 
  179     void mergeNodes(
const Node & a,
const Node & b){
 
  180         const BaseGraphNode aa=NodeHelper::itemToGraphItem(mergeGraph_,a);
 
  181         const BaseGraphNode bb=NodeHelper::itemToGraphItem(mergeGraph_,b);
 
  182         nodeSizeMap_[aa]+=nodeSizeMap_[bb];
 
  186     void eraseEdge(
const Edge & edge){
 
  190         pq_.deleteItem(edge.id());
 
  194         const Node newNode = mergeGraph_.inactiveEdgesNode(edge);
 
  198         for (IncEdgeIt e(mergeGraph_,newNode);e!=lemon::INVALID;++e)
 
  201             const Edge incEdge(*e);
 
  204             const BaseGraphEdge incGraphEdge = EdgeHelper::itemToGraphItem(mergeGraph_,incEdge);
 
  209             const ValueType newWeight =    getEdgeWeight(incEdge);
 
  212             pq_.push(incEdge.id(),newWeight);
 
  213             minWeightEdgeMap_[incGraphEdge]=newWeight;
 
  220     Edge contractionEdge(){
 
  221         index_type minLabel = pq_.top();
 
  222         while(mergeGraph_.hasEdgeId(minLabel)==
false){
 
  223             eraseEdge(Edge(minLabel));
 
  224             minLabel = pq_.top();
 
  226         return Edge(minLabel);
 
  230     WeightType contractionWeight(){
 
  231         index_type minLabel = pq_.top();
 
  232         while(mergeGraph_.hasEdgeId(minLabel)==
false){
 
  233             eraseEdge(Edge(minLabel));
 
  234             minLabel = pq_.top();
 
  236         return pq_.topPriority();
 
  242     MergeGraph & mergeGraph(){
 
  248         index_type minLabel = pq_.top();
 
  249         while(mergeGraph_.hasEdgeId(minLabel)==
false){
 
  250             eraseEdge(Edge(minLabel));
 
  251             minLabel = pq_.top();
 
  253         return mergeGraph_.edgeNum()==0 || mergeGraph_.nodeNum()==1;
 
  257     ValueType getEdgeWeight(
const Edge & e){
 
  259         const Node u = mergeGraph_.u(e);
 
  260         const Node v = mergeGraph_.v(e);
 
  262         const BaseGraphEdge ee=EdgeHelper::itemToGraphItem(mergeGraph_,e);
 
  263         const BaseGraphNode uu=NodeHelper::itemToGraphItem(mergeGraph_,u);
 
  264         const BaseGraphNode vv=NodeHelper::itemToGraphItem(mergeGraph_,v);
 
  266         const float sizeU = nodeSizeMap_[uu] ;
 
  267         const float sizeV = nodeSizeMap_[vv] ;
 
  269         const ValueType wardFac = 2.0 / ( 1.0/std::pow(sizeU,wardness_) + 1/std::pow(sizeV,wardness_) );
 
  272         const ValueType fromEdgeIndicator = edgeIndicatorMap_[ee];
 
  273         const ValueType totalWeight = fromEdgeIndicator*wardFac;
 
  278     MergeGraph & mergeGraph_;
 
  279     EDGE_INDICATOR_MAP edgeIndicatorMap_;
 
  280     EDGE_SIZE_MAP edgeSizeMap_;
 
  281     NODE_SIZE_MAP nodeSizeMap_;
 
  282     MIN_WEIGHT_MAP minWeightEdgeMap_;
 
  284     ValueType wardness_;;
 
  317         class EDGE_INDICATOR_MAP,
 
  319         class NODE_FEATURE_MAP,
 
  321         class MIN_WEIGHT_MAP,
 
  338         typedef typename EDGE_INDICATOR_MAP::Value ValueType;
 
  339         typedef ValueType WeightType;
 
  340         typedef MERGE_GRAPH MergeGraph;
 
  341         typedef typename MergeGraph::Graph Graph;
 
  342         typedef typename Graph::Edge BaseGraphEdge;
 
  343         typedef typename Graph::Node BaseGraphNode;
 
  344         typedef typename MergeGraph::Edge Edge;
 
  345         typedef typename MergeGraph::Node Node;
 
  346         typedef typename MergeGraph::EdgeIt EdgeIt;
 
  347         typedef typename MergeGraph::NodeIt NodeIt;
 
  348         typedef typename MergeGraph::IncEdgeIt IncEdgeIt;
 
  349         typedef typename MergeGraph::index_type index_type;
 
  350         typedef MergeGraphItemHelper<MergeGraph,Edge> EdgeHelper;
 
  351         typedef MergeGraphItemHelper<MergeGraph,Node> NodeHelper;
 
  354         typedef typename EDGE_INDICATOR_MAP::Reference EdgeIndicatorReference;
 
  355         typedef typename NODE_FEATURE_MAP::Reference NodeFeatureReference;
 
  358             MergeGraph & mergeGraph,
 
  359             EDGE_INDICATOR_MAP edgeIndicatorMap,
 
  360             EDGE_SIZE_MAP edgeSizeMap,
 
  361             NODE_FEATURE_MAP nodeFeatureMap,
 
  362             NODE_SIZE_MAP nodeSizeMap,
 
  363             MIN_WEIGHT_MAP minWeightEdgeMap,
 
  364             NODE_LABEL_MAP nodeLabelMap,
 
  365             const ValueType beta,
 
  367             const ValueType wardness=static_cast<ValueType>(1.0),
 
  368             const ValueType 
gamma = static_cast<ValueType>(10000000.0),
 
  369             const ValueType sameLabelMultiplier = static_cast<ValueType>(0.8)
 
  371         :   mergeGraph_(mergeGraph),
 
  372             edgeIndicatorMap_(edgeIndicatorMap),
 
  373             edgeSizeMap_(edgeSizeMap),
 
  374             nodeFeatureMap_(nodeFeatureMap),
 
  375             nodeSizeMap_(nodeSizeMap),
 
  376             minWeightEdgeMap_(minWeightEdgeMap),
 
  377             nodeLabelMap_(nodeLabelMap),
 
  378             pq_(mergeGraph.maxEdgeId()+1),
 
  382             sameLabelMultiplier_(sameLabelMultiplier),
 
  384             useStopWeight_(false),
 
  387             typedef typename MergeGraph::MergeNodeCallBackType MergeNodeCallBackType;
 
  388             typedef typename MergeGraph::MergeEdgeCallBackType MergeEdgeCallBackType;
 
  389             typedef typename MergeGraph::EraseEdgeCallBackType EraseEdgeCallBackType;
 
  392             MergeNodeCallBackType cbMn(MergeNodeCallBackType:: template from_method<SelfType,&SelfType::mergeNodes>(
this));
 
  393             MergeEdgeCallBackType cbMe(MergeEdgeCallBackType:: template from_method<SelfType,&SelfType::mergeEdges>(
this));
 
  394             EraseEdgeCallBackType cbEe(EraseEdgeCallBackType:: template from_method<SelfType,&SelfType::eraseEdge>(
this));
 
  396             mergeGraph_.registerMergeNodeCallBack(cbMn);
 
  397             mergeGraph_.registerMergeEdgeCallBack(cbMe);
 
  398             mergeGraph_.registerEraseEdgeCallBack(cbEe);
 
  402             for(EdgeIt e(mergeGraph);e!=lemon::INVALID;++e){
 
  403                 const Edge edge = *e;
 
  404                 const BaseGraphEdge graphEdge=EdgeHelper::itemToGraphItem(mergeGraph_,edge);
 
  405                 const index_type edgeId = mergeGraph_.id(edge);
 
  406                 const ValueType currentWeight = this->getEdgeWeight(edge);
 
  407                 pq_.
push(edgeId,currentWeight);
 
  408                 minWeightEdgeMap_[graphEdge]=currentWeight;
 
  417             const BaseGraphEdge aa=EdgeHelper::itemToGraphItem(mergeGraph_,a);
 
  418             const BaseGraphEdge bb=EdgeHelper::itemToGraphItem(mergeGraph_,b);
 
  419             if(!isLifted_.empty()){
 
  420                 const bool isLiftedA =  isLifted_[mergeGraph_.graph().id(aa)];
 
  421                 const bool isLiftedB =  isLifted_[mergeGraph_.graph().id(bb)];
 
  422                 if(isLiftedA && isLiftedB){
 
  426                 isLifted_[mergeGraph_.graph().id(aa)] = isLiftedA && isLiftedB;
 
  430                 EdgeIndicatorReference va=edgeIndicatorMap_[aa];
 
  431                 EdgeIndicatorReference vb=edgeIndicatorMap_[bb];
 
  432                 va*=edgeSizeMap_[aa];
 
  433                 vb*=edgeSizeMap_[bb];
 
  436                 edgeSizeMap_[aa]+=edgeSizeMap_[bb];
 
  437                 va/=(edgeSizeMap_[aa]);
 
  438                 vb/=edgeSizeMap_[bb];
 
  446             const BaseGraphNode aa=NodeHelper::itemToGraphItem(mergeGraph_,a);
 
  447             const BaseGraphNode bb=NodeHelper::itemToGraphItem(mergeGraph_,b);
 
  448             NodeFeatureReference va=nodeFeatureMap_[aa];
 
  449             NodeFeatureReference vb=nodeFeatureMap_[bb];
 
  450             va*=nodeSizeMap_[aa];
 
  451             vb*=nodeSizeMap_[bb];
 
  453             nodeSizeMap_[aa]+=nodeSizeMap_[bb];
 
  454             va/=(nodeSizeMap_[aa]);
 
  455             vb/=nodeSizeMap_[bb];
 
  459             const UInt32 labelA = nodeLabelMap_[aa];
 
  460             const UInt32 labelB = nodeLabelMap_[bb];
 
  462             if(labelA!=0 && labelB!=0 && labelA!=labelB){
 
  463                 throw std::runtime_error(
"both nodes have labels");
 
  466                 const UInt32 newLabel  = std::max(labelA, labelB);
 
  467                 nodeLabelMap_[aa] = newLabel;
 
  480             const Node newNode = mergeGraph_.inactiveEdgesNode(edge);
 
  485             for (IncEdgeIt e(mergeGraph_,newNode);e!=lemon::INVALID;++e){
 
  488                 const Edge incEdge(*e);
 
  491                 const BaseGraphEdge incGraphEdge = EdgeHelper::itemToGraphItem(mergeGraph_,incEdge);
 
  496                 const ValueType newWeight =    getEdgeWeight(incEdge);
 
  502                 pq_.
push(incEdge.id(),newWeight);
 
  503                 minWeightEdgeMap_[incGraphEdge]=newWeight;
 
  511             index_type minLabel = pq_.
top();
 
  512             while(mergeGraph_.hasEdgeId(minLabel)==
false){
 
  514                 minLabel = pq_.
top();
 
  517             if(!isLifted_.empty()){
 
  518                 if(isLifted_[minLabel])
 
  519                     throw std::runtime_error(
"use lifted edges only if you are DerThorsten or know what you are doing\n");
 
  521             return Edge(minLabel);
 
  526             index_type minLabel = pq_.
top();
 
  527             while(mergeGraph_.hasEdgeId(minLabel)==
false){
 
  529                 minLabel = pq_.
top();
 
  542             index_type minLabel = pq_.
top();
 
  543             while(mergeGraph_.hasEdgeId(minLabel)==
false){
 
  545                 minLabel = pq_.
top();
 
  549                 if(p >= stopWeight_){
 
  557         void setLiftedEdges(ITER idsBegin, ITER idsEnd){
 
  558             if(isLifted_.size()<std::size_t(mergeGraph_.graph().maxEdgeId()+1)){
 
  559                 isLifted_.resize(mergeGraph_.graph().maxEdgeId()+1,
false);
 
  560                 std::fill(isLifted_.begin(), isLifted_.end(), 
false);
 
  562             while(idsBegin!=idsEnd){
 
  563                 isLifted_[*idsBegin] = 
true;
 
  565                 const ValueType currentWeight = this->getEdgeWeight(Edge(*idsBegin));
 
  566                 pq_.
push(*idsBegin,currentWeight);
 
  567                 minWeightEdgeMap_[mergeGraph_.graph().edgeFromId(*idsBegin)]=currentWeight;
 
  572         void enableStopWeight(
const ValueType stopWeight){
 
  573             useStopWeight_ = 
true;
 
  574             stopWeight_ = stopWeight;
 
  577         ValueType getEdgeWeight(
const Edge & e){
 
  578             const BaseGraphEdge ee=EdgeHelper::itemToGraphItem(mergeGraph_,e);
 
  579             if(!isLifted_.empty() && isLifted_[mergeGraph_.graph().id(ee)]){
 
  583             const Node u = mergeGraph_.u(e);
 
  584             const Node v = mergeGraph_.v(e);
 
  586             const BaseGraphNode uu=NodeHelper::itemToGraphItem(mergeGraph_,u);
 
  587             const BaseGraphNode vv=NodeHelper::itemToGraphItem(mergeGraph_,v);
 
  589             const float sizeU = nodeSizeMap_[uu];
 
  590             const float sizeV = nodeSizeMap_[vv];
 
  593             const ValueType wardFac = 2.0 / ( 1.0/std::pow(sizeU,wardness_) + 1/std::pow(sizeV,wardness_) );
 
  595             const ValueType fromEdgeIndicator = edgeIndicatorMap_[ee];
 
  596             ValueType fromNodeDist = metric_(nodeFeatureMap_[uu],nodeFeatureMap_[vv]);
 
  597             ValueType totalWeight = ((1.0-beta_)*fromEdgeIndicator + beta_*fromNodeDist)*wardFac;
 
  600             const UInt32 labelA = nodeLabelMap_[uu];
 
  601             const UInt32 labelB = nodeLabelMap_[vv];
 
  603             if(labelA!=0 && labelB!=0){
 
  604                 if(labelA == labelB){
 
  605                     totalWeight*=sameLabelMultiplier_;
 
  608                     totalWeight += gamma_;
 
  615         MergeGraph & mergeGraph_;
 
  616         EDGE_INDICATOR_MAP edgeIndicatorMap_;
 
  617         EDGE_SIZE_MAP edgeSizeMap_;
 
  618         NODE_FEATURE_MAP nodeFeatureMap_;
 
  619         NODE_SIZE_MAP nodeSizeMap_;
 
  620         MIN_WEIGHT_MAP minWeightEdgeMap_;
 
  621         NODE_LABEL_MAP nodeLabelMap_;
 
  626         ValueType sameLabelMultiplier_;
 
  627         metrics::Metric<float> metric_;
 
  629         std::vector<bool> isLifted_;
 
  631         ValueType stopWeight_;
 
  651         const size_t      nodeNumStopCond = 1,
 
  652         const bool        buildMergeTree  = 
false,
 
  654     : nodeNumStopCond_ (nodeNumStopCond)
 
  655     , maxMergeWeight_(NumericTraits<double>::max())
 
  656     , nodeFeatureImportance_(0.5)
 
  657     , sizeImportance_(1.0)
 
  659     , buildMergeTreeEncoding_(buildMergeTree)
 
  669         nodeNumStopCond_ = count;
 
  679         maxMergeWeight_ = val;
 
  692         vigra_precondition(0.0 <= val && val <= 1.0,
 
  693             "ClusteringOptions::nodePropertyImportance(val): 0 <= val <= 1 required.");
 
  694         nodeFeatureImportance_ = val;
 
  708         vigra_precondition(0.0 <= val && val <= 1.0,
 
  709             "ClusteringOptions::sizeImportance(val): 0 <= val <= 1 required.");
 
  710         sizeImportance_ = val;
 
  724         nodeFeatureMetric_ = metric;
 
  730         buildMergeTreeEncoding_ = val;
 
  744     size_t nodeNumStopCond_;
 
  745     double maxMergeWeight_;
 
  746     double nodeFeatureImportance_;
 
  747     double sizeImportance_;
 
  749     bool   buildMergeTreeEncoding_;
 
  754 template< 
class CLUSTER_OPERATOR>
 
  755 class HierarchicalClusteringImpl
 
  758     typedef CLUSTER_OPERATOR                        ClusterOperator;
 
  759     typedef typename ClusterOperator::MergeGraph    MergeGraph;
 
  760     typedef typename MergeGraph::Graph              Graph;
 
  761     typedef typename Graph::Edge                    BaseGraphEdge;
 
  762     typedef typename Graph::Node                    BaseGraphNode;
 
  763     typedef typename MergeGraph::Edge               Edge;
 
  764     typedef typename MergeGraph::Node               Node;
 
  765     typedef typename CLUSTER_OPERATOR::WeightType   ValueType;
 
  766     typedef typename MergeGraph::index_type         MergeGraphIndexType;
 
  768     typedef ClusteringOptions Parameter;
 
  772             const MergeGraphIndexType  a,
 
  773             const MergeGraphIndexType  b,
 
  774             const MergeGraphIndexType  r,
 
  777         a_(a),b_(b),r_(r),w_(w){
 
  779         MergeGraphIndexType a_;
 
  780         MergeGraphIndexType b_;
 
  781         MergeGraphIndexType r_;
 
  785     typedef std::vector<MergeItem> MergeTreeEncoding;
 
  788     HierarchicalClusteringImpl(
 
  789         ClusterOperator & clusterOperator,
 
  790         const Parameter & parameter = Parameter()
 
  793         clusterOperator_(clusterOperator),
 
  795         mergeGraph_(clusterOperator_.mergeGraph()),
 
  796         graph_(mergeGraph_.graph()),
 
  797         timestamp_(graph_.maxNodeId()+1),
 
  799         timeStampIndexToMergeIndex_(),
 
  800         mergeTreeEndcoding_()
 
  802         if(param_.buildMergeTreeEncoding_){
 
  805             mergeTreeEndcoding_.reserve(graph_.nodeNum()*2);
 
  806             toTimeStamp_.resize(graph_.maxNodeId()+1);
 
  807             timeStampIndexToMergeIndex_.resize(graph_.maxNodeId()+1);
 
  808             for(MergeGraphIndexType nodeId=0;nodeId<=mergeGraph_.maxNodeId();++nodeId){
 
  809                 toTimeStamp_[nodeId]=nodeId;
 
  821         while(mergeGraph_.nodeNum()>param_.nodeNumStopCond_ && mergeGraph_.edgeNum()>0 && !clusterOperator_.done()){
 
  823             const Edge edgeToRemove = clusterOperator_.contractionEdge();
 
  824             if(param_.buildMergeTreeEncoding_){
 
  825                 const MergeGraphIndexType uid = mergeGraph_.id(mergeGraph_.u(edgeToRemove));
 
  826                 const MergeGraphIndexType vid = mergeGraph_.id(mergeGraph_.v(edgeToRemove));
 
  827                 const ValueType w             = clusterOperator_.contractionWeight();
 
  829                 mergeGraph_.contractEdge( edgeToRemove);
 
  830                 const MergeGraphIndexType aliveNodeId = mergeGraph_.hasNodeId(uid) ? uid : vid;
 
  831                 const MergeGraphIndexType deadNodeId  = aliveNodeId==vid ? uid : vid;
 
  832                 timeStampIndexToMergeIndex_[timeStampToIndex(timestamp_)]=mergeTreeEndcoding_.size();
 
  833                 mergeTreeEndcoding_.push_back(MergeItem( toTimeStamp_[aliveNodeId],toTimeStamp_[deadNodeId],timestamp_,w));
 
  834                 toTimeStamp_[aliveNodeId]=timestamp_;
 
  840                 mergeGraph_.contractEdge( edgeToRemove );
 
  842             if(param_.verbose_ && mergeGraph_.nodeNum()%1==0){
 
  843                 std::cout<<
"\rNodes: "<<std::setw(10)<<mergeGraph_.nodeNum()<<std::flush;
 
  852     const MergeTreeEncoding & mergeTreeEndcoding()
const{
 
  853         return mergeTreeEndcoding_;
 
  856     template<
class EDGE_MAP>
 
  857     void ucmTransform(EDGE_MAP & edgeMap)
const{
 
  858         typedef typename Graph::EdgeIt  BaseGraphEdgeIt;
 
  860         for(BaseGraphEdgeIt iter(graph()); iter!=lemon::INVALID; ++iter ){
 
  861             const BaseGraphEdge edge=*iter;
 
  862             edgeMap[
edge] = edgeMap[mergeGraph().reprGraphEdge(edge)];
 
  867     template<
class OUT_ITER>
 
  868     size_t leafNodeIds(
const MergeGraphIndexType treeNodeId, OUT_ITER begin)
const{
 
  869         if(treeNodeId<=graph_.maxNodeId()){
 
  876             std::queue<MergeGraphIndexType>     queue;
 
  877             queue.push(treeNodeId);
 
  879             while(!queue.empty()){
 
  881                 const MergeGraphIndexType 
id = queue.front();
 
  883                 const MergeGraphIndexType mergeIndex = timeStampToMergeIndex(
id);
 
  884                 const MergeGraphIndexType ab[]= { mergeTreeEndcoding_[mergeIndex].a_, mergeTreeEndcoding_[mergeIndex].b_};
 
  886                 for(
size_t i=0;i<2;++i){
 
  887                     if(ab[i]<=graph_.maxNodeId()){
 
  902     const Graph & graph()
const{
 
  907     const MergeGraph & mergeGraph()
const{
 
  912     const MergeGraphIndexType reprNodeId(
const MergeGraphIndexType 
id)
const{
 
  913         return mergeGraph_.reprNodeId(
id);
 
  917     MergeGraphIndexType timeStampToIndex(
const MergeGraphIndexType timestamp)
const{
 
  918         return timestamp- graph_.maxNodeId();
 
  922     MergeGraphIndexType timeStampToMergeIndex(
const MergeGraphIndexType timestamp)
const{
 
  923         return timeStampIndexToMergeIndex_[timeStampToIndex(timestamp)];
 
  927     ClusterOperator & clusterOperator_;
 
  929     MergeGraph & mergeGraph_;
 
  930     const Graph  & graph_;
 
  935     MergeGraphIndexType timestamp_;
 
  936     std::vector<MergeGraphIndexType> toTimeStamp_;
 
  937     std::vector<MergeGraphIndexType> timeStampIndexToMergeIndex_;
 
  939     MergeTreeEncoding mergeTreeEndcoding_;
 
 1042 template <
class GRAPH,
 
 1043           class EDGE_WEIGHT_MAP,  
class EDGE_LENGTH_MAP,
 
 1044           class NODE_FEATURE_MAP, 
class NOSE_SIZE_MAP,
 
 1045           class NODE_LABEL_MAP>
 
 1048                        EDGE_WEIGHT_MAP 
const & edgeWeights, EDGE_LENGTH_MAP 
const & edgeLengths,
 
 1049                        NODE_FEATURE_MAP 
const & nodeFeatures, NOSE_SIZE_MAP 
const & nodeSizes,
 
 1050                        NODE_LABEL_MAP & labelMap,
 
 1051                        ClusteringOptions options = ClusteringOptions())
 
 1053     typedef typename NODE_LABEL_MAP::Value LabelType;
 
 1054     typedef MergeGraphAdaptor<GRAPH> MergeGraph;
 
 1055     typedef typename GRAPH::template EdgeMap<float>     EdgeUltrametric;
 
 1056     typedef typename GRAPH::template NodeMap<LabelType> NodeSeeds;
 
 1058     MergeGraph mergeGraph(graph);
 
 1063     EdgeUltrametric edgeUltrametric(graph);
 
 1064     NodeSeeds nodeSeeds(graph);
 
 1068     typedef cluster_operators::EdgeWeightNodeFeatures<
 
 1078     MergeOperator mergeOperator(mergeGraph,
 
 1079                                 edgeWeights, edgeLengths,
 
 1080                                 nodeFeatures, nodeSizes,
 
 1081                                 edgeUltrametric, nodeSeeds,
 
 1082                                 options.nodeFeatureImportance_,
 
 1083                                 options.nodeFeatureMetric_,
 
 1084                                 options.sizeImportance_,
 
 1085                                 options.maxMergeWeight_);
 
 1087     typedef HierarchicalClusteringImpl<MergeOperator> Clustering;
 
 1089     Clustering clustering(mergeOperator, options);
 
 1090     clustering.cluster();
 
 1092     for(
typename GRAPH::NodeIt node(graph); node != lemon::INVALID; ++node)
 
 1094         labelMap[*node] = mergeGraph.reprNodeId(graph.id(*node));
 
 1102 #endif // VIGRA_HIERARCHICAL_CLUSTERING_HXX 
This Cluster Operator is a MONSTER. It can really do a lot. 
Definition: hierarchical_clustering.hxx:324
MergeGraph & mergeGraph()
get a reference to the merge 
Definition: hierarchical_clustering.hxx:537
ClusteringOptions & minRegionCount(size_t count)
Definition: hierarchical_clustering.hxx:667
priority_type topPriority() const 
get top priority 
Definition: priority_queue.hxx:496
ClusteringOptions & sizeImportance(double val)
Definition: hierarchical_clustering.hxx:706
ClusteringOptions & maxMergeDistance(double val)
Definition: hierarchical_clustering.hxx:677
ClusteringOptions & verbose(bool val=true)
Definition: hierarchical_clustering.hxx:738
Manhattan distance (L1 norm) 
Definition: metrics.hxx:236
Options object for hierarchical clustering. 
Definition: hierarchical_clustering.hxx:646
ClusteringOptions & nodeFeatureImportance(double val)
Definition: hierarchical_clustering.hxx:690
void push(const value_type i, const priority_type p)
Insert a index with a given priority. 
Definition: priority_queue.hxx:475
MetricType
Tags to select a metric for vector distance computation. 
Definition: metrics.hxx:229
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
WeightType contractionWeight()
get the edge weight of the edge which should be contracted next 
Definition: hierarchical_clustering.hxx:525
void hierarchicalClustering(...)
Reduce the number of nodes in a graph by iteratively contracting the cheapest edge. 
EdgeWeightNodeFeatures(MergeGraph &mergeGraph, EDGE_INDICATOR_MAP edgeIndicatorMap, EDGE_SIZE_MAP edgeSizeMap, NODE_FEATURE_MAP nodeFeatureMap, NODE_SIZE_MAP nodeSizeMap, MIN_WEIGHT_MAP minWeightEdgeMap, NODE_LABEL_MAP nodeLabelMap, const ValueType beta, const metrics::MetricType metricType, const ValueType wardness=static_cast< ValueType >(1.0), const ValueType gamma=static_cast< ValueType >(10000000.0), const ValueType sameLabelMultiplier=static_cast< ValueType >(0.8))
construct cluster operator 
Definition: hierarchical_clustering.hxx:357
void mergeEdges(const Edge &a, const Edge &b)
will be called via callbacks from mergegraph 
Definition: hierarchical_clustering.hxx:414
void eraseEdge(const Edge &edge)
will be called via callbacks from mergegraph 
Definition: hierarchical_clustering.hxx:472
double gamma(double x)
The gamma function. 
Definition: mathutil.hxx:1587
std::pair< typename vigra::GridGraph< N, DirectedTag >::edge_descriptor, bool > edge(typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &u, typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &v, vigra::GridGraph< N, DirectedTag > const &g)
Return the pair (edge_descriptor, true) when an edge between vertices u and v exists, or (lemon::INVALID, false) otherwise (API: boost). 
Definition: multi_gridgraph.hxx:2990
void deleteItem(const value_type i)
deleqte the priority associated with index i 
Definition: priority_queue.hxx:516
ClusteringOptions & nodeFeatureMetric(metrics::MetricType metric)
Definition: hierarchical_clustering.hxx:722
void mergeNodes(const Node &a, const Node &b)
will be called via callbacks from mergegraph 
Definition: hierarchical_clustering.hxx:445
detail::SelectIntegerType< 32, detail::UnsignedIntTypes >::type UInt32
32-bit unsigned int 
Definition: sized_int.hxx:183
const_reference top() const 
get index with top priority 
Definition: priority_queue.hxx:490
Edge contractionEdge()
get the edge which should be contracted next 
Definition: hierarchical_clustering.hxx:510