Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
SpannerKortsarzPeleg.h
Go to the documentation of this file.
1
33#pragma once
34
35#include <ogdf/basic/NodeSet.h>
39
40namespace ogdf {
41
72template<typename TWeight>
73class SpannerKortsarzPeleg : public SpannerModule<TWeight> {
77
78public:
80 virtual bool preconditionsOk(const GraphAttributes& GA, double stretch,
81 std::string& error) override {
82 if (GA.directed()) {
83 error = "The graph must be undirected";
84 return false;
85 }
86 if (stretch != 2.0) {
87 error = "The stretch must be 2.0";
88 return false;
89 }
90 if (!isSimple(GA.constGraph())) {
91 error = "The graph is not simple";
92 return false;
93 }
95 error = "The graph must be unweighted";
96 return false;
97 }
98 return true;
99 }
100
101private:
102 virtual void init(const GraphAttributes& GA, double stretch, GraphCopySimple& spanner,
103 EdgeArray<bool>& inSpanner) override {
105 m_G.clear();
106 m_G.init(GA.constGraph());
107 }
108
109 virtual typename SpannerModule<TWeight>::ReturnType execute() override {
110 while (true) {
111 node maxNode = nullptr;
112 double maxDensity = 0.0;
114 List<edge> maxE_U; // holds the edges of the maximum dense subgraph
115
116 for (node v : m_G.nodes) {
117 // Create neighbor graph
119 // Note: v is not part of the neighbor graph.
121 for (adjEntry adj : v->adjEntries) {
122 neighborGraph.newNode(adj->twinNode());
123 }
124 for (edge e : m_G.edges) {
125 if (neighborGraph.copy(e->target()) != nullptr
126 && neighborGraph.copy(e->source()) != nullptr) {
127 neighborGraph.newEdge(e);
128 }
129 }
130
131 // Calculate dense subgraph and find all edges E_U of this subgraph
133 int64_t timelimit = -1;
134 if (isTimelimitEnabled()) {
135 timelimit = max(static_cast<int64_t>(0), getTimeLeft());
136 }
139 [&](node n) {
140 OGDF_ASSERT(neighborGraph.original(n) != nullptr);
141 return neighborGraph.original(n);
142 },
143 timelimit);
144 if (!success) {
146 }
147
149 for (edge e : m_G.edges) {
150 if (denseSubset.isMember(e->source()) && denseSubset.isMember(e->target())) {
151 E_U.pushBack(e);
152 }
153 }
154
155 // Did we found a new maximum dense subgraph?
156 double density = denseSubset.size() == 0
157 ? 0.0
158 : static_cast<double>(E_U.size()) / denseSubset.size();
161 maxNode = v;
163 maxE_U = E_U;
164 }
165 }
166
167 if (m_eps.less(maxDensity, 1.0)) {
168 break;
169 }
170
171 OGDF_ASSERT(maxNode != nullptr);
172
173 // add edges to spanner
174 for (node u : maxDenseSubset.nodes()) {
175 edge e = m_G.searchEdge(maxNode, u); // e is part of m_G
176 addToSpanner(e);
177
178 // remove from m_G
179 m_G.delEdge(e);
180 }
181
182 // Remove R(H^u, maxDenseSubset) from m_G
183 // Improvement: H^c (see paper) is actually not needed. Since
184 // R(H^u, maxDenseSubset) is the intersection of E_U and the current spanner
185 // edges, but E_U only consists of current spanner edges (Note that the loop
186 // above only contains edges not in E_U since maxNode is not part of the
187 // neighbor graph), the intersection is not needed. One can directly delete
188 // all edges in E_U.
189 for (edge e : maxE_U) {
190 m_G.delEdge(e);
191 }
192 }
193
194 // Add uncovered edges to spanner
195 for (edge e : m_G.edges) {
196 addToSpanner(e);
197 }
198
200 }
201
205 inline void addToSpanner(edge e) {
207 (*m_inSpanner)[m_G.original(e)] = true;
208 }
209
216};
217
218}
Declares maximum density subgraph algorithms.
Declaration and implementation of ogdf::NodeSet.
Basic module for spanner algorithms.
Class for adjacency list elements.
Definition Graph_d.h:79
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
Class for the representation of edges.
Definition Graph_d.h:300
std::enable_if< std::is_integral< T >::value, bool >::type less(const T &x, const T &y) const
Compare if x is LESS than y for integral types.
Definition EpsilonTest.h:57
std::enable_if< std::is_integral< T >::value, bool >::type greater(const T &x, const T &y) const
Compare if x is GREATER than y for integral types.
Stores additional attributes of a graph (like layout information).
const Graph & constGraph() const
Returns a reference to the associated graph.
static const long edgeDoubleWeight
Corresponds to edge attribute doubleWeight(edge).
static const long edgeIntWeight
Corresponds to edge attribute intWeight(edge).
Copies of graphs with mapping between nodes and edges.
Definition GraphCopy.h:59
edge newEdge(edge eOrig)
Creates a new edge in the graph copy with original edge eOrig.
Definition GraphCopy.h:188
virtual void delEdge(edge e) override
Removes edge e.
void init(const Graph &G)
Re-initializes the copy using G.
const Graph & original() const
Returns a reference to the original graph.
Definition GraphCopy.h:85
void createEmpty(const Graph &G)
Re-initializes the copy using G, but does not create any nodes or edges.
virtual void clear()
Removes all nodes and all edges from the graph.
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition Graph_d.h:589
edge searchEdge(node v, node w, bool directed=false) const
Searches and returns an edge connecting nodes v and w in time O( min(deg(v ), deg(w ))).
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition Graph_d.h:592
Doubly linked lists (maintaining the length of the list).
Definition List.h:1435
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1531
ReturnType
The return type of a module.
Definition Module.h:50
Class for the representation of nodes.
Definition Graph_d.h:177
Node sets.
Definition NodeSet.h:54
Approximation multiplicative 2-spanner calculation.
virtual bool preconditionsOk(const GraphAttributes &GA, double stretch, std::string &error) override
void addToSpanner(edge e)
Adds e from m_G to the spanner and sets inSpanner.
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner) override
Initializes members and create an empty spanner.
GraphCopySimple m_G
The copy of GA.constGraph() to work on. Edges will be removed in each iteration.
virtual SpannerModule< TWeight >::ReturnType execute() override
Executes the core algorithm.
Interface for spanner algorithms.
void assertTimeLeft()
Assert, that time is left.
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner)
Initializes members and create an empty spanner.
const GraphAttributes * m_GA
EdgeArray< bool > * m_inSpanner
GraphCopySimple * m_spanner
bool maximumDensitySubgraph(Graph &G, NodeSet< true > &subgraphNodes, std::function< node(node)> resultNodeMap=[](node v) { return v;}, int64_t timelimit=-1)
Calculates the maximum density subgraph of G.
bool isSimple(const Graph &G)
Returns true iff G contains neither self-loops nor parallel edges.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
Declaration of simple graph algorithms.
A simple exception used to exit from the execution, if the timelimit is reached.