marci@1172: /** marci@1172: @defgroup gwrappers Wrapper Classes for Graphs marci@1172: \brief This group contains several wrapper classes for graphs marci@1172: @ingroup graphs marci@556: marci@1172: The main parts of LEMON are the different graph structures, marci@1172: generic graph algorithms, graph concepts which couple these, and marci@1252: graph wrappers. While the previous notions are more or less clear, the marci@1252: latter one needs further explanation. marci@1172: Graph wrappers are graph classes which serve for considering graph marci@1252: structures in different ways. marci@1252: marci@1252: A short example makes this much marci@1172: clearer. marci@1172: Suppose that we have an instance \c g of a directed graph marci@1252: type say ListGraph and an algorithm marci@1172: \code template int algorithm(const Graph&); \endcode marci@1252: is needed to run on the reversed oriented graph. marci@1172: It may be expensive (in time or in memory usage) to copy marci@1252: \c g with the reversed orientation. marci@1252: In this case, a wrapper class is used, which marci@1252: (according to LEMON graph concepts) works as a graph. marci@1252: The wrapper uses marci@1252: the original graph structure and graph operations when methods of the marci@1252: reversed oriented graph are called. marci@1252: This means that the wrapper have minor memory usage, marci@1252: and do not perform sophisticated algorithmic actions. marci@1252: The purpose of it is to give a tool for the cases when marci@1252: a graph have to be used in a specific alteration. marci@1252: If this alteration is obtained by a usual construction marci@1252: like filtering the edge-set or considering a new orientation, then marci@1252: a wrapper is worthwhile to use. marci@1252: To come back to the reversed oriented graph, in this situation marci@1252: \code template class RevGraphWrapper; \endcode marci@1252: template class can be used. marci@1252: The code looks as follows marci@1172: \code marci@1172: ListGraph g; marci@1172: RevGraphWrapper rgw(g); marci@1172: int result=algorithm(rgw); marci@1172: \endcode marci@1172: After running the algorithm, the original graph \c g marci@1252: is untouched. marci@1172: This techniques gives rise to an elegant code, and marci@1172: based on stable graph wrappers, complex algorithms can be marci@1172: implemented easily. marci@1252: marci@1172: In flow, circulation and bipartite matching problems, the residual marci@1172: graph is of particular importance. Combining a wrapper implementing marci@1172: this, shortest path algorithms and minimum mean cycle algorithms, marci@1172: a range of weighted and cardinality optimization algorithms can be marci@1252: obtained. marci@1252: For other examples, marci@1252: the interested user is referred to the detailed documentation of marci@1252: particular wrappers. marci@1252: marci@1172: The behavior of graph wrappers can be very different. Some of them keep marci@1172: capabilities of the original graph while in other cases this would be marci@1252: meaningless. This means that the concepts that they are models of depend marci@1172: on the graph wrapper, and the wrapped graph(s). marci@1172: If an edge of \c rgw is deleted, this is carried out by marci@1252: deleting the corresponding edge of \c g, thus the wrapper modifies the marci@1252: original graph. marci@1252: But for a residual marci@1172: graph, this operation has no sense. marci@1252: Let us stand one more example here to simplify your work. marci@1252: RevGraphWrapper has constructor marci@1252: \code marci@1252: RevGraphWrapper(Graph& _g); marci@1252: \endcode marci@1172: This means that in a situation, marci@1172: when a const ListGraph& reference to a graph is given, marci@1172: then it have to be instantiated with Graph=const ListGraph. marci@1172: \code marci@1172: int algorithm1(const ListGraph& g) { marci@1172: RevGraphWrapper rgw(g); marci@1172: return algorithm2(rgw); marci@1172: } marci@1172: \endcode marci@1172: */