Exemplo n.º 1
0
	/** add a new vertex into the kernel 
	*   \return the handle  of the vertex
	*/
	VertexHandle TopologyKernel::new_vertex() 
	{
		vertices_.push_back(Vertex());
		v_properties_resize(n_vertices());

		return handle(vertices_.back());
	}
Exemplo n.º 2
0
  bool is_kuratowski_subgraph(const Graph& g,
                              ForwardIterator begin, 
                              ForwardIterator end, 
                              VertexIndexMap vm
                              )
  {

    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
    typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
    typedef typename graph_traits<Graph>::edge_descriptor edge_t;
    typedef typename graph_traits<Graph>::edges_size_type e_size_t;
    typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
    typedef typename std::vector<vertex_t> v_list_t;
    typedef typename v_list_t::iterator v_list_iterator_t;
    typedef iterator_property_map
      <typename std::vector<v_list_t>::iterator, VertexIndexMap> 
      vertex_to_v_list_map_t;

    typedef adjacency_list<vecS, vecS, undirectedS> small_graph_t;

    detail::target_graph_t target_graph = detail::tg_k_3_3; //unless we decide otherwise later

    static small_graph_t K_5(detail::make_K_5<small_graph_t>());

    static small_graph_t K_3_3(detail::make_K_3_3<small_graph_t>());

    v_size_t n_vertices(num_vertices(g));
    v_size_t max_num_edges(3*n_vertices - 5);

    std::vector<v_list_t> neighbors_vector(n_vertices);
    vertex_to_v_list_map_t neighbors(neighbors_vector.begin(), vm);

    e_size_t count = 0;
    for(ForwardIterator itr = begin; itr != end; ++itr)
      {

        if (count++ > max_num_edges)
          return false;

        edge_t e(*itr);
        vertex_t u(source(e,g));
        vertex_t v(target(e,g));

        neighbors[u].push_back(v);
        neighbors[v].push_back(u);

      }


    for(v_size_t max_size = 2; max_size < 5; ++max_size)
      {

        vertex_iterator_t vi, vi_end;
        for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
          {
            vertex_t v(*vi);

            //a hack to make sure we don't contract the middle edge of a path
            //of four degree-3 vertices
            if (max_size == 4 && neighbors[v].size() == 3)
              {
                if (neighbors[neighbors[v][0]].size() +
                    neighbors[neighbors[v][1]].size() +
                    neighbors[neighbors[v][2]].size()
                    < 11 // so, it has two degree-3 neighbors
                    )
                  continue;
              }

            while (neighbors[v].size() > 0 && neighbors[v].size() < max_size)
              {
                // Find one of v's neighbors u such that that v and u
                // have no neighbors in common. We'll look for such a 
                // neighbor with a naive cubic-time algorithm since the 
                // max size of any of the neighbor sets we'll consider 
                // merging is 3
                
                bool neighbor_sets_intersect = false;
                
                vertex_t min_u = graph_traits<Graph>::null_vertex();
                vertex_t u;
                v_list_iterator_t v_neighbor_end = neighbors[v].end();
                for(v_list_iterator_t v_neighbor_itr = neighbors[v].begin();
                    v_neighbor_itr != v_neighbor_end; 
                    ++v_neighbor_itr
                    )
                  {
                    neighbor_sets_intersect = false;
                    u = *v_neighbor_itr;
                    v_list_iterator_t u_neighbor_end = neighbors[u].end();
                    for(v_list_iterator_t u_neighbor_itr = 
                          neighbors[u].begin();
                        u_neighbor_itr != u_neighbor_end && 
                          !neighbor_sets_intersect; 
                        ++u_neighbor_itr
                        )
                      {
                        for(v_list_iterator_t inner_v_neighbor_itr = 
                              neighbors[v].begin();
                            inner_v_neighbor_itr != v_neighbor_end; 
                            ++inner_v_neighbor_itr
                            )
                          {
                            if (*u_neighbor_itr == *inner_v_neighbor_itr)
                              {
                                neighbor_sets_intersect = true;
                                break;
                              }
                          }
                        
                      }
                    if (!neighbor_sets_intersect &&
                        (min_u == graph_traits<Graph>::null_vertex() || 
                         neighbors[u].size() < neighbors[min_u].size())
                        )
                      {
                        min_u = u;
                      }
                        
                  }

                if (min_u == graph_traits<Graph>::null_vertex())
                  // Exited the loop without finding an appropriate neighbor of
                  // v, so v must be a lost cause. Move on to other vertices.
                  break;
                else
                  u = min_u;

                detail::contract_edge(neighbors, u, v);

              }//end iteration over v's neighbors

          }//end iteration through vertices v

        if (max_size == 3)
          {
            // check to see whether we should go on to find a K_5
            for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
              if (neighbors[*vi].size() == 4)
                {
                  target_graph = detail::tg_k_5;
                  break;
                }

            if (target_graph == detail::tg_k_3_3)
              break;
          }
        
      }//end iteration through max degree 2,3, and 4

    
    //Now, there should only be 5 or 6 vertices with any neighbors. Find them.
    
    v_list_t main_vertices;
    vertex_iterator_t vi, vi_end;
    
    for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
      {
        if (!neighbors[*vi].empty())
          main_vertices.push_back(*vi);
      }
    
    // create a graph isomorphic to the contracted graph to test 
    // against K_5 and K_3_3
    small_graph_t contracted_graph(main_vertices.size());
    std::map<vertex_t,typename graph_traits<small_graph_t>::vertex_descriptor> 
      contracted_vertex_map;
    
    typename v_list_t::iterator itr, itr_end;
    itr_end = main_vertices.end();
    typename graph_traits<small_graph_t>::vertex_iterator 
      si = vertices(contracted_graph).first;
    
    for(itr = main_vertices.begin(); itr != itr_end; ++itr, ++si)
      {
        contracted_vertex_map[*itr] = *si;
      }

    typename v_list_t::iterator jtr, jtr_end;
    for(itr = main_vertices.begin(); itr != itr_end; ++itr)
      {
        jtr_end = neighbors[*itr].end();
        for(jtr = neighbors[*itr].begin(); jtr != jtr_end; ++jtr)
          {
            if (get(vm,*itr) < get(vm,*jtr))
              {
                add_edge(contracted_vertex_map[*itr],
                         contracted_vertex_map[*jtr],
                         contracted_graph
                         );
              }
          }
      }
    
    if (target_graph == detail::tg_k_5)
      {
        return boost::isomorphism(K_5,contracted_graph);
      }
    else //target_graph == tg_k_3_3
      {
        return boost::isomorphism(K_3_3,contracted_graph);
      }
    
    
  }