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
35#include <ogdf/basic/Math.h>
39
40#include <type_traits>
41
42namespace ogdf {
43
45
46template<typename TCost, class Enable = void>
47class MaximalPlanarSubgraphSimple { };
48
50
52
59template<typename TCost>
60class MaximalPlanarSubgraphSimple<TCost, typename std::enable_if<std::is_integral<TCost>::value>::type>
61 : public PlanarSubgraphModule<TCost> {
62public:
65 : m_heuristic(*(new PlanarSubgraphEmpty<TCost>)), m_deleteHeuristic(true) { }
66
72 : m_heuristic(heuristic), m_deleteHeuristic(false) { }
73
76 if (m_deleteHeuristic) {
77 delete &m_heuristic;
78 }
79 }
80
82 virtual MaximalPlanarSubgraphSimple* clone() const override {
83 auto result = new MaximalPlanarSubgraphSimple(*(m_heuristic.clone()));
84 result->m_deleteHeuristic =
85 true; // normally a given heuristic is not deleted by the destructor
86 return result;
87 }
88
89protected:
100 List<edge>& delEdges, const EdgeArray<TCost>* pCost, bool preferredImplyPlanar) override {
101 Module::ReturnType result;
102 delEdges.clear();
104 if (pCost == nullptr) {
105 result = m_heuristic.call(graph, preferredEdges, heuDelEdges, preferredImplyPlanar);
106 } else {
107 result = m_heuristic.call(graph, *pCost, preferredEdges, heuDelEdges,
110 }
111 if (Module::isSolution(result)) {
112 GraphCopy copy(graph);
113 for (edge e : heuDelEdges) {
114 copy.delEdge(copy.copy(e));
115 }
116 for (edge e : heuDelEdges) {
117 edge f = copy.newEdge(e);
118
119 if (!isPlanar(copy)) {
120 delEdges.pushBack(e);
121 copy.delEdge(f);
122 }
123 }
124 }
125 return result;
126 }
127
128
129private:
132};
133
134template<typename TCost>
135class MaximalPlanarSubgraphSimple<TCost, typename std::enable_if<std::is_floating_point<TCost>::value>::type>
136 : public PlanarSubgraphModule<TCost> {
137public:
145 : m_heuristic(*(new PlanarSubgraphEmpty<TCost>))
146 , m_deleteHeuristic(true)
147 , m_randomness(0.0)
148 , m_randomGenerator()
149 , m_runs(1) { }
150
158 double randomness = 0.0, unsigned int runs = 1)
159 : m_heuristic(heuristic)
160 , m_deleteHeuristic(false)
161 , m_randomness(randomness)
162 , m_randomGenerator()
163 , m_runs(runs) {
164 OGDF_ASSERT(runs > 0);
165 }
166
169 if (m_deleteHeuristic) {
170 delete &m_heuristic;
171 }
172 }
173
175 virtual MaximalPlanarSubgraphSimple* clone() const override {
176 auto result = new MaximalPlanarSubgraphSimple(*(m_heuristic.clone()), m_randomness, m_runs);
177 result->m_deleteHeuristic =
178 true; // normally a given heuristic is not deleted by the destructor
179 return result;
180 }
181
186 void setSeed(unsigned seed) { m_randomGenerator.seed(seed); }
187
188
189protected:
200 List<edge>& delEdges, const EdgeArray<TCost>* pCost, bool preferredImplyPlanar) override {
201 Module::ReturnType result = Module::ReturnType::Error;
202 delEdges.clear();
203
204 // scale the costs and do multiple runs (if needed)
206
207 // normalize costs to [0,1] and apply randomness
209
210 for (auto i = 0u; i < m_runs; i++) {
212
213 if (pCost == nullptr) {
214 result = m_heuristic.call(graph, preferredEdges, heuDelEdges, preferredImplyPlanar);
215 } else {
216 std::uniform_real_distribution<TCost> distribution(0.0, 1.0);
217 edge firstEdge = graph.firstEdge();
218 TCost maxCost = firstEdge == nullptr ? 0 : (*pCost)[firstEdge];
219 TCost minCost = firstEdge == nullptr ? 0 : (*pCost)[firstEdge];
220 for (edge e : graph.edges) {
221 Math::updateMax(maxCost, (*pCost)[e]);
222 Math::updateMin(minCost, (*pCost)[e]);
223 }
224 for (edge e : graph.edges) {
225 // do not merge with first FOR !
226 // normalized = pCost transformed to [0,1]
227 TCost normalized = 1;
228 if (maxCost > minCost) {
229 normalized = ((*pCost)[e] - minCost) / (maxCost - minCost);
230 }
231 // now use randomness
232 normalizedCost[e] = (1.0 - m_randomness) * normalized
233 + m_randomness * distribution(m_randomGenerator);
234 }
235 result = m_heuristic.call(graph, normalizedCost, preferredEdges, heuDelEdges,
237 }
238
239 if (Module::isSolution(result)) {
240 GraphCopy copy(graph);
241
242 if (pCost != nullptr) {
244 heuDelEdges.quicksort(cmp);
245 }
246
247 for (edge e : heuDelEdges) {
248 copy.delEdge(copy.copy(e));
249 }
250
251 delEdgesCurrentBest.clear();
252 for (edge e : heuDelEdges) {
253 edge f = copy.newEdge(e);
254
255 if (!isPlanar(copy)) {
256 delEdgesCurrentBest.pushBack(e);
257 copy.delEdge(f);
258 }
259 }
260
261 if (pCost == nullptr) {
262 if (i == 0 || delEdgesCurrentBest.size() < delEdges.size()) {
263 // better solution: copy to delEdges
264 delEdges.clear();
265 for (auto e : delEdgesCurrentBest) {
266 delEdges.pushBack(e);
267 };
268 }
269 } else {
270 if (i == 0
271 || weightOfList(delEdgesCurrentBest, normalizedCost)
272 < weightOfList(delEdges, normalizedCost)) {
273 // better solution: copy to delEdges
274 delEdges.clear();
275 for (auto e : delEdgesCurrentBest) {
276 delEdges.pushBack(e);
277 };
278 }
279 }
280 }
281 }
282
283 return result;
284 }
285
286private:
290 std::default_random_engine m_randomGenerator;
291 unsigned int m_runs;
292
299 TCost result = 0.0;
300 for (auto e : list) {
301 result += weights[e];
302 }
303 return result;
304 }
305};
306
307}
Implementation of disjoint sets data structures (union-find functionality).
Declaration and Implementation of class PlanarSubgraphEmpty.
Mathematical Helpers.
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
Class for the representation of edges.
Definition Graph_d.h:300
Copies of graphs supporting edge splitting.
Definition GraphCopy.h:254
virtual void delEdge(edge e) override
Removes edge e and clears the list of edges corresponding to e's original edge.
node copy(node v) const
Returns the node in the graph copy corresponding to v.
Definition GraphCopy.h:338
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:521
edge firstEdge() const
Returns the first edge in the list of all edges.
Definition Graph_d.h:652
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
int size() const
Returns the number of elements in the list.
Definition List.h:1472
void clear()
Removes all elements from the list.
Definition List.h:1610
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition List.h:1531
void quicksort()
Sorts the list using Quicksort.
Definition List.h:1315
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:50
Dummy implementation for maximum planar subgraph that returns an empty graph.
Interface for planar subgraph algorithms.
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:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
Definition GML.h:110
Declaration of simple graph algorithms.
Compare elements based on a single comparable attribute.
Definition comparer.h:398