81template<
typename TCost>
83 using BlockType = std::pair<Graph*, EdgeArray<edge>*>;
105 (
m_block[i].first !=
nullptr) ? std::numeric_limits<int>::max() : 0;
116 TCost newSolution = pNewDelEdges->
size();
119 newSolution = TCost(0);
120 for (
edge e : *pNewDelEdges) {
121 newSolution += (*m_pCost)[origEdge[e]];
126 std::lock_guard<std::mutex> guard(
m_mutex);
195 if (G.numberOfEdges() < 9) {
205 for (
edge e : G.edges) {
206 if (!e->isSelfLoop()) {
207 blockEdges[componentID[e]].pushFront(e);
215 for (
int i = 0; i < nBlocks; i++) {
216 if (blockEdges[i].size() < 9) {
227 for (
edge e : blockEdges[i]) {
228 if (copyV[e->source()] ==
nullptr) {
229 copyV[e->source()] = bc->
newNode();
232 if (copyV[e->target()] ==
nullptr) {
233 copyV[e->target()] = bc->
newNode();
237 (*origE)[bc->
newEdge(copyV[e->source()], copyV[e->target()])] = e;
240 for (
node v : marked) {
247 unsigned int nThreads = min(this->
maxThreads(), (
unsigned int)nRuns);
252 parCall(block, pCost, nRuns, nThreads, delEdges);
256 for (
int i = 0; i < nBlocks; i++) {
257 delete block[i].first;
258 delete block[i].second;
271 const int nBlocks = block.
size();
276 for (
int i = 0; i < nBlocks; ++i) {
277 bestDelEdges[i] =
nullptr;
278 bestSolution[i] = (block[i].first !=
nullptr) ? std::numeric_limits<TCost>::max() : 0;
281 for (
int run = 0; run < nRuns; ++run) {
282 for (
int i = 0; i < nBlocks; ++i) {
283 if (bestSolution[i] > 1) {
284 const Graph&
B = *block[i].first;
294 TCost currentSolution;
295 if (pCost ==
nullptr) {
296 currentSolution = pCurrentDelEdges->
size();
299 for (
edge e : *pCurrentDelEdges) {
300 currentSolution += (*pCost)[origEdge[e]];
304 if (currentSolution < bestSolution[i]) {
305 delete bestDelEdges[i];
306 bestDelEdges[i] = pCurrentDelEdges;
307 bestSolution[i] = currentSolution;
309 delete pCurrentDelEdges;
316 for (
int i = 0; i < nBlocks; ++i) {
317 if (bestDelEdges[i] !=
nullptr) {
319 for (
edge e : *bestDelEdges[i]) {
322 delete bestDelEdges[i];
329 unsigned int nThreads,
List<edge>& delEdges) {
334 for (
unsigned int i = 0; i < nThreads - 1; ++i) {
335 worker[i] =
new Worker(&master);
336 thread[i] =
Thread(*worker[i]);
341 for (
unsigned int i = 0; i < nThreads - 1; ++i) {
359 for (
node v : G.nodes) {
360 for (
adjEntry adj : v->adjEntries) {
361 edge e = adj->theEdge();
362 if (numbering[e->
opposite(v)] > numbering[v]) {
363 PlanarLeafKey* L =
new PlanarLeafKey(e);
364 inLeaves[v].pushFront(L);
367 table[numbering[v]] = v;
370 for (
node v : G.nodes) {
371 for (PlanarLeafKey* L : inLeaves[v]) {
372 outLeaves[L->userStructKey()->opposite(v)].pushFront(L);
380 for (
int i = 2; i < G.numberOfNodes(); i++) {
382 T.
Reduction(outLeaves[table[i]], eliminatedKeys);
383 totalEliminatedKeys.
conc(eliminatedKeys);
389 edge e = key->userStructKey();
394 for (
node v : G.nodes) {
395 while (!inLeaves[v].empty()) {
396 PlanarLeafKey* L = inLeaves[v].popFrontRet();
409 for (
int i = 0; i < nBlocks; ++i) {
419 pCurrentDelEdges = master.
postNewResult(i, pCurrentDelEdges);
420 delete pCurrentDelEdges;
Declaration and implementation of Array class and Array algorithms.
Includes declaration of graph class.
Decralation of GraphElement and GraphList classes.
Declaration of doubly linked lists and iterators.
Declares base class for all module types.
Declaration and implementation of the class PQLeafKey.
Declaration of class PlanarLeafKey.
Declaration of interface for planar subgraph algorithms.
Declaration of class PlanarSubgraphPQTree.
Declaration of singly linked lists and iterators.
Declaration of st-Numbering functions.
Declaration of Thread class representing threads.
Basic declarations, included by all source files.
Class for adjacency list elements.
The parameterized class Array implements dynamic arrays of type E.
INDEX size() const
Returns the size (number of elements) of the array.
Class for the representation of edges.
node opposite(node v) const
Returns the adjacent node different from v.
Data type for general directed graphs (adjacency list representation).
node newNode(int index=-1)
Creates a new node and returns it.
edge newEdge(node v, node w, int index=-1)
Creates a new edge (v,w) and returns it.
Doubly linked lists (maintaining the length of the list).
int size() const
Returns the number of elements in the list.
void clear()
Removes all elements from the list.
iterator pushBack(const E &x)
Adds element x at the end of the list.
virtual void emptyAllPertinentNodes()
Does a clean up after a reduction.
ReturnType
The return type of a module.
@ Feasible
The solution is feasible.
@ Optimal
The solution is optimal.
Class for the representation of nodes.
The class template PQLeafKey is a derived class of class template PQBasicKey.
virtual void Cleanup()
Removes the entire PQ-tree.
ThreadMaster(const Array< BlockType > &block, const EdgeArray< TCost > *pCost, int runs)
int m_nBlocks
number of blocks
Array< List< edge > * > m_bestDelEdges
best solution for block
List< edge > * postNewResult(int i, List< edge > *pNewDelEdges)
std::atomic< int > m_runs
const Array< BlockType > & m_block
the blocks (graph and edge mapping)
bool considerBlock(int i) const
std::mutex m_mutex
thread synchronization
const EdgeArray< TCost > * m_pCost
edge cost (may be 0)
void buildSolution(List< edge > &delEdges)
Array< TCost > m_bestSolution
value of best solution for block
const Graph & block(int i) const
Worker & operator=(const Worker &other)
Worker(const Worker &other)
Worker(ThreadMaster *pMaster)
Computation of a planar subgraph using PQ-trees.
virtual PlanarSubgraphFast * clone() const override
Returns a new instance of fast planar subgraph with the same option settings.
static void doWorkHelper(ThreadMaster &master)
virtual Module::ReturnType doCall(const Graph &G, const List< edge > &preferedEdges, List< edge > &delEdges, const EdgeArray< TCost > *pCost, bool preferedImplyPlanar) override
Returns true, if G is planar, false otherwise.
int runs() const
Returns the current number of randomized runs.
static void planarize(const Graph &G, NodeArray< int > &numbering, List< edge > &delEdges)
Performs a planarization on a biconnected component of G.
PlanarSubgraphFast()
Creates an instance of the fast planar subgraph algorithm with default settings (runs = 10).
void seqCall(const Array< BlockType > &block, const EdgeArray< TCost > *pCost, int nRuns, bool randomize, List< edge > &delEdges)
Realizes the sequential implementation.
void runs(int nRuns)
Sets the number of randomized runs to nRuns.
void parCall(const Array< BlockType > &block, const EdgeArray< TCost > *pCost, int nRuns, unsigned int nThreads, List< edge > &delEdges)
Realizes the parallel implementation.
std::pair< Graph *, EdgeArray< edge > * > BlockType
int m_nRuns
The number of runs for randomization.
Interface for planar subgraph algorithms.
unsigned int maxThreads() const
Returns the maximal number of used threads.
virtual int Initialize(SListPure< PlanarLeafKey * > &leafKeys)
Initializes a new PQ-tree with a set of leaves.
void ReplaceRoot(SListPure< PlanarLeafKey * > &leafKeys)
Replaces the pertinent subtree by a set of new leaves.
virtual bool Reduction(SListPure< PlanarLeafKey * > &leafKeys, SList< PQLeafKey< edge, whaInfo *, bool > * > &eliminatedKeys)
Reduces a set of leaves.
void init(const Base *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Singly linked lists (maintaining the length of the list).
void conc(SList< E > &L2)
Appends L2 to this list and makes L2 empty.
SListIterator< E > pushBack(const E &x)
Adds element x at the end of the list.
Threads supporting OGDF's memory management.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
RegisteredArray for nodes, edges and adjEntries of a graph.
int biconnectedComponents(const Graph &G, EdgeArray< int > &component, int &nonEmptyComponents)
Computes the biconnected components of G.
int computeSTNumbering(const Graph &G, NodeArray< int > &numbering, node s=nullptr, node t=nullptr, bool randomized=false)
Computes an st-Numbering of G.
The namespace for all OGDF objects.
Declaration of simple graph algorithms.
Declaration of class whaInfo.