/* Copyright (c) 1997-2006 Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany) http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version: http://www.gnu.org/licenses/gpl.txt. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #ifndef _POLYMAKE_GRAPH_ADAPTER_H #define _POLYMAKE_GRAPH_ADAPTER_H "$Project: polymake $$Id: GraphAdapter.h 7406 2006-08-02 17:26:57Z gawrilow $" #include #include #include #include namespace pm { namespace graph { template struct edge_id_accessor { typedef IteratorRef argument_type; typedef typename deref::type iterator; typedef pair::value_type*> result_type; private: static int from_node(argument_type it, True) { return it.get_line_index(); } static int from_node(argument_type it, False) { return it->key - it.get_line_index(); } public: result_type operator() (argument_type it) const { return result_type(from_node(it, bool2type()), it.operator->()); } }; template class edge_id_list : public modified_tree< edge_id_list, list( Hidden< Tree >, Operation< BuildUnaryIt > ) > { protected: ~edge_id_list(); }; } } // end namespace pm::graph /* The next two specializations should solve the problem of ambiguous edge_ids in undirected graphs, by constraining the comparison on the second component (pointer to the cell), which is indeed unique. */ namespace std { template inline bool operator== (const pair*>& p1, const pair*>& p2) { return p1.second==p2.second; } template inline bool operator< (const pair*>& p1, const pair*>& p2) { return p1.second struct hash< std::pair*> > { protected: hash*> h_second; public: size_t operator() (const std::pair*>& p) const { return h_second(p.second); } }; } namespace polymake { namespace graph { template class GraphAdapter : public pm::hash_map_adapter { public: typedef Graph basic_graph_type; const basic_graph_type& get_basic_graph() const { return G; } static const pm::graph::kind is_directed=dir; GraphAdapter(const basic_graph_type& G_arg) : G(G_arg) { } typedef typename basic_graph_type::const_node_container_ref Nodes; typedef typename basic_graph_type::const_edge_container_ref Edges; Nodes nodes() const { return pm::nodes(G); } Edges edges() const { return pm::edges(G); } typedef int node_id; typedef std::pair*> edge_id; static node_id void_node_id() { return -1; } static edge_id void_edge_id() { return edge_id(-1,0); } typedef typename basic_graph_type::template edge_access::out::const_reference OutEdges; typedef typename basic_graph_type::template edge_access::in::const_reference InEdges; OutEdges out_edges(node_id n) const { return G.template out_edges(n); } InEdges in_edges(node_id n) const { return G.template in_edges(n); } static node_id to_node(const edge_id& e) { return e.second->key-e.first; } static node_id from_node(const edge_id& e) { return e.first; } template struct node_property_map { typedef pm::vector_as_property_map type; }; template static typename node_property_map::type create_property_map(node_id*, Value*) { return typename node_property_map::type(); } template void clear(pm::vector_as_property_map& map) const { map.clear(); map.get_container().reserve(G.nodes()); } template void clear(pm::vector_as_property_map& map, const Value& v) const { clear(map); map.set_default_value(v); } template void init(pm::vector_as_property_map& map) const { map.clear(); map.get_container().resize(G.nodes()); } template void init(pm::vector_as_property_map& map, const Value& v) const { init(map); std::fill(pm::entire(map), v); } template struct edge_property_map : hash_map_adapter::template property_map { }; using hash_map_adapter::create_property_map; using hash_map_adapter::init; using hash_map_adapter::clear; template struct property_map; template struct property_map : node_property_map { }; template struct property_map : edge_property_map { }; protected: const basic_graph_type& G; }; // This is an example - only one of possible adaptors for the dijkstra algorithm. // It assumes that EdgeAttr represents the edge length, which is of one of usual arithmetic types. template class ShortestPathAdapter : public GraphAdapter { typedef GraphAdapter _super; public: ShortestPathAdapter(const typename _super::basic_graph_type& G) : _super(G) { } ShortestPathAdapter(const _super& arg) : _super(arg) { } typedef EdgeAttr weight_type; typedef EdgeAttr distance_type; typedef operations::cmp distance_comparator_type; static distance_comparator_type get_distance_comparator() { return distance_comparator_type(); } static const weight_type& get_edge_weight(typename _super::edge_id e) { return e.second->data; } }; } } #endif // _POLYMAKE_GRAPH_ADAPTER_H // Local Variables: // mode:C++ // c-basic-offset:3 // End: