42namespace steiner_tree {
120#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
121 std::cout <<
"Normalizing factor is " <<
m_lcm << std::endl;
131#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
132 std::cout <<
"Add terminal " << v <<
" representing original terminal " <<
t << std::endl;
176#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
177 std::cout <<
"Add source node " <<
getSource() <<
" with edges to:" << std::endl;
179 for (
auto root :
roots) {
180#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
181 std::cout <<
" * node " << root.first <<
" with cost 0 and capacity " << root.second
200 roots.push(std::make_pair(root, cap));
205#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
207 std::cout <<
"Edge from " << e <<
" of cost " <<
m_cost[e] <<
" and capacity "
224#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
226 <<
" with edges coming from:" << std::endl;
233 for (
adjEntry adj : v->adjEntries) {
242#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
243 std::cout <<
" * terminal " << v <<
" with zero cost and capacity " <<
y_v
257#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
258 std::cout <<
"Add edge from pseudo-target " <<
getPseudotarget() <<
" to target "
259 <<
getTarget() <<
" with zero cost and capacity " <<
m_y << std::endl;
265#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
266 std::cout <<
" * updating for terminal " << v << std::endl;
271#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
272 std::cout <<
" * target capacity initialized to " <<
capTarget
273 <<
", source capacity and delta to 0" << std::endl;
279#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
280 std::cout <<
" * remove edge with capacity " <<
getCapacity(adj->theEdge())
281 <<
" from source " <<
getSource() << std::endl;
288#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
290 <<
" with capacity " <<
getCapacity(adj->theEdge())
291 <<
" participating in delta" << std::endl;
299#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
300 std::cout <<
" * update target capacity for edge " << adj->theEdge()
301 <<
" by adding " <<
getCapacity(adj->theEdge()) << std::endl;
306 if (v != adj->theEdge()->target()) {
307#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
308 std::cout <<
" and change source capacity by the same amount" << std::endl;
314#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
315 std::cout <<
" * new target capacity is " <<
capTarget <<
" and delta = " << delta
321#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
322 std::cout <<
" * new edge from pseudotarget to target with zero cost and capacity "
327#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
328 std::cout <<
" * new edge from source to " << v <<
" with zero cost and capacity "
380 while (!
stack.empty()) {
385 const edge e = adj->theEdge();
386 const node w = adj->twinNode();
387 if (!pred[v] || w != pred[v]->theNode()) {
392 for (
node x = v; pred[x]; x = pred[x]->theNode()) {
407 newEdge(e->source(), x, w, cap);
408 newEdge(x, e->target(), 0, cap);
422 const edge eO = pair.key();
423 const edge eC = pair.info();
466#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
467 std::cout <<
"Full components to use in blowup graph:\n";
552#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
553 std::cout <<
"Updating capacities (y = " <<
m_y <<
")" << std::endl;
557#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
558 std::cout <<
" * new y = " <<
m_y << std::endl;
576 for (
edge e : edges) {
591 if (
t->degree() > 0) {
600 template<
typename NODELIST>
602 auto it = nodes.begin();
604 for (++it; it != nodes.end(); ++it) {
622 while (!cleanup.
empty()) {
627#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
628 std::cout <<
" * remove pendant node " << v <<
" for cleanup" << std::endl;
632 }
else if (v->
indeg() == 0) {
633#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
634 std::cout <<
" * " << v <<
" has no incoming edge -> fix directions"
639#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
640 std::cout <<
" * make " << w <<
" parent of " << v <<
" (reverse edge "
641 << e <<
")" << std::endl;
662 if ((*it)->degree() == 0) {
671 edge rootEdge =
nullptr;
674 edge e = (*it)->theEdge();
699 todo.pushBack(origEdge);
701 while (!
todo.empty()) {
714 adj = adj->cyclicSucc()) {
717 todo.pushBack(adj->theEdge());
Definition of ogdf::steiner_tree::goemans::CoreEdgeModule class template.
Definition of the FullComponentStore class template.
Declaration and implementation of HashArray class.
Class for adjacency list elements.
adjEntry twin() const
Returns the corresponding adjacency element associated with the same edge.
adjEntry cyclicSucc() const
Returns the cyclic successor in the adjacency list.
adjEntry succ() const
Returns the successor in the adjacency list.
edge theEdge() const
Returns the edge associated with this adjacency entry.
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
node theNode() const
Returns the node whose adjacency list contains this element.
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
E popRet()
Removes the newest element from the buffer and returns it.
void push(E e)
Puts a new element in the buffer.
bool empty() const
Returns true if the buffer is empty, false otherwise.
Dynamic arrays indexed with edges.
void init()
Reinitializes the array. Associates the array with no graph.
Class for the representation of edges.
node source() const
Returns the source node of the edge.
Data type for general directed graphs (adjacency list representation).
node contract(edge e, bool keepSelfLoops=false)
Contracts edge e while preserving the order of adjacency entries.
edge newEdge(node v, node w)
Creates a new edge (v,w) and returns it.
virtual void delNode(node v)
Removes node v and all incident edges from the graph.
void reverseEdge(edge e)
Reverses the edge e, i.e., exchanges source and target node.
virtual void delEdge(edge e)
Removes edge e from the graph.
void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter)
Moves adjacency entry adjMove after adjAfter.
node newNode()
Creates a new node and returns it.
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Indexed arrays using hashing for element access.
HashConstIterator< I, E, H > begin() const
Returns an iterator to the first element in the list of all elements.
Iterators for hash tables.
Doubly linked lists (maintaining the length of the list).
iterator pushBack(const E &x)
Adds element x at the end of the list.
Encapsulates a pointer to a list element.
bool valid() const
Returns true iff the iterator points to an element.
Dynamic arrays indexed with nodes.
Class for the representation of nodes.
int indeg() const
Returns the indegree of the node.
int degree() const
Returns the degree of the node (indegree + outdegree).
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
adjEntry lastAdj() const
Returns the last entry in the adjacency list.
bool isTerminal(int id, node t) const
checks if a given node t is a terminal in the full component with given id
adjEntry start(int i) const
T cost(int i) const
Returns the sum of edge costs of this full component.
const EdgeWeightedGraph< T > & graph() const
node original(node v) const
const Array< node > & terminals(int id) const
Returns the list of terminals in the full component with given id.
int size() const
Returns the number of full components in the store.
A special-purpose blowup graph for gammoid computation: directed, with special source and target,...
T getCost(edge e) const
Returns the cost of e.
void removeBasis(node v)
Removes a basis and cleans up.
List< node > m_terminals
The terminals in the blowup graph.
const EdgeArray< int > & capacities() const
Returns a reference to the edge array containing all capacities.
void contract(node &v, node t)
Contracts node v and terminal t into v.
void setCapacity(edge e, int capacity)
void initBlowupGraphComponents(const EdgeWeightedGraph< T > &originalGraph, const List< node > &terminals)
Initializes all components in the blowup graph as well as core edges and witness sets.
int numberOfWitnesses(edge e) const
Return the number of witnesses of an edge.
void delEdges(ArrayBuffer< edge > edges)
Removes edges in edges.
void removeIsolatedTerminals()
Removes isolated terminals.
int getY() const
Returns the y-value of all terminals.
int getLCM() const
Returns the least common multiple of all denominators.
node getSource() const
Returns the source node.
void initSource(ArrayBuffer< std::pair< node, int > > &roots)
Connects source to component roots.
void initCoreWitness()
Finds a "random" set of core edges and "replace" found edges by nodes, also find the witness sets for...
void delCore(node e)
Remove a core edge.
edge newEdge(node v, node w, T cost, int capacity)
Adds and returns a new edge between v and w of specified cost and capacity.
void addWitness(node e, edge f)
Adds e to W(f)
node getTarget() const
Returns the target node.
List< node > m_coreEdges
the core edges as nodes
void copyComponent(const edge origEdge, const int origCap, const int copyCap)
Copy a component in the blowup graph and set original capacity to origCap and capacity of copy to cop...
void addCore(node e)
Adds a core edge.
double computeCoreWeight(node v) const
Compute the weight of a core edge.
const FullComponentWithExtraStore< T, double > & m_fullCompStore
all enumerated full components, with solution
int getCapacity(edge e) const
Returns the capacity of e.
edge findRootEdge(node v)
Finds the root node of a component given by v, an arbitrary inner nonterminal of the component.
NodeArray< ArrayBuffer< edge > > m_witness
const List< node > & terminals() const
Returns a reference to the list containing all terminals in the blowup graph.
node getPseudotarget() const
Returns the pseudotarget node.
EdgeArray< int > m_capacity
T getCoreCost(node v) const
Get cost of a core edge.
void initTarget()
Connects target.
const Graph & getGraph() const
const double m_eps
epsilon for double operations
node initBlowupGraphComponent(const NodeArray< node > ©, adjEntry start, int cap)
Does a bfs of the component tree to add directed components with the first terminal as root.
void updateSpecialCapacities()
Updates capacities from source to terminals and terminals to pseudotarget.
node initTerminal(node t)
Inserts a terminal.
void contract(NODELIST &nodes)
Contracts nodes.
void makeCWCopy(const HashArray< edge, edge > &edgeMap)
Copies witness sets and core edges for a given copy map.
node getOriginal(node v) const
Returns the original node of v.
void initPseudotarget()
Connects pseudotarget.
NodeArray< bool > m_isTerminal
Incidence vector for the blowup graph terminals.
void computeLCM()
Computes the least common multiple of the values assigned to the full components.
bool isTerminal(node v) const
Returns true if and only if v is a terminal.
const CoreEdgeModule< T > & m_ceModule
NodeArray< node > m_original
Mapping of blowup graph nodes to original nodes. If a node in a blowup graph represents more than one...
int updateSourceAndTargetArcCapacities(const node v)
Updates arc capacities s->v and v->t.
T getCoreCapacity(node v) const
Get capacity of a core edge.
BlowupGraph(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const FullComponentWithExtraStore< T, double > &fullCompStore, const CoreEdgeModule< T > &ceModule, double eps=1e-8)
Initializes a blowup graph including core edges and witness sets.
const ArrayBuffer< edge > & witnessList(node e) const
Return list of loss edges f in W(e)
EdgeArray< int > m_witnessCard
const List< node > & core() const
Return list of core edges (implemented by nodes)
Interface for core edge finder algorithms.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
T lcm(T a, T b)
Returns the least common multipler of two numbers.
T gcd(T a, T b)
Returns the greatest common divisor of two numbers.
void getFraction(double d, int &num, int &denom, const double epsilon=5e-10, const int count=10)
Converts a double to a fraction.
The namespace for all OGDF objects.