x
Yes
No
Do you want to visit DriveHQ English website?
Inicio
Características
Precios
Prueba gratuita
Software cliente
Acerca de nosotros
Servidor de archivos
|
Solución de copias de seguridad
|
Servidor FTP
|
Servidor de correo electrónico
|
Alojamiento web
|
Software cliente
Servidor de archivos
Solución de copia de seguridad
Servidor FTP
Servidor de correo electrónico
Alojamiento web
Software cliente
is_kuratowski_subgraph.hpp - Hosted on DriveHQ Cloud IT Platform
Arriba
Subir
Descargar
Compartir
Publicar
Nueva carpeta
Nuevo archivo
Copiar
Cortar
Eliminar
Pegar
Clasificación
Actualizar
Ruta de la carpeta: \\game3dprogramming\materials\GameFactory\GameFactoryDemo\references\boost_1_35_0\boost\graph\is_kuratowski_subgraph.hpp
Girar
Efecto
Propiedad
Historial
//======================================================================= // Copyright 2007 Aaron Windsor // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= #ifndef __IS_KURATOWSKI_SUBGRAPH_HPP__ #define __IS_KURATOWSKI_SUBGRAPH_HPP__ #include
#include
//for next/prior #include
//for tie #include
#include
#include
#include
#include
#include
#include
namespace boost { namespace detail { template
Graph make_K_5() { typename graph_traits
::vertex_iterator vi, vi_end, inner_vi; Graph K_5(5); for(tie(vi,vi_end) = vertices(K_5); vi != vi_end; ++vi) for(inner_vi = next(vi); inner_vi != vi_end; ++inner_vi) add_edge(*vi, *inner_vi, K_5); return K_5; } template
Graph make_K_3_3() { typename graph_traits
::vertex_iterator vi, vi_end, bipartition_start, inner_vi; Graph K_3_3(6); bipartition_start = next(next(next(vertices(K_3_3).first))); for(tie(vi, vi_end) = vertices(K_3_3); vi != bipartition_start; ++vi) for(inner_vi= bipartition_start; inner_vi != vi_end; ++inner_vi) add_edge(*vi, *inner_vi, K_3_3); return K_3_3; } template
void contract_edge(AdjacencyList& neighbors, Vertex u, Vertex v) { // Remove u from v's neighbor list neighbors[v].erase(std::remove(neighbors[v].begin(), neighbors[v].end(), u ), neighbors[v].end() ); // Replace any references to u with references to v typedef typename AdjacencyList::value_type::iterator adjacency_iterator_t; adjacency_iterator_t u_neighbor_end = neighbors[u].end(); for(adjacency_iterator_t u_neighbor_itr = neighbors[u].begin(); u_neighbor_itr != u_neighbor_end; ++u_neighbor_itr ) { Vertex u_neighbor(*u_neighbor_itr); std::replace(neighbors[u_neighbor].begin(), neighbors[u_neighbor].end(), u, v ); } // Remove v from u's neighbor list neighbors[u].erase(std::remove(neighbors[u].begin(), neighbors[u].end(), v ), neighbors[u].end() ); // Add everything in u's neighbor list to v's neighbor list std::copy(neighbors[u].begin(), neighbors[u].end(), std::back_inserter(neighbors[v]) ); // Clear u's neighbor list neighbors[u].clear(); } } // namespace detail template
bool is_kuratowski_subgraph(const Graph& g, ForwardIterator begin, ForwardIterator end, VertexIndexMap vm ) { typedef typename graph_traits
::vertex_descriptor vertex_t; typedef typename graph_traits
::vertex_iterator vertex_iterator_t; typedef typename graph_traits
::edge_descriptor edge_t; typedef typename graph_traits
::edges_size_type e_size_t; typedef typename graph_traits
::vertices_size_type v_size_t; typedef typename std::vector
v_list_t; typedef typename v_list_t::iterator v_list_iterator_t; typedef iterator_property_map
::iterator, VertexIndexMap> vertex_to_v_list_map_t; typedef adjacency_list
small_graph_t; enum target_graph_t { k_3_3, k_5}; target_graph_t target_graph = k_3_3; //unless we decide otherwise later static small_graph_t K_5(detail::make_K_5
()); static small_graph_t K_3_3(detail::make_K_3_3
()); v_size_t n_vertices(num_vertices(g)); v_size_t max_num_edges(3*n_vertices - 5); std::vector
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(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
::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
::null_vertex() || neighbors[u].size() < neighbors[min_u].size()) ) { min_u = u; } } if (min_u == graph_traits
::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(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) if (neighbors[*vi].size() == 4) { target_graph = k_5; break; } if (target_graph == 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(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_descriptor> contracted_vertex_map; typename v_list_t::iterator itr, itr_end; itr_end = main_vertices.end(); typename graph_traits
::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 == k_5) { return isomorphism(K_5,contracted_graph); } else //target_graph == k_3_3 { return isomorphism(K_3_3,contracted_graph); } } template
bool is_kuratowski_subgraph(const Graph& g, ForwardIterator begin, ForwardIterator end ) { return is_kuratowski_subgraph(g, begin, end, get(vertex_index,g)); } } #endif //__IS_KURATOWSKI_SUBGRAPH_HPP__
is_kuratowski_subgraph.hpp
Dirección de la página
Dirección del archivo
Anterior
45/95
Siguiente
Descargar
( 10 KB )
Comments
Total ratings:
0
Average rating:
No clasificado
of 10
Would you like to comment?
Join now
, or
Logon
if you are already a member.