52template<
typename T,
typename ExtraDataType>
53class FullComponentWithExtraStore;
60class EdgeWeightedGraph;
62namespace steiner_tree {
133 denominators.
push(denom);
137 for (
int denom : denominators) {
140#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
141 std::cout <<
"Normalizing factor is " <<
m_lcm << std::endl;
151#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
152 std::cout <<
"Add terminal " << v <<
" representing original terminal " << t << std::endl;
171 while (!queueT.
empty()) {
196#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
197 std::cout <<
"Add source node " <<
getSource() <<
" with edges to:" << std::endl;
199 for (
auto root : roots) {
200#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
201 std::cout <<
" * node " << root.first <<
" with cost 0 and capacity " << root.second
220 roots.
push(std::make_pair(root, cap));
225#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
227 std::cout <<
"Edge from " << e <<
" of cost " <<
m_cost[e] <<
" and capacity "
244#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
246 <<
" with edges coming from:" << std::endl;
253 for (
adjEntry adj : v->adjEntries) {
262#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
263 std::cout <<
" * terminal " << v <<
" with zero cost and capacity " << y_v
277#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
278 std::cout <<
"Add edge from pseudo-target " <<
getPseudotarget() <<
" to target "
279 <<
getTarget() <<
" with zero cost and capacity " <<
m_y << std::endl;
285#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
286 std::cout <<
" * updating for terminal " << v << std::endl;
290 int capTarget = -
getLCM();
291#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
292 std::cout <<
" * target capacity initialized to " << capTarget
293 <<
", source capacity and delta to 0" << std::endl;
299#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
300 std::cout <<
" * remove edge with capacity " <<
getCapacity(adj->theEdge())
301 <<
" from source " <<
getSource() << std::endl;
308#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
310 <<
" with capacity " <<
getCapacity(adj->theEdge())
311 <<
" participating in delta" << std::endl;
319#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
320 std::cout <<
" * update target capacity for edge " << adj->theEdge()
321 <<
" by adding " <<
getCapacity(adj->theEdge()) << std::endl;
326 if (v != adj->theEdge()->target()) {
327#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
328 std::cout <<
" and change source capacity by the same amount" << std::endl;
334#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
335 std::cout <<
" * new target capacity is " << capTarget <<
" and delta = " << delta
341#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
342 std::cout <<
" * new edge from pseudotarget to target with zero cost and capacity "
343 << capTarget << std::endl;
347#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
348 std::cout <<
" * new edge from source to " << v <<
" with zero cost and capacity "
349 << capSource << std::endl;
354 return delta + capTarget;
389 if (!isLossEdge[e]) {
400 while (!stack.
empty()) {
405 const edge e = adj->theEdge();
406 const node w = adj->twinNode();
407 if (!pred[v] || w != pred[v]->theNode()) {
412 for (
node x = v; pred[x]; x = pred[x]->theNode()) {
422 for (
edge e : coreEdges) {
424 const node x = splitMap[e];
427 newEdge(e->source(), x, w, cap);
428 newEdge(x, e->target(), 0, cap);
442 const edge eO = pair.key();
443 const edge eC = pair.info();
486#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
487 std::cout <<
"Full components to use in blowup graph:\n";
572#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
573 std::cout <<
"Updating capacities (y = " <<
m_y <<
")" << std::endl;
577#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
578 std::cout <<
" * new y = " <<
m_y << std::endl;
596 for (
edge e : edges) {
620 template<
typename NODELIST>
622 auto it = nodes.begin();
624 for (++it; it != nodes.end(); ++it) {
642 while (!cleanup.
empty()) {
647#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
648 std::cout <<
" * remove pendant node " << v <<
" for cleanup" << std::endl;
652 }
else if (v->
indeg() == 0) {
653#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
654 std::cout <<
" * " << v <<
" has no incoming edge -> fix directions"
659#ifdef OGDF_STEINER_TREE_GOEMANS_BLOWUP_GRAPH_LOGGING
660 std::cout <<
" * make " << w <<
" parent of " << v <<
" (reverse edge "
661 << e <<
")" << std::endl;
682 if ((*it)->degree() == 0) {
691 edge rootEdge =
nullptr;
694 edge e = (*it)->theEdge();
721 while (!todo.
empty()) {
Declaration and implementation of ArrayBuffer class.
Includes declaration of graph class.
Decralation of GraphElement and GraphList classes.
Declaration and implementation of HashArray class.
Declaration of classes used for hashing.
Declaration of doubly linked lists and iterators.
Basic declarations, included by all source files.
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.
Class for the representation of edges.
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
node target() const
Returns the target node of the edge.
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.
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.
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.
void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter)
Moves adjacency entry adjMove after adjAfter.
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.
E popFrontRet()
Removes the first element from the list and returns it.
Encapsulates a pointer to a list element.
bool valid() const
Returns true iff the iterator points to an element.
bool empty() const
Returns true iff the list is empty.
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.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
RegisteredArray for nodes, edges and adjEntries of a graph.
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.
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.