Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

SpannerKortsarzPeleg.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 #include <ogdf/basic/NodeSet.h>
39 
40 namespace ogdf {
41 
72 template<typename TWeight>
73 class SpannerKortsarzPeleg : public SpannerModule<TWeight> {
77 
78 public:
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 
101 private:
102  virtual void init(const GraphAttributes& GA, double stretch, GraphCopySimple& spanner,
103  EdgeArray<bool>& inSpanner) override {
104  SpannerModule<TWeight>::init(GA, stretch, spanner, inSpanner);
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;
113  NodeSet<true> maxDenseSubset(m_GA->constGraph());
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
118  GraphCopySimple neighborGraph;
119  // Note: v is not part of the neighbor graph.
120  neighborGraph.setOriginalGraph(m_G);
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
132  NodeSet<true> denseSubset(m_G);
133  int64_t timelimit = -1;
134  if (isTimelimitEnabled()) {
135  timelimit = max(static_cast<int64_t>(0), getTimeLeft());
136  }
137  bool success = maximumDensitySubgraph(
138  neighborGraph, denseSubset,
139  [&](node n) {
140  OGDF_ASSERT(neighborGraph.original(n) != nullptr);
141  return neighborGraph.original(n);
142  },
143  timelimit);
144  if (!success) {
146  }
147 
148  List<edge> E_U;
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();
159  if (m_eps.greater(density, maxDensity)) {
160  maxDensity = density;
161  maxNode = v;
162  maxDenseSubset = denseSubset;
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 }
ogdf::GraphAttributes::edgeIntWeight
static const long edgeIntWeight
Corresponds to edge attribute intWeight(edge).
Definition: GraphAttributes.h:119
NodeSet.h
Declaration and implementation of ogdf::NodeSet.
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::GraphAttributes
Stores additional attributes of a graph (like layout information).
Definition: GraphAttributes.h:66
ogdf::SpannerModule::isTimelimitEnabled
bool isTimelimitEnabled()
Definition: SpannerModule.h:161
ogdf::GraphCopySimple::delEdge
void delEdge(edge e) override
Removes edge e.
ogdf::SpannerKortsarzPeleg::preconditionsOk
virtual bool preconditionsOk(const GraphAttributes &GA, double stretch, std::string &error) override
Definition: SpannerKortsarzPeleg.h:80
ogdf::SpannerModule::TimeoutException
Definition: SpannerModule.h:183
ogdf::EpsilonTest
Definition: EpsilonTest.h:41
ogdf::GraphCopySimple::copy
edge copy(edge e) const override
Returns the edge in the graph copy corresponding to e.
Definition: GraphCopy.h:288
ogdf::SpannerModule::m_spanner
GraphCopySimple * m_spanner
Definition: SpannerModule.h:130
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::SpannerKortsarzPeleg::addToSpanner
void addToSpanner(edge e)
Adds e from m_G to the spanner and sets inSpanner.
Definition: SpannerKortsarzPeleg.h:205
ogdf::SpannerModule::init
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner)
Initializes members and create an empty spanner.
Definition: SpannerModule.h:136
MaximumDensitySubgraph.h
Declares maximum density subgraph algorithms.
ogdf::NodeSet::nodes
const RS::list_type & nodes()
Returns a reference to the list of nodes contained in this set.
Definition: GraphSets.h:65
ogdf::SpannerKortsarzPeleg::init
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner) override
Initializes members and create an empty spanner.
Definition: SpannerKortsarzPeleg.h:102
ogdf::NodeSet< true >
ogdf::GraphCopySimple
Copies of graphs with mapping between nodes and edges.
Definition: GraphCopy.h:254
ogdf::RegisteredSet::size
int size() const
Returns the number of elements in this set.
Definition: RegisteredSet.h:151
ogdf::GraphCopySimple::setOriginalGraph
void setOriginalGraph(const Graph *G) override
Re-initializes the copy using G (which might be null), but does not create any nodes or edges.
ogdf::GraphAttributes::directed
bool directed() const
Returns if the graph is directed.
Definition: GraphAttributes.h:226
ogdf::GraphAttributes::constGraph
const Graph & constGraph() const
Returns a reference to the associated graph.
Definition: GraphAttributes.h:217
SpannerModule.h
Basic module for spanner algorithms.
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:135
ogdf::EpsilonTest::less
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
ogdf::maximumDensitySubgraph
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.
ogdf::GraphCopyBase::init
void init(const Graph &G)
Re-initializes the copy using G, creating copies for all nodes and edges in G.
Definition: GraphCopy.h:66
ogdf::Graph::nodes
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Definition: Graph_d.h:924
ogdf::SpannerModule::getTimeLeft
int64_t getTimeLeft()
Definition: SpannerModule.h:166
ogdf::NodeElement::adjEntries
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Definition: Graph_d.h:264
ogdf::SpannerKortsarzPeleg::m_G
GraphCopySimple m_G
The copy of GA.constGraph() to work on. Edges will be removed in each iteration.
Definition: SpannerKortsarzPeleg.h:75
ogdf::EdgeElement::source
node source() const
Returns the source node of the edge.
Definition: Graph_d.h:391
ogdf::GraphCopyBase::newNode
node newNode(node vOrig)
Creates a new node in the graph copy with original node vOrig.
Definition: GraphCopy.h:185
ogdf::List< edge >
ogdf::RegisteredSet::isMember
bool isMember(element_type v) const
Returns true iff element v is contained in this set.
Definition: RegisteredSet.h:136
ogdf::SpannerModule
Interface for spanner algorithms.
Definition: SpannerModule.h:57
ogdf::EpsilonTest::greater
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.
Definition: EpsilonTest.h:161
ogdf::SpannerKortsarzPeleg::execute
virtual SpannerModule< TWeight >::ReturnType execute() override
Executes the core algorithm.
Definition: SpannerKortsarzPeleg.h:109
ogdf::AdjElement::twinNode
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition: Graph_d.h:168
ogdf::GraphCopySimple::clear
void clear() override
Removes all nodes and edges from this copy but does not break the link with the original graph.
ogdf::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:927
ogdf::SpannerKortsarzPeleg::m_eps
EpsilonTest m_eps
Definition: SpannerKortsarzPeleg.h:76
ogdf::SpannerModule::m_GA
const GraphAttributes * m_GA
Definition: SpannerModule.h:128
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
ogdf::Graph::searchEdge
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 ))).
ogdf::List::size
int size() const
Returns the number of elements in the list.
Definition: List.h:1478
ogdf::GraphAttributes::edgeDoubleWeight
static const long edgeDoubleWeight
Corresponds to edge attribute doubleWeight(edge).
Definition: GraphAttributes.h:122
ogdf::SpannerKortsarzPeleg
Approximation multiplicative 2-spanner calculation.
Definition: SpannerKortsarzPeleg.h:73
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:394
ogdf::Module::ReturnType
ReturnType
The return type of a module.
Definition: Module.h:50
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:233
ogdf::GraphCopySimple::newEdge
edge newEdge(edge eOrig)
Creates a new edge in the graph copy with original edge eOrig.
Definition: GraphCopy.h:314
ogdf::isSimple
bool isSimple(const Graph &G)
Returns true iff G contains neither self-loops nor parallel edges.
Definition: simple_graph_alg.h:394
simple_graph_alg.h
Declaration of simple graph algorithms.
ogdf::GraphAttributes::has
bool has(long attr) const
Returns true iff all attributes in attr are available.
Definition: GraphAttributes.h:194
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1537
ogdf::GraphCopyBase::original
const Graph & original() const
Returns a reference to the original graph.
Definition: GraphCopy.h:98
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709