Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
MaximalPlanarSubgraphSimple.h
Go to the documentation of this file.
1
32#pragma once
33
34#include <ogdf/basic/Graph.h>
37#include <ogdf/basic/List.h>
38#include <ogdf/basic/Math.h>
39#include <ogdf/basic/Module.h>
40#include <ogdf/basic/basic.h>
41#include <ogdf/basic/comparer.h>
45
46#include <random>
47#include <type_traits>
48
49namespace ogdf {
50
52
53template<typename TCost, class Enable = void>
54class MaximalPlanarSubgraphSimple { };
55
57
59
66template<typename TCost>
67class MaximalPlanarSubgraphSimple<TCost, typename std::enable_if<std::is_integral<TCost>::value>::type>
68 : public PlanarSubgraphModule<TCost> {
69public:
72 : m_heuristic(*(new PlanarSubgraphEmpty<TCost>)), m_deleteHeuristic(true) { }
73
79 : m_heuristic(heuristic), m_deleteHeuristic(false) { }
80
83 if (m_deleteHeuristic) {
84 delete &m_heuristic;
85 }
86 }
87
89 virtual MaximalPlanarSubgraphSimple* clone() const override {
90 auto result = new MaximalPlanarSubgraphSimple(*(m_heuristic.clone()));
91 result->m_deleteHeuristic =
92 true; // normally a given heuristic is not deleted by the destructor
93 return result;
94 }
95
96protected:
106 virtual Module::ReturnType doCall(const Graph& graph, const List<edge>& preferredEdges,
107 List<edge>& delEdges, const EdgeArray<TCost>* pCost, bool preferredImplyPlanar) override {
108 Module::ReturnType result;
109 delEdges.clear();
110 List<edge> heuDelEdges;
111 if (pCost == nullptr) {
112 result = m_heuristic.call(graph, preferredEdges, heuDelEdges, preferredImplyPlanar);
113 } else {
114 result = m_heuristic.call(graph, *pCost, preferredEdges, heuDelEdges,
115 preferredImplyPlanar);
116 heuDelEdges.quicksort(GenericComparer<edge, TCost>(*pCost));
117 }
118 if (Module::isSolution(result)) {
119 GraphCopy copy(graph);
120 for (edge e : heuDelEdges) {
121 copy.delEdge(copy.copy(e));
122 }
123 for (edge e : heuDelEdges) {
124 edge f = copy.newEdge(e);
125
126 if (!isPlanar(copy)) {
127 delEdges.pushBack(e);
128 copy.delEdge(f);
129 }
130 }
131 }
132 return result;
133 }
134
135
136private:
139};
140
141template<typename TCost>
142class MaximalPlanarSubgraphSimple<TCost, typename std::enable_if<std::is_floating_point<TCost>::value>::type>
143 : public PlanarSubgraphModule<TCost> {
144public:
152 : m_heuristic(*(new PlanarSubgraphEmpty<TCost>))
153 , m_deleteHeuristic(true)
154 , m_randomness(0.0)
155 , m_randomGenerator()
156 , m_runs(1) { }
157
165 double randomness = 0.0, unsigned int runs = 1)
166 : m_heuristic(heuristic)
167 , m_deleteHeuristic(false)
168 , m_randomness(randomness)
169 , m_randomGenerator()
170 , m_runs(runs) {
171 OGDF_ASSERT(runs > 0);
172 }
173
176 if (m_deleteHeuristic) {
177 delete &m_heuristic;
178 }
179 }
180
182 virtual MaximalPlanarSubgraphSimple* clone() const override {
183 auto result = new MaximalPlanarSubgraphSimple(*(m_heuristic.clone()), m_randomness, m_runs);
184 result->m_deleteHeuristic =
185 true; // normally a given heuristic is not deleted by the destructor
186 return result;
187 }
188
193 void setSeed(unsigned seed) { m_randomGenerator.seed(seed); }
194
195
196protected:
206 virtual Module::ReturnType doCall(const Graph& graph, const List<edge>& preferredEdges,
207 List<edge>& delEdges, const EdgeArray<TCost>* pCost, bool preferredImplyPlanar) override {
208 Module::ReturnType result = Module::ReturnType::Error;
209 delEdges.clear();
210
211 // scale the costs and do multiple runs (if needed)
212 List<edge> delEdgesCurrentBest;
213
214 // normalize costs to [0,1] and apply randomness
215 EdgeArray<TCost> normalizedCost(graph);
216
217 for (auto i = 0u; i < m_runs; i++) {
218 List<edge> heuDelEdges;
219
220 if (pCost == nullptr) {
221 result = m_heuristic.call(graph, preferredEdges, heuDelEdges, preferredImplyPlanar);
222 } else {
223 std::uniform_real_distribution<TCost> distribution(0.0, 1.0);
224 edge firstEdge = graph.firstEdge();
225 TCost maxCost = firstEdge == nullptr ? 0 : (*pCost)[firstEdge];
226 TCost minCost = firstEdge == nullptr ? 0 : (*pCost)[firstEdge];
227 for (edge e : graph.edges) {
228 Math::updateMax(maxCost, (*pCost)[e]);
229 Math::updateMin(minCost, (*pCost)[e]);
230 }
231 for (edge e : graph.edges) {
232 // do not merge with first FOR !
233 // normalized = pCost transformed to [0,1]
234 TCost normalized = 1;
235 if (maxCost > minCost) {
236 normalized = ((*pCost)[e] - minCost) / (maxCost - minCost);
237 }
238 // now use randomness
239 normalizedCost[e] = (1.0 - m_randomness) * normalized
240 + m_randomness * distribution(m_randomGenerator);
241 }
242 result = m_heuristic.call(graph, normalizedCost, preferredEdges, heuDelEdges,
243 preferredImplyPlanar);
244 }
245
246 if (Module::isSolution(result)) {
247 GraphCopy copy(graph);
248
249 if (pCost != nullptr) {
250 GenericComparer<edge, TCost> cmp(normalizedCost);
251 heuDelEdges.quicksort(cmp);
252 }
253
254 for (edge e : heuDelEdges) {
255 copy.delEdge(copy.copy(e));
256 }
257
258 delEdgesCurrentBest.clear();
259 for (edge e : heuDelEdges) {
260 edge f = copy.newEdge(e);
261
262 if (!isPlanar(copy)) {
263 delEdgesCurrentBest.pushBack(e);
264 copy.delEdge(f);
265 }
266 }
267
268 if (pCost == nullptr) {
269 if (i == 0 || delEdgesCurrentBest.size() < delEdges.size()) {
270 // better solution: copy to delEdges
271 delEdges.clear();
272 for (auto e : delEdgesCurrentBest) {
273 delEdges.pushBack(e);
274 };
275 }
276 } else {
277 if (i == 0
278 || weightOfList(delEdgesCurrentBest, normalizedCost)
279 < weightOfList(delEdges, normalizedCost)) {
280 // better solution: copy to delEdges
281 delEdges.clear();
282 for (auto e : delEdgesCurrentBest) {
283 delEdges.pushBack(e);
284 };
285 }
286 }
287 }
288 }
289
290 return result;
291 }
292
293private:
297 std::default_random_engine m_randomGenerator;
298 unsigned int m_runs;
299
305 TCost weightOfList(const List<edge>& list, const EdgeArray<TCost>& weights) {
306 TCost result = 0.0;
307 for (auto e : list) {
308 result += weights[e];
309 }
310 return result;
311 }
312};
313
314}
Includes declaration of graph class.
Declaration of graph copy classes.
Decralation of GraphElement and GraphList classes.
Declaration of doubly linked lists and iterators.
Declares base class for all module types.
Declaration and Implementation of class PlanarSubgraphEmpty.
Declaration of interface for planar subgraph algorithms.
Mathematical Helpers.
Basic declarations, included by all source files.
Class for the representation of edges.
Definition Graph_d.h:364
Copies of graphs supporting edge splitting.
Definition GraphCopy.h:390
edge copy(edge e) const override
Returns the first edge in the list of edges corresponding to edge e.
Definition GraphCopy.h:463
void delEdge(edge e) override
Removes edge e and clears the list of edges corresponding to e's original edge.
edge newEdge(edge eOrig)
Creates a new edge (v,w) with original edge eOrig.
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:866
edge firstEdge() const
Returns the first edge in the list of all edges.
Definition Graph_d.h:1000
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition Graph_d.h:932
Doubly linked lists (maintaining the length of the list).
Definition List.h:1451
int size() const
Returns the number of elements in the list.
Definition List.h:1488
void clear()
Removes all elements from the list.
Definition List.h:1626
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1547
void quicksort()
Sorts the list using Quicksort.
Definition List.h:1331
MaximalPlanarSubgraphSimple(PlanarSubgraphModule< TCost > &heuristic)
Constructor with user given heuristic that is executed before extending the solution to maximality.
virtual Module::ReturnType doCall(const Graph &graph, const List< edge > &preferredEdges, List< edge > &delEdges, const EdgeArray< TCost > *pCost, bool preferredImplyPlanar) override
Computes the set of edges delEdges which have to be deleted to obtain the planar subgraph.
MaximalPlanarSubgraphSimple(PlanarSubgraphModule< TCost > &heuristic, double randomness=0.0, unsigned int runs=1)
Constructor.
void setSeed(unsigned seed)
set seed of std::default_random_engine generator to use when randomness > 0
std::default_random_engine m_randomGenerator
random generator to use with std::uniform_real_distribution
virtual Module::ReturnType doCall(const Graph &graph, const List< edge > &preferredEdges, List< edge > &delEdges, const EdgeArray< TCost > *pCost, bool preferredImplyPlanar) override
Computes the set of edges delEdges which have to be deleted to obtain the planar subgraph.
double m_randomness
randomness of the process: use 0 to compute everything based on the costs, use 1 for completely rando...
ReturnType
The return type of a module.
Definition Module.h:52
Dummy implementation for maximum planar subgraph that returns an empty graph.
Interface for planar subgraph algorithms.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition Graph_d.h:717
Declarations for Comparer objects.
Declaration of extended graph algorithms.
bool isPlanar(const Graph &G)
Returns true, if G is planar, false otherwise.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.
Definition GML.h:111
Compare elements based on a single comparable attribute.
Definition comparer.h:402