lemon/matrix_maps.h
changeset 2034 b71f8ff62046
parent 1993 2115143eceea
child 2039 dacc4ce9474d
equal deleted inserted replaced
5:c9264da30246 6:36153ee1286a
   207   /// type a value. It increase the size of the container when the 
   207   /// type a value. It increase the size of the container when the 
   208   /// associated graph modified, so it updated automaticly whenever
   208   /// associated graph modified, so it updated automaticly whenever
   209   /// it is needed.
   209   /// it is needed.
   210   template <typename _Graph, typename _Item, typename _Value>
   210   template <typename _Graph, typename _Item, typename _Value>
   211   class DynamicMatrixMap 
   211   class DynamicMatrixMap 
   212     : protected AlterationNotifier<_Item>::ObserverBase {
   212     : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
   213   public:
   213   public:
   214     typedef typename AlterationNotifier<_Item>::ObserverBase Parent;
   214     typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase 
       
   215     Parent;
   215 
   216 
   216     typedef _Graph Graph;
   217     typedef _Graph Graph;
   217     typedef _Item Key;
   218     typedef _Item Key;
   218 
   219 
   219     typedef _Item FirstKey;
   220     typedef _Item FirstKey;
   233 
   234 
   234     /// \brief Creates an item matrix for the given graph
   235     /// \brief Creates an item matrix for the given graph
   235     ///
   236     ///
   236     /// Creates an item matrix for the given graph.
   237     /// Creates an item matrix for the given graph.
   237     DynamicMatrixMap(const Graph& _graph) 
   238     DynamicMatrixMap(const Graph& _graph) 
   238       : graph(_graph), values(size(_graph.maxId(Key()) + 1)) {
   239       : values(size(_graph.maxId(Key()) + 1)) {
   239       Parent::attach(graph.getNotifier(Key()));
   240       Parent::attach(_graph.getNotifier(Key()));
   240     }
   241     }
   241 
   242 
   242     /// \brief Creates an item matrix for the given graph
   243     /// \brief Creates an item matrix for the given graph
   243     ///
   244     ///
   244     /// Creates an item matrix for the given graph and assigns for each
   245     /// Creates an item matrix for the given graph and assigns for each
   245     /// pairs of keys the given parameter.
   246     /// pairs of keys the given parameter.
   246     DynamicMatrixMap(const Graph& _graph, const Value& _val) 
   247     DynamicMatrixMap(const Graph& _graph, const Value& _val) 
   247       : graph(_graph), values(size(_graph.maxId(Key()) + 1), _val) {
   248       : values(size(_graph.maxId(Key()) + 1), _val) {
   248       Parent::attach(graph.getNotifier(Key()));
   249       Parent::attach(_graph.getNotifier(Key()));
   249     }
       
   250 
       
   251     ~DynamicMatrixMap() {
       
   252       if (Parent::attached()) {
       
   253 	Parent::detach();
       
   254       }
       
   255     }
   250     }
   256 
   251 
   257     /// \brief Gives back the value assigned to the \c first - \c second
   252     /// \brief Gives back the value assigned to the \c first - \c second
   258     /// ordered pair.
   253     /// ordered pair.
   259     ///
   254     ///
   260     /// Gives back the value assigned to the \c first - \c second ordered pair.
   255     /// Gives back the value assigned to the \c first - \c second ordered pair.
   261     ConstReference operator()(const Key& first, const Key& second) const {
   256     ConstReference operator()(const Key& first, const Key& second) const {
   262       return values[index(graph.id(first), graph.id(second))];
   257       return values[index(Parent::getNotifier()->id(first), 
       
   258                           Parent::getNotifier()->id(second))];
   263     }
   259     }
   264     
   260     
   265     /// \brief Gives back the value assigned to the \c first - \c second
   261     /// \brief Gives back the value assigned to the \c first - \c second
   266     /// ordered pair.
   262     /// ordered pair.
   267     ///
   263     ///
   268     /// Gives back the value assigned to the \c first - \c second ordered pair.
   264     /// Gives back the value assigned to the \c first - \c second ordered pair.
   269     Reference operator()(const Key& first, const Key& second) {
   265     Reference operator()(const Key& first, const Key& second) {
   270       return values[index(graph.id(first), graph.id(second))];
   266       return values[index(Parent::getNotifier()->id(first), 
       
   267                           Parent::getNotifier()->id(second))];
   271     }
   268     }
   272 
   269 
   273     /// \brief Setter function for the matrix map.
   270     /// \brief Setter function for the matrix map.
   274     ///
   271     ///
   275     /// Setter function for the matrix map.
   272     /// Setter function for the matrix map.
   276     void set(const Key& first, const Key& second, const Value& val) {
   273     void set(const Key& first, const Key& second, const Value& val) {
   277       values[index(graph.id(first), graph.id(second))] = val;
   274       values[index(Parent::getNotifier()->id(first), 
       
   275                    Parent::getNotifier()->id(second))] = val;
   278     }
   276     }
   279 
   277 
   280   protected:
   278   protected:
   281 
   279 
   282     static int index(int i, int j) {
   280     static int index(int i, int j) {
   290     static int size(int s) {
   288     static int size(int s) {
   291       return s * s;
   289       return s * s;
   292     }
   290     }
   293 
   291 
   294     virtual void add(const Key& key) {
   292     virtual void add(const Key& key) {
   295       if (size(graph.id(key) + 1) >= (int)values.size()) {
   293       if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
   296 	values.resize(size(graph.id(key) + 1));	
   294 	values.resize(size(Parent::getNotifier()->id(key) + 1));	
   297       }
   295       }
   298     }
   296     }
   299 
   297 
   300     virtual void erase(const Key&) {}
   298     virtual void erase(const Key&) {}
   301 
   299 
   302     virtual void build() {
   300     virtual void build() {
   303       values.resize(size(graph.maxId(Key()) + 1));
   301       values.resize(size(Parent::getNotifier()->maxId() + 1));
   304     }
   302     }
   305 
   303 
   306     virtual void clear() {
   304     virtual void clear() {
   307       values.clear();
   305       values.clear();
   308     }   
   306     }   
   309     
   307     
   310   private:
   308   private:
   311     const Graph& graph;
       
   312     std::vector<Value> values;
   309     std::vector<Value> values;
   313   };
   310   };
   314 
   311 
   315   /// \brief Container for store values for each unordered pair of graph items
   312   /// \brief Container for store values for each unordered pair of graph items
   316   ///
   313   ///
   318   /// type a value. It increase the size of the container when the 
   315   /// type a value. It increase the size of the container when the 
   319   /// associated graph modified, so it updated automaticly whenever
   316   /// associated graph modified, so it updated automaticly whenever
   320   /// it is needed. 
   317   /// it is needed. 
   321   template <typename _Graph, typename _Item, typename _Value>
   318   template <typename _Graph, typename _Item, typename _Value>
   322   class DynamicSymMatrixMap 
   319   class DynamicSymMatrixMap 
   323     : protected AlterationNotifier<_Item>::ObserverBase {
   320     : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
   324   public:
   321   public:
   325     typedef typename AlterationNotifier<_Item>::ObserverBase Parent;
   322     typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase 
       
   323     Parent;
   326 
   324 
   327     typedef _Graph Graph;
   325     typedef _Graph Graph;
   328     typedef _Item Key;
   326     typedef _Item Key;
   329 
   327 
   330     typedef _Item FirstKey;
   328     typedef _Item FirstKey;
   344 
   342 
   345     /// \brief Creates an item matrix for the given graph
   343     /// \brief Creates an item matrix for the given graph
   346     ///
   344     ///
   347     /// Creates an item matrix for the given graph.
   345     /// Creates an item matrix for the given graph.
   348     DynamicSymMatrixMap(const Graph& _graph) 
   346     DynamicSymMatrixMap(const Graph& _graph) 
   349       : graph(_graph), values(size(_graph.maxId(Key()) + 1)) {
   347       : values(size(_graph.maxId(Key()) + 1)) {
   350       Parent::attach(graph.getNotifier(Key()));
   348       Parent::attach(_graph.getNotifier(Key()));
   351     }
   349     }
   352 
   350 
   353     /// \brief Creates an item matrix for the given graph
   351     /// \brief Creates an item matrix for the given graph
   354     ///
   352     ///
   355     /// Creates an item matrix for the given graph and assigns for each
   353     /// Creates an item matrix for the given graph and assigns for each
   356     /// pairs of keys the given parameter.
   354     /// pairs of keys the given parameter.
   357     DynamicSymMatrixMap(const Graph& _graph, const Value& _val) 
   355     DynamicSymMatrixMap(const Graph& _graph, const Value& _val) 
   358       : graph(_graph), values(size(_graph.maxId(Key()) + 1), _val) {
   356       : values(size(_graph.maxId(Key()) + 1), _val) {
   359       Parent::attach(graph.getNotifier(Key()));
   357       Parent::attach(_graph.getNotifier(Key()));
   360     }
       
   361 
       
   362     ~DynamicSymMatrixMap() {
       
   363       if (Parent::attached()) {
       
   364 	Parent::detach();
       
   365       }
       
   366     }
   358     }
   367 
   359 
   368     /// \brief Gives back the value assigned to the \c first - \c second
   360     /// \brief Gives back the value assigned to the \c first - \c second
   369     /// unordered pair.
   361     /// unordered pair.
   370     ///
   362     ///
   371     /// Gives back the value assigned to the \c first - \c second unordered 
   363     /// Gives back the value assigned to the \c first - \c second unordered 
   372     /// pair.
   364     /// pair.
   373     ConstReference operator()(const Key& first, const Key& second) const {
   365     ConstReference operator()(const Key& first, const Key& second) const {
   374       return values[index(graph.id(first), graph.id(second))];
   366       return values[index(Parent::getNotifier()->id(first), 
       
   367                           Parent::getNotifier()->id(second))];
   375     }
   368     }
   376     
   369     
   377     /// \brief Gives back the value assigned to the \c first - \c second
   370     /// \brief Gives back the value assigned to the \c first - \c second
   378     /// unordered pair.
   371     /// unordered pair.
   379     ///
   372     ///
   380     /// Gives back the value assigned to the \c first - \c second unordered 
   373     /// Gives back the value assigned to the \c first - \c second unordered 
   381     /// pair.
   374     /// pair.
   382     Reference operator()(const Key& first, const Key& second) {
   375     Reference operator()(const Key& first, const Key& second) {
   383       return values[index(graph.id(first), graph.id(second))];
   376       return values[index(Parent::getNotifier()->id(first), 
       
   377                           Parent::getNotifier()->id(second))];
   384     }
   378     }
   385 
   379 
   386     /// \brief Setter function for the matrix map.
   380     /// \brief Setter function for the matrix map.
   387     ///
   381     ///
   388     /// Setter function for the matrix map.
   382     /// Setter function for the matrix map.
   389     void set(const Key& first, const Key& second, const Value& val) {
   383     void set(const Key& first, const Key& second, const Value& val) {
   390       values[index(graph.id(first), graph.id(second))] = val;
   384       values[index(Parent::getNotifier()->id(first), 
       
   385                    Parent::getNotifier()->id(second))] = val;
   391     }
   386     }
   392 
   387 
   393   protected:
   388   protected:
   394 
   389 
   395     static int index(int i, int j) {
   390     static int index(int i, int j) {
   403     static int size(int s) {
   398     static int size(int s) {
   404       return s * (s + 1) / 2;
   399       return s * (s + 1) / 2;
   405     }
   400     }
   406 
   401 
   407     virtual void add(const Key& key) {
   402     virtual void add(const Key& key) {
   408       if (size(graph.id(key) + 1) >= (int)values.size()) {
   403       if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) {
   409 	values.resize(size(graph.id(key) + 1));	
   404 	values.resize(size(Parent::getNotifier()->id(key) + 1));	
   410       }
   405       }
   411     }
   406     }
   412 
   407 
   413     virtual void erase(const Key&) {}
   408     virtual void erase(const Key&) {}
   414 
   409 
   415     virtual void build() {
   410     virtual void build() {
   416       values.resize(size(graph.maxId(Key()) + 1));
   411       values.resize(size(Parent::getNotifier()->maxId() + 1));
   417     }
   412     }
   418 
   413 
   419     virtual void clear() {
   414     virtual void clear() {
   420       values.clear();
   415       values.clear();
   421     }   
   416     }   
   422     
   417     
   423   private:
   418   private:
   424     const Graph& graph;
       
   425     std::vector<Value> values;
   419     std::vector<Value> values;
   426   };
   420   };
   427 
   421 
   428 }
   422 }
   429 
   423