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