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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_MAT_GRAPH_H
00045 # define TPL_MAT_GRAPH_H
00046
00047 # include <tpl_graph.H>
00048 # include <dyn_sort_utils.H>
00049
00050 using namespace Aleph;
00051
00052 namespace Aleph
00053 {
00054
00055 template <typename GT> inline static
00056 typename GT::Node * get_node(DynArray<typename GT::Node *> nodes,
00057 const long & i)
00058 {
00059
00060 if (i >= nodes.size())
00061 throw std::out_of_range("Index of node out of range");
00062
00063 return nodes.access(i);
00064 }
00065 template <typename GT>
00066 inline static long index_of_node(DynArray<typename GT::Node *> nodes,
00067 const long & n,
00068 typename GT::Node * p)
00069 {
00070 return Aleph::binary_search<typename GT::Node*>(nodes, p, 0, n - 1);
00071 }
00072 inline static long index_array(const long & i, const long & j, const long & n)
00073
00074 {
00075 if (i >= n or j >= n)
00076 throw std::out_of_range("Matrix index out of range");
00077
00078 return i + j*n;
00079 }
00080
00081 template <typename Entry>
00082 inline static Entry * read_matrix(const DynArray<Entry> & mat,
00083 const long & i,
00084 const long & j,
00085 const long & n)
00086 {
00087 const long index = index_array(i, j, n);
00088
00089 if (not mat.exist(index))
00090 return NULL;
00091
00092 return &const_cast<Entry&>(mat.access(index));
00093 }
00094 template <typename Entry>
00095 inline static void write_matrix(DynArray<Entry> & mat,
00096 const long & i,
00097 const long & j,
00098 const long & n,
00099 const Entry & entry)
00100 {
00101 mat[index_array(i, j, n)] = entry;
00102 }
00103
00153 template <typename GT>
00154 class Map_Matrix_Graph
00155 {
00156 public:
00158 typedef GT List_Graph_Type;
00159
00161 typedef typename GT::Node_Type Node_Type;
00162
00164 typedef typename GT::Arc_Type Arc_Type;
00165
00167 typedef typename GT::Node Node;
00168
00170 typedef typename GT::Arc Arc;
00171
00172 private:
00173
00174 DynArray<Node*> nodes;
00175 GT * lgraph;
00176 mutable size_t num_nodes;
00177 struct Mat_Entry
00178 {
00179 Arc * arc;
00180
00181 Mat_Entry(Arc * __arc = NULL) : arc(__arc) { }
00182 };
00183 DynArray<Mat_Entry> mat;
00184
00185 public:
00186
00188 Map_Matrix_Graph(GT & g);
00189
00191 Map_Matrix_Graph(Map_Matrix_Graph & mat);
00193 inline Map_Matrix_Graph & operator = (Map_Matrix_Graph & mat);
00194
00204 inline Map_Matrix_Graph & operator = (GT & g);
00217 inline Node * operator () (const long & i) const;
00232 inline long operator () (Node * node) const;
00252 inline Arc * operator () (Node * src_node, Node * tgt_node) const;
00268 inline Arc * operator () (const long & i, const long & j) const;
00270 GT & get_list_graph() { return *lgraph; }
00273 const size_t & get_num_nodes() const { return num_nodes; }
00276 void copy_list_graph(GT & g);
00277 };
00278
00279 template <class GT>
00280 typename GT::Node * Map_Matrix_Graph<GT>::operator () (const long & i) const
00281 {
00282 return get_node <GT> (nodes, i);
00283 }
00284 template <class GT>
00285 long Map_Matrix_Graph<GT>::operator () (typename GT::Node * node) const
00286 {
00287 return index_of_node <GT> (nodes, num_nodes, node);
00288 }
00289 template <class GT>
00290 typename GT::Arc * Map_Matrix_Graph<GT>::operator () (const long & i,
00291 const long & j) const
00292 {
00293 Mat_Entry * mat_entry = read_matrix<Mat_Entry>(mat, i, j, num_nodes);
00294
00295 if (mat_entry == NULL)
00296 return NULL;
00297
00298 return mat_entry->arc;
00299 }
00300
00301 template <class GT>
00302 typename GT::Arc * Map_Matrix_Graph<GT>::operator () (Node * src_node,
00303 Node * tgt_node) const
00304 {
00305 Mat_Entry * mat_entry =
00306 read_matrix<Mat_Entry>(mat,
00307 index_of_node<GT>(nodes, num_nodes, src_node),
00308 index_of_node<GT>(nodes, num_nodes, tgt_node),
00309 num_nodes);
00310
00311 if (mat_entry == NULL)
00312 return NULL;
00313
00314 return mat_entry->arc;
00315 }
00316 template <class GT>
00317 Map_Matrix_Graph<GT>::Map_Matrix_Graph(GT & g)
00318 : lgraph(&g), num_nodes(g.get_num_nodes())
00319 {
00320 copy_list_graph(g);
00321 }
00322 template <class GT>
00323 Map_Matrix_Graph<GT>::Map_Matrix_Graph
00324 (Map_Matrix_Graph<GT>::Map_Matrix_Graph & mat)
00325 {
00326 copy_list_graph(*(mat.lgraph));
00327 }
00328
00329 template <class GT>
00330 Map_Matrix_Graph<GT>& Map_Matrix_Graph<GT>::operator = (Map_Matrix_Graph & mat)
00331 {
00332 if (this == &mat)
00333 return *this;
00334
00335 copy_list_graph(*(mat.lgraph));
00336
00337 return *this;
00338 }
00339
00340 template <class GT>
00341 Map_Matrix_Graph<GT> & Map_Matrix_Graph<GT>::operator = (GT & g)
00342 {
00343 copy_list_graph(g);
00344 }
00345 template <class GT>
00346 void Map_Matrix_Graph<GT>::copy_list_graph(GT & g)
00347 {
00348
00349 lgraph = &g;
00350 num_nodes = g.get_num_nodes();
00351
00352 nodes.cut();
00353 mat.cut();
00354
00355
00356 int i = 0;
00357 for (typename GT::Node_Iterator it(g); it.has_current(); it.next(), ++i)
00358 nodes[i] = it.get_current_node();
00359
00360 quicksort(nodes);
00361
00362
00363 for (typename GT::Node_Iterator nit(g); nit.has_current(); nit.next())
00364 {
00365 Node * src = nit.get_current_node();
00366
00367 const long src_idx = index_of_node<GT>(nodes, num_nodes, src);
00368
00369
00370 for (typename GT::Node_Arc_Iterator ait(src); ait.has_current(); ait.next())
00371 {
00372 Arc * arc = ait.get_current_arc();
00373
00374 Node * tgt = g.get_connected_node(arc, src);
00375
00376 const long tgt_idx = index_of_node<GT>(nodes, num_nodes, tgt);
00377
00378 write_matrix<Mat_Entry>(mat, src_idx, tgt_idx, num_nodes, arc);
00379 }
00380 }
00381 }
00382
00412 template <typename GT>
00413 class Matrix_Graph
00414 {
00415
00416 public:
00417
00419 typedef GT List_Graph_Type;
00420
00423 typedef typename GT::Node_Type Node_Type;
00424
00427 typedef typename GT::Arc_Type Arc_Type;
00428
00430 typedef typename GT::Node Node;
00431
00433 typedef typename GT::Arc Arc;
00434
00435 private:
00436
00437 DynArray<Node_Type> nodes;
00438 DynArray<Arc_Type> arcs;
00439 mutable size_t n;
00440 mutable Arc_Type Null_Value;
00441 void copy(Matrix_Graph & mat)
00442 {
00443
00444 if (this == &mat)
00445 return;
00446
00447 n = mat.n;
00448 Null_Value = mat.Null_value;
00449
00450 nodes.cut();
00451 arcs.cut();
00452
00453 arcs.set_default_initial_value(Null_Value);
00454
00455 for (int i = 0; i < n; ++i)
00456 {
00457 nodes[i] = mat.nodes[i];
00458
00459 for (int j = 0; j < n; ++j)
00460 {
00461 const long mat_index = index_array(i, j, n);
00462
00463 if (not arcs.exist(mat_index))
00464 continue;
00465
00466 arcs.touch(mat_index) = mat.arcs.access(mat_index);
00467 }
00468 }
00469 }
00470
00471 void copy(GT & g)
00472 {
00473 n = g.get_num_nodes();
00474
00475 DynArray<typename GT::Node *> ptr;
00476
00477 int i = 0;
00478 for (typename GT::Node_Iterator it(g); it.has_current(); it.next(), ++i)
00479 ptr[i] = it.get_current_node();
00480
00481 quicksort(ptr);
00482
00483 arcs.set_default_initial_value(Null_Value);
00484
00485 for (i = 0; i < n; ++i)
00486 {
00487 typename GT::Node * src = ptr[i];
00488
00489 nodes[i] = src->get_info();
00490
00491 for (typename GT::Node_Arc_Iterator it(src);
00492 it.has_current(); it.next())
00493 {
00494 typename GT::Arc * arc = it.get_current_arc();
00495
00496 typename GT::Node * tgt = it.get_tgt_node();
00497
00498 const long j = index_of_node<GT>(ptr, n, tgt);
00499
00500 const long mat_index = index_array(i, j, n);
00501
00502 arcs[mat_index] = arc->get_info();
00503 }
00504 }
00505 }
00506
00507 public:
00508
00510 const size_t & get_num_nodes() const { return n; }
00512 const Arc_Type & null_value() const { return Null_Value; }
00529 Matrix_Graph(GT & g, const Arc_Type & null) : Null_Value(null)
00530 {
00531 copy(g);
00532 }
00541 Matrix_Graph(Matrix_Graph & mat)
00542 {
00543 copy(mat);
00544 }
00557 Matrix_Graph & operator = (Matrix_Graph & mat)
00558 {
00559 copy(mat);
00560
00561 return *this;
00562 }
00563
00577 Matrix_Graph & operator = (GT & g)
00578 {
00579 copy(g);
00580
00581 return *this;
00582 }
00599 const Arc_Type & operator () (const long & i, const long & j) const
00600 {
00601 const long mat_index = index_array(i, j, n);
00602
00603 if (not arcs.exist(mat_index))
00604 return Null_Value;
00605
00606 return arcs.access(mat_index);
00607 }
00617 Node_Type & operator () (const long & i) const
00618 {
00619 if (i >= n)
00620 throw std::out_of_range("node index out of range");
00621
00622 return const_cast<Node_Type &>(nodes.access(i));
00623 }
00624
00641 Arc_Type & operator () (const long & i, const long & j)
00642 {
00643 const long mat_index = index_array(i, j, n);
00644
00645 return arcs.touch(mat_index);
00646 }
00647 };
00648
00675 template <typename GT, typename __Entry_Type>
00676 class Ady_Mat
00677 {
00678
00679 public:
00680
00682 typedef GT List_Graph_Type;
00683
00685 typedef __Entry_Type Entry_Type;
00686
00689 typedef typename GT::Node_Type Node_Type;
00690
00693 typedef typename GT::Arc_Type Arc_Type;
00694
00696 typedef typename GT::Node Node;
00697
00699 typedef typename GT::Arc Arc;
00700
00701 private:
00702
00703 GT * lgraph;
00704 DynArray<Node*> nodes;
00705 DynArray<Entry_Type> mat;
00706 mutable size_t num_nodes;
00707 mutable Entry_Type Null_Value;
00708 void test_same_graph(Ady_Mat & mat)
00709 {
00710 if (lgraph == mat.lgraph)
00711 return;
00712
00713 throw std::domain_error("mat does not refers the same List_Graph than this");
00714 }
00715
00716 void copy_nodes(GT & g)
00717 {
00718 lgraph = &g;
00719 num_nodes = g.get_num_nodes();
00720
00721 nodes.cut();
00722
00723
00724 int i = 0;
00725 for (typename GT::Node_Iterator it(g); it.has_current(); it.next(), ++i)
00726 nodes[i] = it.get_current_node();
00727
00728 quicksort(nodes);
00729 }
00730
00731 Ady_Mat & copy(Ady_Mat & mat)
00732 {
00733 if (this == &mat)
00734 return *this;
00735
00736 test_same_graph(mat);
00737
00738 Null_Value = mat.Null_Value;
00739
00740 copy(mat.lgraph);
00741
00742 return *this;
00743 }
00744
00745 public:
00746
00749 Node * operator () (const long & i) const
00750 {
00751 return Aleph::get_node<GT>(nodes, i);
00752 }
00753
00756 long operator () (Node * node) const
00757 {
00758 return index_of_node<GT>(nodes, num_nodes, node);
00759 }
00760
00775 Entry_Type & operator () (const long & i, const long & j)
00776 {
00777 return mat.touch(index_array(i, j, num_nodes));
00778 }
00779
00794 const Entry_Type & operator () (const long & i, const long & j) const
00795 {
00796 const long index = index_array(i, j, num_nodes);
00797
00798 if (mat.exist(index))
00799 return mat.access(index);
00800
00801 return Null_Value;
00802 }
00803
00821 Entry_Type & operator () (Node * src, Node * tgt)
00822 {
00823 return (*this)(index_of_node <GT> (nodes, num_nodes, src),
00824 index_of_node <GT> (nodes, num_nodes, tgt));
00825 }
00826
00844 const Entry_Type & operator () (Node * src, Node * tgt) const
00845 {
00846 return (*this)(index_of_node <GT> (nodes, num_nodes, src),
00847 index_of_node <GT> (nodes, num_nodes, tgt));
00848 }
00850 GT & get_list_graph() { return *lgraph; }
00851
00853 const Entry_Type & null_value() const { return Null_Value; }
00854
00857 const size_t & get_num_nodes() const { return num_nodes; }
00873 Ady_Mat(GT & g) : lgraph(&g), num_nodes(lgraph->get_num_nodes())
00874 {
00875 copy_nodes(g);
00876 }
00891 Ady_Mat(GT & g, const Entry_Type & null)
00892 : lgraph(&g), num_nodes(lgraph->get_num_nodes()), Null_Value(null)
00893 {
00894 copy_nodes(*lgraph);
00895 }
00897 void set_null_value(const Entry_Type & null)
00898 {
00899 Null_Value = null;
00900 }
00902 Ady_Mat(Ady_Mat & mat)
00903 {
00904 copy(mat);
00905 }
00929 template <class Operation> void operate_all_arcs_list_graph();
00956 template <class Operation> void operate_all_arcs_list_graph(void * ptr);
00976 template <class Operation> void operate_all_arcs_matrix();
00977
00999 template <class Operation> void operate_all_arcs_matrix(void * ptr);
01000 };
01001
01002 template <class GT, typename __Entry_Type>
01003 template <class Operation>
01004 void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_list_graph()
01005 {
01006
01007 for (typename GT::Node_Iterator nit(*lgraph); nit.has_current(); nit.next())
01008 {
01009 Node * src = nit.get_current_node();
01010
01011 const long src_idx =
01012 index_of_node<List_Graph_Type>(nodes, num_nodes, src);
01013
01014
01015 for (typename GT::Node_Arc_Iterator at(src); at.has_current(); at.next())
01016 {
01017 Arc * arc = at.get_current_arc();
01018
01019 const long tgt_idx =
01020 index_of_node<List_Graph_Type>(nodes, num_nodes,
01021 arc->get_tgt_node());
01022
01023 Entry_Type & entry =
01024 mat.touch(index_array(src_idx, tgt_idx, num_nodes));
01025
01026 Operation () (*this, arc, src_idx, tgt_idx, entry);
01027 }
01028 }
01029 }
01030
01031 template <class GT, typename __Entry_Type>
01032 template <class Operation>
01033 void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_matrix()
01034 {
01035 const long & n = num_nodes;
01036
01037 for (int s = 0; s < n; ++s)
01038 {
01039 Node * src_node = get_node<GT>(nodes, s);
01040
01041 for (int t = 0; t < n; ++t)
01042 {
01043 Node * tgt_node = get_node<GT>(nodes, t);
01044
01045 Entry_Type & entry = mat.touch(index_array(s, t, num_nodes));
01046
01047 Operation () (*this, src_node, tgt_node, s, t, entry);
01048 }
01049 }
01050 }
01051 template <class GT, typename __Entry_Type>
01052 template <class Operation>
01053 void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_list_graph(void * ptr)
01054 {
01055
01056 for (typename GT::Node_Iterator nit(*lgraph); nit.has_current(); nit.next())
01057 {
01058 Node * src = nit.get_current_node();
01059
01060 const long src_idx =
01061 index_of_node<List_Graph_Type>(nodes, num_nodes, src);
01062
01063
01064 for (typename GT::Node_Arc_Iterator at(src); at.has_current(); at.next())
01065 {
01066 Arc * arc = at.get_current_arc();
01067
01068 Node * tgt = lgraph->get_tgt_node(arc);
01069
01070 const long tgt_idx =
01071 index_of_node<List_Graph_Type>(nodes, num_nodes, tgt);
01072
01073 Entry_Type & entry =
01074 mat.touch(index_array(src_idx, tgt_idx, num_nodes));
01075
01076 Operation () (*this, arc, src_idx, tgt_idx, entry, ptr);
01077 }
01078 }
01079 }
01080
01081 template <class GT, typename __Entry_Type>
01082 template <class Operation>
01083 void Ady_Mat<GT, __Entry_Type>::operate_all_arcs_matrix(void * ptr)
01084 {
01085 const long & n = num_nodes;
01086
01087 for (int s = 0; s < n; ++s)
01088 {
01089 Node * src_node = get_node<GT>(nodes, s);
01090
01091 for (int t = 0; t < n; ++t)
01092 {
01093 Node * tgt_node = get_node<GT>(nodes, t);
01094
01095 Entry_Type & entry = mat.touch(index_array(s, t, num_nodes));
01096
01097 Operation () (*this, src_node, tgt_node, s, t, entry, ptr);
01098 }
01099 }
01100 }
01101
01121 template <class GT>
01122 class Bit_Mat_Graph
01123 {
01124
01125 public:
01126
01128 typedef GT List_Graph_Type;
01129
01131 typedef typename GT::Node Node;
01132
01134 typedef typename GT::Arc Arc;
01135
01136 private:
01137
01138 BitArray bit_array;
01139 GT * lgraph;
01140 DynArray<typename GT::Node*> nodes;
01141 mutable size_t n;
01142 void copy_list_graph(GT & g)
01143 {
01144 n = g.get_num_nodes();
01145
01146 nodes.cut();
01147
01148
01149 int i = 0;
01150 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
01151 nodes[i++] = static_cast<typename GT::Node*>(it.get_current_node());
01152
01153 quicksort(nodes);
01154
01155 bit_array.resize(n*n);
01156
01157
01158 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
01159 {
01160 typename GT::Node * src = it.get_current_node();
01161
01162 const size_t src_idx =
01163 index_of_node<List_Graph_Type>(nodes, n, src);
01164
01165 for (typename GT::Node_Arc_Iterator jt(src); jt.has_current(); jt.next())
01166 {
01167 typename GT::Node * tgt = jt.get_tgt_node();
01168
01169 const size_t tgt_idx =
01170 index_of_node<List_Graph_Type>(nodes, n, tgt);
01171
01172 bit_array[index_array(src_idx, tgt_idx,n)] = 1;
01173 }
01174 }
01175 }
01176 struct Proxy
01177 {
01178 BitArray & bit_array;
01179
01180 const size_t bit_index;
01181
01182 Proxy(Bit_Mat_Graph & __bitmat, const long & i, const long & j)
01183 : bit_array(__bitmat.bit_array), bit_index(index_array(i, j, __bitmat.n))
01184 {
01185
01186 }
01187
01188 Proxy& operator = (const Proxy & proxy)
01189 {
01190 bit_array[bit_index] = proxy.bit_array[proxy.bit_index];
01191 }
01192
01193 Proxy& operator = (const int & i)
01194 {
01195 bit_array[bit_index] = i;
01196
01197 return *this;
01198 }
01199
01200 operator int () const
01201 {
01202 return bit_array[bit_index];
01203 }
01204 };
01205
01206 public:
01207
01209 const size_t & get_num_nodes() const { return n; }
01211 Bit_Mat_Graph() : lgraph(NULL) { }
01212
01215 Bit_Mat_Graph(GT & g) : lgraph(&g)
01216 {
01217 copy_list_graph(g);
01218 }
01219
01221 Bit_Mat_Graph(const Bit_Mat_Graph & bitmat)
01222 : bit_array(bitmat.bit_array), lgraph(bitmat.lgraph),
01223 nodes(bitmat.nodes), n(bitmat.n)
01224 {
01225
01226 }
01227
01229 Bit_Mat_Graph(const size_t & dim)
01230 : bit_array(dim*dim), lgraph(NULL),
01231 nodes(dim), n(dim)
01232 {
01233
01234 }
01237 void set_list_graph(GT & g)
01238 {
01239 lgraph = &g;
01240
01241 copy_list_graph(g);
01242 }
01243
01246 GT * get_list_graph() { return lgraph; }
01248 Bit_Mat_Graph & operator = (const Bit_Mat_Graph & bitmat)
01249 {
01250 if (this == &bitmat)
01251 return *this;
01252
01253 lgraph = bitmat.lgraph;
01254 bit_array = bitmat.bit_array;
01255
01256 return *this;
01257 }
01258
01260 Bit_Mat_Graph & operator = (GT & g)
01261 {
01262 if (&g == lgraph)
01263 return *this;
01264
01265 copy_list_graph(g);
01266
01267 return *this;
01268 }
01271 Node * operator () (const long & i) const
01272 {
01273
01274 if (lgraph == NULL)
01275 throw std::domain_error("There is no a List_Graph object");
01276
01277 return Aleph::get_node<GT>(nodes, i);
01278 }
01279
01282 long operator () (Node * node) const
01283 {
01284
01285 if (lgraph == NULL)
01286 throw std::domain_error("There is no a List_Graph object");
01287
01288 return index_of_node<GT>(nodes, n, node);
01289 }
01290 Proxy operator () (const long & i, const long & j)
01291 {
01292 return Proxy(*this, i, j);
01293 }
01294
01295 Proxy operator () (const long & i, const long & j) const
01296 {
01297 return Proxy(const_cast<Bit_Mat_Graph&>(*this), i, j);
01298 }
01299
01300 Proxy operator () (Node * src_node, Node * tgt_node)
01301 {
01302 if (lgraph == NULL)
01303 throw std::domain_error("There is no a List_Graph object");
01304
01305 return Proxy(*this, index_of_node<GT>(nodes, n, src_node),
01306 index_of_node<GT>(nodes, n, tgt_node));
01307 }
01308
01309 Proxy operator () (Node * src_node, Node * tgt_node) const
01310 {
01311 if (lgraph == NULL)
01312 throw std::domain_error("There is no a List_Graph object");
01313
01314 return Proxy(*this, index_of_node<GT>(nodes, n, src_node),
01315 index_of_node<GT>(nodes, n, tgt_node));
01316 }
01317 };
01318
01319 }
01320
01321 # endif // TPL_MAT_GRAPH_H
01322