00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "alg/mstaccess.h"
00029 #include "base/memory.hpp"
00030 #include "base/common.hpp"
00031 #include "base/vector.hpp"
00032 #include "base/map.hpp"
00033 #include "base/stack.hpp"
00034 #include "base/list.hpp"
00035
00036 #include "alg/mst.hpp"
00037
00038 BEGIN_TERIMBER_NAMESPACE
00039 #pragma pack(4)
00040
00042 class cluster_engine_impl : public cluster_engine
00043 {
00044 public:
00046 cluster_engine_impl() :
00047 _client(0)
00048 {
00049 }
00050
00052 virtual
00053 void
00054 do_clustering( const cluster_client* client,
00055 double max_vertex_distance,
00056 double max_cluster_distance,
00057 double avg_cluster_distance
00058 )
00059 {
00060 _clusters.clear();
00061 _all.clear_all();
00062
00063 if (!client)
00064 return;
00065
00066 _client = client;
00067
00068 cluster_processor< cluster_engine_impl, cluster_engine_impl >
00069 processor(*this, *this, max_vertex_distance, max_cluster_distance, avg_cluster_distance);
00070 const cluster_map_t& clusters = processor.get_clusters();
00071
00072
00073 for (cluster_map_t::const_iterator iter = clusters.begin(); iter != clusters.end(); ++iter)
00074 {
00075 cluster_list_t dummy;
00076 cluster_map_t::iterator it = _clusters.insert(_all, iter.key(), dummy).first;
00077 for (cluster_list_t::const_iterator liter = iter->begin(); liter != iter->end(); ++liter)
00078 {
00079 it->push_back(_all, *liter);
00080 }
00081 }
00082 }
00083
00085 virtual
00086 size_t
00087 get_clusters_count() const
00088 {
00089 return _clusters.size();
00090 }
00091
00093 virtual
00094 size_t
00095 get_cluster_size(size_t cluster_index
00096 ) const
00097 {
00098 if (cluster_index < 0 || cluster_index >= _clusters.size())
00099 return os_minus_one;
00100
00101
00102 cluster_map_t::const_iterator iter = _clusters.find(cluster_index);
00103
00104 return iter->size();
00105
00106 }
00107
00109 virtual
00110 size_t
00111 get_cluster_object(size_t cluster_index,
00112 size_t object_index
00113 ) const
00114 {
00115 if (cluster_index < 0 || cluster_index >= _clusters.size())
00116 return os_minus_one;
00117
00118
00119 cluster_map_t::const_iterator iter = _clusters.find(cluster_index);
00120
00121 if (object_index < 0 || object_index >= iter->size())
00122 return os_minus_one;
00123
00124 size_t i = 0;
00125 for (cluster_list_t::const_iterator liter = iter->begin(); liter != iter->end(); ++liter, ++i)
00126 {
00127 if (i == object_index)
00128 return *liter;
00129 }
00130
00131 return os_minus_one;
00132 }
00133
00135 inline
00136 size_t
00137 size() const
00138 {
00139 return _client->size();
00140 }
00141
00143 inline
00144 double
00145 distance( size_t from,
00146 size_t to
00147 ) const
00148 {
00149 return _client->distance(from, to);
00150 }
00151
00153 inline
00154 void
00155 notify( const char* msg
00156 ) const
00157 {
00158 _client->notify(msg);
00159 }
00160 private:
00161 const cluster_client* _client;
00162 cluster_map_t _clusters;
00163 byte_allocator _all;
00164 };
00165
00166
00167 #pragma pack()
00168 END_TERIMBER_NAMESPACE
00169
00170
00171 cluster_engine*
00172 cluster_engine_factory::get_cluster_engine()
00173 {
00174 return new TERIMBER::cluster_engine_impl();
00175 }