Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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 
42 namespace ogdf {
43 
45 
46 template<typename TCost, class Enable = void>
47 class MaximalPlanarSubgraphSimple { };
48 
50 
52 
59 template<typename TCost>
60 class MaximalPlanarSubgraphSimple<TCost, typename std::enable_if<std::is_integral<TCost>::value>::type>
61  : public PlanarSubgraphModule<TCost> {
62 public:
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 
89 protected:
99  virtual Module::ReturnType doCall(const Graph& graph, const List<edge>& preferredEdges,
100  List<edge>& delEdges, const EdgeArray<TCost>* pCost, bool preferredImplyPlanar) override {
101  Module::ReturnType result;
102  delEdges.clear();
103  List<edge> heuDelEdges;
104  if (pCost == nullptr) {
105  result = m_heuristic.call(graph, preferredEdges, heuDelEdges, preferredImplyPlanar);
106  } else {
107  result = m_heuristic.call(graph, *pCost, preferredEdges, heuDelEdges,
108  preferredImplyPlanar);
109  heuDelEdges.quicksort(GenericComparer<edge, TCost>(*pCost));
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 
129 private:
132 };
133 
134 template<typename TCost>
135 class MaximalPlanarSubgraphSimple<TCost, typename std::enable_if<std::is_floating_point<TCost>::value>::type>
136  : public PlanarSubgraphModule<TCost> {
137 public:
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 
189 protected:
199  virtual Module::ReturnType doCall(const Graph& graph, const List<edge>& preferredEdges,
200  List<edge>& delEdges, const EdgeArray<TCost>* pCost, bool preferredImplyPlanar) override {
202  delEdges.clear();
203 
204  // scale the costs and do multiple runs (if needed)
205  List<edge> delEdgesCurrentBest;
206 
207  // normalize costs to [0,1] and apply randomness
208  EdgeArray<TCost> normalizedCost(graph);
209 
210  for (auto i = 0u; i < m_runs; i++) {
211  List<edge> heuDelEdges;
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,
236  preferredImplyPlanar);
237  }
238 
239  if (Module::isSolution(result)) {
240  GraphCopy copy(graph);
241 
242  if (pCost != nullptr) {
243  GenericComparer<edge, TCost> cmp(normalizedCost);
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 
286 private:
289  double m_randomness;
290  std::default_random_engine m_randomGenerator;
291  unsigned int m_runs;
292 
298  TCost weightOfList(const List<edge>& list, const EdgeArray<TCost>& weights) {
299  TCost result = 0.0;
300  for (auto e : list) {
301  result += weights[e];
302  }
303  return result;
304  }
305 };
306 
307 }
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::m_deleteHeuristic
bool m_deleteHeuristic
flag to store we have to delete a self created heuristic
Definition: MaximalPlanarSubgraphSimple.h:288
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::Module::isSolution
static bool isSolution(ReturnType ret)
Returns true iff ret indicates that the module returned a feasible solution.
Definition: Module.h:65
ogdf::PlanarSubgraphModule
Interface for planar subgraph algorithms.
Definition: PlanarSubgraphModule.h:48
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_integral< TCost >::value >::type >::MaximalPlanarSubgraphSimple
MaximalPlanarSubgraphSimple(PlanarSubgraphModule< TCost > &heuristic)
Constructor with user given heuristic that is executed before extending the solution to maximality.
Definition: MaximalPlanarSubgraphSimple.h:71
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_integral< TCost >::value >::type >::m_heuristic
PlanarSubgraphModule< TCost > & m_heuristic
user given heuristic
Definition: MaximalPlanarSubgraphSimple.h:130
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::MaximalPlanarSubgraphSimple
MaximalPlanarSubgraphSimple(PlanarSubgraphModule< TCost > &heuristic, double randomness=0.0, unsigned int runs=1)
Constructor.
Definition: MaximalPlanarSubgraphSimple.h:157
extended_graph_alg.h
Declaration of extended graph algorithms.
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::MaximalPlanarSubgraphSimple
MaximalPlanarSubgraphSimple()
Constructor.
Definition: MaximalPlanarSubgraphSimple.h:144
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::~MaximalPlanarSubgraphSimple
virtual ~MaximalPlanarSubgraphSimple()
Destructor.
Definition: MaximalPlanarSubgraphSimple.h:168
ogdf::GraphCopy
Copies of graphs supporting edge splitting.
Definition: GraphCopy.h:384
ogdf::isPlanar
bool isPlanar(const Graph &G)
Returns true, if G is planar, false otherwise.
Definition: extended_graph_alg.h:274
PlanarSubgraphEmpty.h
Declaration and Implementation of class PlanarSubgraphEmpty. Heuristic: We obtain a planar subgraph b...
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_integral< TCost >::value >::type >::clone
virtual MaximalPlanarSubgraphSimple * clone() const override
Clone method.
Definition: MaximalPlanarSubgraphSimple.h:82
Minisat::Internal::copy
static void copy(const T &from, T &to)
Definition: Alg.h:61
ogdf::Module::ReturnType::Error
@ Error
Computation was aborted due to an error.
backward::Color::type
type
Definition: backward.hpp:1716
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_integral< TCost >::value >::type >::MaximalPlanarSubgraphSimple
MaximalPlanarSubgraphSimple()
Constructor.
Definition: MaximalPlanarSubgraphSimple.h:64
ogdf::Math::updateMin
void updateMin(T &min, const T &newValue)
Stores the minimum of min and newValue in min.
Definition: Math.h:98
ogdf::List< edge >
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:862
Math.h
Mathematical Helpers.
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::m_randomness
double m_randomness
randomness of the process: use 0 to compute everything based on the costs, use 1 for completely rando...
Definition: MaximalPlanarSubgraphSimple.h:289
ogdf::Graph::firstEdge
edge firstEdge() const
Returns the first edge in the list of all edges.
Definition: Graph_d.h:995
ogdf::Graph::edges
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Definition: Graph_d.h:927
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::m_runs
unsigned int m_runs
number of runs when algorithms is randomized
Definition: MaximalPlanarSubgraphSimple.h:291
ogdf::Math::updateMax
void updateMax(T &max, const T &newValue)
Stores the maximum of max and newValue in max.
Definition: Math.h:90
std
Definition: GML.h:110
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_integral< TCost >::value >::type >::~MaximalPlanarSubgraphSimple
virtual ~MaximalPlanarSubgraphSimple()
Desctructor.
Definition: MaximalPlanarSubgraphSimple.h:75
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::weightOfList
TCost weightOfList(const List< edge > &list, const EdgeArray< TCost > &weights)
Definition: MaximalPlanarSubgraphSimple.h:298
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::doCall
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.
Definition: MaximalPlanarSubgraphSimple.h:199
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::m_heuristic
PlanarSubgraphModule< TCost > & m_heuristic
user given heuristic
Definition: MaximalPlanarSubgraphSimple.h:287
DisjointSets.h
Implementation of disjoint sets data structures (union-find functionality).
ogdf::PlanarSubgraphEmpty
Dummy implementation for maximum planar subgraph that returns an empty graph.
Definition: PlanarSubgraphEmpty.h:44
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:356
ogdf::List::size
int size() const
Returns the number of elements in the list.
Definition: List.h:1478
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_integral< TCost >::value >::type >::doCall
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.
Definition: MaximalPlanarSubgraphSimple.h:99
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::m_randomGenerator
std::default_random_engine m_randomGenerator
random generator to use with std::uniform_real_distribution
Definition: MaximalPlanarSubgraphSimple.h:290
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::clone
virtual MaximalPlanarSubgraphSimple * clone() const override
Clone method.
Definition: MaximalPlanarSubgraphSimple.h:175
ogdf::Module::ReturnType
ReturnType
The return type of a module.
Definition: Module.h:50
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_integral< TCost >::value >::type >::m_deleteHeuristic
bool m_deleteHeuristic
flag to store we have to delete a self created heuristic
Definition: MaximalPlanarSubgraphSimple.h:131
simple_graph_alg.h
Declaration of simple graph algorithms.
ogdf::GenericComparer
Compare elements based on a single comparable attribute.
Definition: comparer.h:398
ogdf::MaximalPlanarSubgraphSimple< TCost, typename std::enable_if< std::is_floating_point< TCost >::value >::type >::setSeed
void setSeed(unsigned seed)
set seed of std::default_random_engine generator to use when randomness > 0
Definition: MaximalPlanarSubgraphSimple.h:186
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1537
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:709
ogdf::List::clear
void clear()
Removes all elements from the list.
Definition: List.h:1616