#pragma once #include #include namespace cgv{ namespace math{ //a basic graph edge type struct edge { //index of start and end vertex unsigned start,end; }; struct weighted_edge : public edge { /// edge weight double weight; int flag; ///standard constructor weighted_edge() : weight(1.0) {} weighted_edge(double w) : weight(w) {} }; //a basic graph node type template struct vertex { typedef typename ET edge_type; //incident edges std::vector edges; unsigned nedges() { return edges.size(); } }; /** * A graph represented in an adjacency list. * * To create a basic graph without extra information stored per vertex or edge * use the predefined type cgv::math::graph: * cgv::math::graph g; * * To create a basic weighted graph with an additional weight attribute per edge use * the predefined type cgv::math::weighted_graph; * cgv::math::weighted_graph wg; * * To create a graph with extra attributes per edge and vertex: * * struct my_edge: public cgv::math::edge * { * double my_extra_edge_attr; * }; * * struct my_vertex : public cgv::math::vertex * { * int my_extra_vertex_attr; * }; * * typedef cgv::math::adjacency_list< my_vertex > my_graph; * my_graph g; * ... */ template class adjacency_list { public: typedef typename v_type vertex_type; typedef typename v_type::edge_type edge_type; ///vertices std::vector *vertices; ///flag indicating a directed/undirected graph bool directed; adjacency_list() { vertices = NULL; directed = true; } ///creates a graph with vnum vertices and zero edges ///the graph is directed if the flag directed is true adjacency_list(const unsigned vnum, bool directed=true) : directed(directed) { vertices = new std::vector(vnum); this->directed = directed; } ///copy constructor adjacency_list(const adjacency_list& al) { if (vertices) delete vertices; directed = al.is_directed(); vertices = new std::vector(*(al.vertices)); } ///assignment operator adjacency_list& operator=(const adjacency_list& al) { if(&al == this) return *this; if (vertices) delete vertices; directed = al.is_directed(); vertices = new std::vector(*(al.vertices)); return *this; } ///destructor of adjacency_list virtual ~adjacency_list() { if(vertices) delete vertices; } ///resize number of vertices, all edge data is removed void resize(const unsigned& vnum) { if(!vertices) vertices = new std::vector(vnum); else { remove_all_edges(); vertices->resize(vnum); } } // clear graph void clear() { if(vertices) { delete vertices; vertices = NULL; } } ///return number of vertices const unsigned nverts() const { assert(vertices != NULL); return vertices->size(); } ///removes all edges void remove_all_edges() { for(unsigned vi = 0; vi < nverts(); vi++) { vertex(vi).edges.clear(); } } ///access vertex i vertex_type& vertex(unsigned i) { return (*vertices)[i]; } ///access const vertex i const vertex_type& vertex(unsigned i)const { return (*vertices)[i]; } ///returns true if the graph is a directed one bool is_directed() const { return directed; } /// checks if edge is already in list bool edge_exists(int start, int end) const { for (unsigned i=0; i < vertex(start).edges.size(); i++) { if(vertex(start).edges[i].end == end) { //std::cout<<"Edge already in list"<size()) { edge_type e; e.start=start; e.end = end; (*vertices)[start].edges.push_back(e); if(!directed) { edge_type e2; e2.start=end; e2.end = start; (*vertices)[end].edges.push_back(e2); } return true; } return false; } ///add new vertex to graph void add_vertex(const vertex_type& v) { vertices->push_back(v); } /*/// adds an edge to the list void add_edge(unsigned start,unsigned end,const edge_type& e) { if(edge_exists(start, end)) return false; if( start < vertices->size() && end < vertices->size()) { edge_type e; e.start = start; e.end = end; (*vertices)[start].edges.push_back(e); if(!directed) { edge_type e2; e2.start = end; e2.end = start; (*vertices)[end].edges.push_back(e); } return true; } return false; }*/ /* /// adds an vertex with n zero filled edges to the list void add(int n){ vertex v; for(int i=0;ipush_back(v); } /// adds an vertex to the list void add(vertex v){ std::cout<<"not tested"<push_back(v); } /// check if an edge is in the list bool contains(edge e){ for (std::vector::iterator it = vertices.begin(); it != vertices.target(); ++it) { for (std::vector::iterator i = it.edges.begin(); i != it.edges.target(); ++i) { if ( e == *i ) return true; } } return false; } /// check if the vertex is in the list bool contains(vertex v){ for (unsigned int i = 0; i < vertices->size(); i ++) { if ( v == (*vertices)[i]) return true; } return false; } // outputs the list as String void to_String(){ for (unsigned int i = 0; i < vertices->size(); i++){ std::cout<::iterator it = (*vertices)[start].edges.begin() + i; (*vertices)[start].edges.erase(it); } } } /// removes an vertex from the list void remove(vertex e){ std::cout<<"not implemented"<size(); i++){ for (unsigned int j = 0;j< (*vertices)[i].edges.size(); j++){ if((*vertices)[i].edges[j].target == n){ std::vector::iterator it = (*vertices)[i].edges.begin() + j; (*vertices)[i].edges.erase(it); } // and decrese all edges with start or end > n if((*vertices)[i].edges[j].target > n){ (*vertices)[i].edges[j].target -= 1; } if((*vertices)[i].edges[j].start > n){ (*vertices)[i].edges[j].start -= 1; } } } std::vector::iterator it = vertices->begin() + n; vertices->erase(it); }*/ }; typedef adjacency_list > base_graph; typedef adjacency_list > weighted_graph; } }