LCOV - code coverage report
Current view: top level - pg/include/mcrl2/pg - Graph.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 0 18 0.0 %
Date: 2024-04-21 03:44:01 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009-2013 University of Twente
       2             : // Copyright (c) 2009-2013 Michael Weber <michaelw@cs.utwente.nl>
       3             : // Copyright (c) 2009-2013 Maks Verver <maksverver@geocities.com>
       4             : // Copyright (c) 2009-2013 Eindhoven University of Technology
       5             : //
       6             : // Distributed under the Boost Software License, Version 1.0.
       7             : // (See accompanying file LICENSE_1_0.txt or copy at
       8             : // http://www.boost.org/LICENSE_1_0.txt)
       9             : 
      10             : /*! \file Graph.h
      11             : 
      12             :     Data structures to define vertices, edges and graphs.
      13             : */
      14             : 
      15             : #ifndef MCRL2_PG_GRAPH_H
      16             : #define MCRL2_PG_GRAPH_H
      17             : 
      18             : #include <algorithm>
      19             : #include <iostream>
      20             : #include <utility>
      21             : #include <vector>
      22             : 
      23             : // Note: these should be unsigned types; some algorithms depend on it!
      24             : typedef std::size_t verti;    //!< type used to number vertices
      25             : typedef std::size_t edgei;    //!< type used to number edges
      26             : 
      27             : #define NO_VERTEX ((verti)-1)
      28             : 
      29             : class StaticGraph;
      30             : 
      31             : /*! \ingroup ParityGameData
      32             :  
      33             :     A static graph consists of V vertices (numbered from 0 to V, exclusive)
      34             :     and E edges, and can store either edge successors, predecessors, or both. */
      35             : class StaticGraph
      36             : {
      37             : #if 0
      38             : public:
      39             :     //! A not-completely-standard-compliant class to iterate over a graph's edges.
      40             :     class EdgeIterator
      41             :     {
      42             :     public:
      43             :         EdgeIterator() { }
      44             :         EdgeIterator(const EdgeIterator &ei) : g(ei.g), v(ei.v), e(ei.e) { }
      45             :         inline EdgeIterator &operator=(const EdgeIterator &ei);
      46             :         inline std::pair<verti, verti> operator*();
      47             :         inline std::pair<verti, verti> operator++();
      48             :         inline std::pair<verti, verti> operator++(int);
      49             : 
      50             :         edgei operator-(const EdgeIterator &ei) { return e - ei.e; }
      51             : 
      52             :     protected:
      53             :         EdgeIterator(const StaticGraph *g, verti v, edgei e) : g(g), v(v), e(e) { }
      54             : 
      55             :     private:
      56             :         const StaticGraph *g;  //! underlying graph whose edges are being iterated
      57             :         verti v;               //! current vertex index
      58             :         edgei e;               //! current edge index
      59             : 
      60             :         friend class StaticGraph;
      61             :     };
      62             : #endif
      63             : 
      64             : public:
      65             :     /*! Iterator used to iterate over predecessor/successor vertices. */
      66             :     typedef const verti *const_iterator;
      67             : 
      68             : #if 0
      69             :     /*! Iterator used to iterate over edges. */
      70             :     typedef EdgeIterator const_edge_iterator;
      71             : #endif
      72             : 
      73             :     /*! A list of edges */
      74             :     typedef std::vector<std::pair<verti, verti> > edge_list;
      75             : 
      76             :     /*! Specifies which parts of the edges are stored.
      77             :         When storing successors only, the functions succ_begin() and succ_end()
      78             :         can be used to iterate over the successors of a given vertex.
      79             :         Conversely, when storing predecessors, pred_begin() and pred_end()
      80             :         can be used to iterate over predecessors.
      81             :         When storing bidirectional edges, both pairs of functions can be used,
      82             :         but this requires more memory. */
      83             :     enum EdgeDirection
      84             :     {
      85             :         EDGE_NONE           = 0,  /* for internal use only! */
      86             :         EDGE_SUCCESSOR      = 1,
      87             :         EDGE_PREDECESSOR    = 2,
      88             :         EDGE_BIDIRECTIONAL  = 3
      89             :     };
      90             : 
      91             :     StaticGraph();          /*!< Construct an empty static graph. */
      92             :     ~StaticGraph();         /*!< Destroy the static graph. */
      93             : 
      94             :     /*! Reset to an empty graph. */
      95             :     void clear();
      96             : 
      97             :     /*! Generate a random graph (replacing the old contents).
      98             :         The resulting game does not contain loops.
      99             : 
     100             :         \param V        number of vertices to generate
     101             :         \param outdeg   desired average outdegree (at least 1)
     102             :         \param edge_dir which parts of edges to store
     103             :         \param scc      create a single strongly-connected component */
     104             :     void make_random(verti V, unsigned outdeg, EdgeDirection edge_dir,
     105             :                      bool scc);
     106             : 
     107             :     /*! Generate a random clustered game, which is based on random games of
     108             :         size `cluster_size` each, which are connected recursively by being
     109             :         substituting for the vertices of another game of size `cluster_size`,
     110             :         repeatedly, until a single game remains.
     111             : 
     112             :         The resulting game is always a single connected component without loops.
     113             : 
     114             :         Passing `V` <= `cluster_size` is equivalent to calling make_random()
     115             :         with `scc` = true. Choosing `V` = `cluster_size`<sup>d</sup>
     116             :         creates a game with recursion depth <em>d</em>.
     117             : 
     118             :         @param cluster_size number of vertices per cluster
     119             :         @param V            total number of vertices to generate
     120             :         @param outdeg       average outdegree (at least 1)
     121             :         @param edge_dir     which parts of the edges to store 
     122             : 
     123             :         \see make_random
     124             :     */
     125             :     void make_random_clustered(verti cluster_size, verti V,
     126             :                                unsigned outdeg, EdgeDirection edge_dir);
     127             : 
     128             :     /*! Randomly shuffles vertex indices.  This is useful to obfuscate some of
     129             :         the structure remaining after make_random_clustered(). */
     130             :     void shuffle_vertices();
     131             : 
     132             :     /*! Shuffle vertex indices by the given permutation.
     133             :         Vertex v becomes perm[v], for all v.
     134             : 
     135             :         \see ParityGame::shuffle
     136             :     */
     137             :     void shuffle_vertices(const std::vector<verti> &perm);
     138             : 
     139             :     /*! Reset the graph to a copy of `graph`. */
     140             :     void assign(const StaticGraph &graph);
     141             : 
     142             :     /*! Reset the graph based on the given edge structure. */
     143             :     void assign(edge_list edges, EdgeDirection edge_dir);
     144             : 
     145             :     /*! Convert the graph into a list of edges. */
     146             :     edge_list get_edges() const;
     147             : 
     148             :     /*! Reset the graph to the subgraph induced by the given vertex set. */
     149             :     template<class ForwardIterator>
     150             :     void make_subgraph( const StaticGraph &graph,
     151             :                         ForwardIterator vertices_begin,
     152             :                         ForwardIterator vertices_end,
     153             :                         bool proper,
     154             :                         EdgeDirection edge_dir = EDGE_NONE );
     155             : 
     156             :     void make_subgraph_threads( const StaticGraph &graph,
     157             :                                 const verti *verts,
     158             :                                 const verti nvert,
     159             :                                 bool proper,
     160             :                                 EdgeDirection edge_dir = EDGE_NONE );
     161             : 
     162             :     /*! Removes the given edges from the graph. The contents of the edge list
     163             :         may be reordered by this function! */
     164             :     void remove_edges(edge_list &edges);
     165             : 
     166             :     /*! Write raw graph data to output stream */
     167             :     void write_raw(std::ostream &os) const;
     168             : 
     169             :     /*! Read raw graph data from input stream */
     170             :     void read_raw(std::istream &is);
     171             : 
     172             :     /*! Swaps the contents of this graph with another one. */
     173             :     void swap(StaticGraph &g);
     174             : 
     175             :     /*! Returns whether the graph is empty. */
     176           0 :     bool empty() const { return V_ == 0; }
     177             : 
     178             :     /*! Returns the number of vertices in the graph. */
     179           0 :     verti V() const { return V_; }
     180             : 
     181             :     /*! Returns the number of edges in the graph. */
     182             :     edgei E() const { return E_; }
     183             : 
     184             :     /*! Return direction of edges stored. */
     185           0 :     EdgeDirection edge_dir() const { return edge_dir_; }
     186             : 
     187             :     /*! Returns an iterator pointing to the first successor of vertex `v`. */
     188           0 :     const_iterator succ_begin(verti v) const {
     189           0 :         return &successors_[successor_index_[v]];
     190             :     }
     191             : 
     192             :     /*! Returns an iterator pointing past the last successor of vertex `v`. */
     193           0 :     const_iterator succ_end(verti v) const {
     194           0 :         return &successors_[successor_index_[v + 1]];
     195             :     }
     196             : 
     197             :     /*! Returns an iterator pointing to the first predecessor of vertex `v`. */
     198           0 :     const_iterator pred_begin(verti v) const {
     199           0 :         return &predecessors_[predecessor_index_[v]];
     200             :     }
     201             : 
     202             :     /*! Returns an iterator pointing past the last predecessor of vertex `v`. */
     203           0 :     const_iterator pred_end(verti v) const {
     204           0 :         return &predecessors_[predecessor_index_[v + 1]];
     205             :     }
     206             : 
     207             :     /*! Returns whether `v` has a successor `w`. */
     208           0 :     bool has_succ(verti v, verti w) const {
     209           0 :         return std::binary_search(succ_begin(v), succ_end(v), w);
     210             :     }
     211             : 
     212             :     /*! Returns whether `w` has a predecessor `v`. */
     213             :     bool has_pred(verti w, verti v) const {
     214             :         return std::binary_search(pred_begin(w), pred_end(w), v);
     215             :     }
     216             : 
     217             :     /*! Returns the degree for vertex `v`. */
     218             :     edgei degree(verti v) const {
     219             :         return indegree(v) + outdegree(v);
     220             :     }
     221             : 
     222             :     /*! Returns the outdegree for vertex `v`. */
     223           0 :     edgei outdegree(verti v) const {
     224           0 :         return succ_end(v) - succ_begin(v);
     225             :     }
     226             : 
     227             :     /*! Returns the indegree for vertex `v`. */
     228             :     edgei indegree(verti v) const {
     229             :         return pred_end(v) - pred_begin(v);
     230             :     }
     231             : 
     232             : #if 0
     233             :     /*! Returns an edge iterator starting at the given vertex.
     234             :         Currently, this requires the graph to store successors. */
     235             :     const_edge_iterator edges_begin(verti v = 0) const {
     236             :         return EdgeIterator(this, v, successor_index_[v]);
     237             :     }
     238             : 
     239             :     /*! Returns an edge iterator pointing to the end of the edge list.
     240             :         Currently, this requires the graph to store successors. */
     241             :     const_edge_iterator edges_end() const {
     242             :         return EdgeIterator(this, V_, E_);
     243             :     }
     244             : #endif
     245             : 
     246             : protected:
     247             :     /*! Turn the current graph (with current edge list passed in `edges`) into
     248             :         a strongly connected component by randomly adding edges where necessary.
     249             :     */
     250             :     void make_random_scc(edge_list &edges);
     251             : 
     252             :     /*! Frees allocated memory and then reallocates memory to store a graph
     253             :         with `V` vertices and `E` edges. */
     254             :     void reset(verti V, edgei E, EdgeDirection edge_dir);
     255             : 
     256             :     /*! Reset the graph to the subgraph induced by the given vertex set, using
     257             :         the given map data structure to create the vertex mapping. */
     258             :     template<class ForwardIterator, class VertexMapT>
     259             :     void make_subgraph( const StaticGraph &graph,
     260             :                         ForwardIterator vertices_begin,
     261             :                         ForwardIterator vertices_end,
     262             :                         VertexMapT &vertex_map,
     263             :                         bool proper,
     264             :                         EdgeDirection edge_dir = EDGE_NONE );
     265             : 
     266             : private:
     267             :     explicit StaticGraph(const StaticGraph &graph);
     268             :     StaticGraph &operator=(const StaticGraph &graph);
     269             : 
     270             : private:
     271             :     verti V_;  /*!< number of vertices */
     272             :     edgei E_;  /*!< number of edges */
     273             : 
     274             :     /*! Successor/predecessor lists (of size E).
     275             :         If edges are pairs of nodes (i,j), then `successors` is the list of
     276             :         successors (j's) obtained after sorting edges by predecessors (i's),
     277             :         and vice versa for `predecessors`. */
     278             :     verti *successors_, *predecessors_;
     279             : 
     280             :     /*! Indices into the successor/predecessor lists (of size V + 1).
     281             :         successor_index[i] is the lowest index of an edge in `successors` with
     282             :         a predecessor >= i; successor_index[V] is E. */
     283             :     edgei *successor_index_, *predecessor_index_;
     284             : 
     285             :     /*! Direction of stored edges. */
     286             :     EdgeDirection edge_dir_;
     287             : 
     288             : private:
     289             :     /* This is a bit of a hack to allow the small progress measures code to
     290             :        do a preprocessing pass for nodes with self-loops. */
     291             :     friend class SmallProgressMeasures;
     292             : 
     293             :     friend class EdgeIterator;
     294             : };
     295             : 
     296             : 
     297           0 : inline void swap(StaticGraph &a, StaticGraph &b)
     298             : {
     299           0 :     a.swap(b);
     300           0 : }
     301             : 
     302             : #include "Graph_impl.h"
     303             : 
     304             : #endif /* ndef MCRL2_PG_GRAPH_H */

Generated by: LCOV version 1.14