|
Open Graph Drawing Framework |
v. 2023.09 (Elderberry)
|
|
|
Go to the documentation of this file.
52 template<
typename T,
typename ExtraDataType>
53 class FullComponentWithExtraStore;
62 class EdgeWeightedGraph;
64 namespace steiner_tree {
113 const edge e = adj->theEdge();
134 for (
int id = 1;
id <=
gamma.size(); ++id) {
169 std::unique_ptr<ArrayBuffer<std::pair<node, int>>> basis(
177 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
178 std::cout <<
"Computing min-cost flow for blowup component " <<
id <<
" of "
179 <<
gamma.size() << std::endl;
180 std::cout <<
" * terminals of component are " <<
gamma.terminals(
id) << std::endl;
183 std::cout <<
" * supply node " << v <<
" with supply " << supply[v] << std::endl;
186 std::cout <<
" * demand node " << v <<
" with demand " << -supply[v] << std::endl;
190 std::cout <<
" * edge " << e <<
" with cost " << blowupGraph.
getCost(e)
191 <<
" and flow bounds [" << lB[e] <<
", " << blowupGraph.
getCapacity(e)
204 cost, supply, flow));
207 for (
edge e : sourceCoreEdges) {
209 basis->push(std::make_pair(e->target(), flow[e]));
210 weight -= flow[e] * cost[e];
214 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
215 std::cout <<
"Basis weight is " << weight << std::endl
216 <<
"Checking if " <<
gamma.cost(
id) <<
"(component cost) * "
217 << blowupGraph.
getLCM() <<
"(lcm) <= " << weight <<
"(basis weight)"
223 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
224 std::cout <<
"Using basis because it is feasible." << std::endl;
226 maxBasis.swap(basis);
236 std::unique_ptr<
ArrayBuffer<std::pair<node, int>>>& maxBasis,
241 for (
int id = 1;
id <=
gamma.size(); ++id) {
242 if (
gamma.cost(
id) > cost) {
243 cost =
gamma.cost(
id);
248 maxBasis.reset(
new ArrayBuffer<std::pair<node, int>>());
257 const edge rootEdge) {
261 while (!stack.
empty()) {
268 isNewTerminal[vO] =
true;
282 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
283 std::cout <<
"Remove basis from blowup graph" << std::endl;
289 for (
auto p : basis) {
290 const node v = p.first;
291 const int count = p.second;
294 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
295 std::cout <<
" * node " << v <<
" with count " << count <<
" (of " << origCap <<
")"
298 if (count < origCap) {
300 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
301 std::cout <<
" -> deferred because fractional" << std::endl;
307 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
308 std::cout <<
" -> done" << std::endl;
313 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
314 if (!fractionalCoreEdges.
empty()) {
315 std::cout <<
"Deferred core edges:" << std::endl;
318 for (
auto p : fractionalCoreEdges) {
319 const node v = p.item();
320 const int count = -p.priority();
322 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
323 std::cout <<
" * node " << v <<
" with count " << count <<
" of " << origCap << std::endl;
339 const std::minstd_rand& rng,
double eps = 1e-8)
354 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
355 std::cout <<
"Start solving based on LP solution" << std::endl;
359 BlowupGraph<T> blowupGraph(m_G, m_terminals, m_fullCompStore, cer, m_eps);
361 while (blowupGraph.
terminals().size() > 1) {
362 #ifdef OGDF_STEINER_TREE_GOEMANS_APPROXIMATION_LOGGING
363 std::cout <<
"Iteration " << ++iteration <<
" with " << blowupGraph.
terminals().size()
364 <<
" terminals" << std::endl;
371 std::unique_ptr<ArrayBuffer<std::pair<node, int>>> maxBasis;
372 int compId = blowupGraph.
getY() > 0
373 ? findComponentAndMaxBasis(maxBasis, blowupGraph,
gamma)
374 : findCheapestComponentAndRemainingBasis(maxBasis, blowupGraph,
gamma);
378 addComponent(isNewTerminal, blowupGraph,
gamma.rootEdge(compId));
381 removeFractionalBasisAndCleanup(*maxBasis, blowupGraph,
gamma);
386 if (blowupGraph.
terminals().size() > 1) {
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
The namespace for all OGDF objects.
Computes a min-cost flow using a network simplex method.
Declaration and implementation of ArrayBuffer class.
void solve(NodeArray< bool > &isNewTerminal)
Perform the actual approximation algorithm on the LP solution.
Includes declaration of graph class.
static bool checkComputedFlow(const Graph &G, const EdgeArray< int > &lowerBound, const EdgeArray< int > &upperBound, const EdgeArray< TCost > &cost, const NodeArray< int > &supply, const EdgeArray< int > &flow, TCost &value)
checks if a computed flow is a feasible solution to the given problem instance.
int capacity() const
Returns the current capacity of the datastructure. Note that this value is rather irrelevant if the a...
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
bool empty() const
Returns true if the buffer is empty, false otherwise.
const Graph & getGraph() const
Definition of ogdf::MinCostFlowReinelt class template.
edge findRootEdge(node v)
Finds the root node of a component given by v, an arbitrary inner nonterminal of the component.
void removeBasis(node v)
Removes a basis and cleans up.
virtual bool call(const Graph &G, const EdgeArray< int > &lowerBound, const EdgeArray< int > &upperBound, const EdgeArray< TCost > &cost, const NodeArray< int > &supply, EdgeArray< int > &flow, NodeArray< TCost > &dual) override
Computes a min-cost flow in the directed graph G using a network simplex method.
Computes a max flow via Preflow-Push (global relabeling and gap relabeling heuristic).
E popRet()
Removes the newest element from the buffer and returns it.
Add edges into a blowup graph and delete them on destruction.
Definition of the ogdf::steiner_tree::goemans::BlowupComponents class template.
TemporaryEdges(BlowupGraph< T > &blowupGraph)
Construct object for a specific blowupGraph.
const double m_eps
epsilon for double operations
Class for adjacency list elements.
const List< node > & terminals() const
Returns a reference to the list containing all terminals in the blowup graph.
int getY() const
Returns the y-value of all terminals.
int gammoidGetRank(const BlowupGraph< T > &blowupGraph) const
Computes the rank of the gammoid (given by the blowup graph)
node getOriginal(node v) const
Returns the original node of v.
edge theEdge() const
Returns the edge associated with this adjacency entry.
void removeFractionalBasisAndCleanup(ArrayBuffer< std::pair< node, int >> &basis, BlowupGraph< T > &blowupGraph, BlowupComponents< T > &gamma)
Remove a given basis and cleanup, the basis may be given fractionally.
void addComponent(NodeArray< bool > &isNewTerminal, const BlowupGraph< T > &blowupGraph, const edge rootEdge)
Add a component of the blowup graph to the final solution (by changing nonterminals to terminals)
const List< node > & core() const
Return list of core edges (implemented by nodes)
void quicksort()
Sorts buffer using Quicksort.
int findCheapestComponentAndRemainingBasis(std::unique_ptr< ArrayBuffer< std::pair< node, int >>> &maxBasis, const BlowupGraph< T > &blowupGraph, const BlowupComponents< T > &gamma)
For the end of the algorithm: find cheapest component and choose all remaining core edges as basis.
Declaration and implementation of Goldberg-Tarjan max-flow algorithm with global relabeling and gap r...
const EdgeWeightedGraph< T > & m_G
int findComponentAndMaxBasis(std::unique_ptr< ArrayBuffer< std::pair< node, int >>> &maxBasis, BlowupGraph< T > &blowupGraph, const BlowupComponents< T > &gamma)
Finds the best component and its maximum-weight basis in the given blowup graph with given core and w...
T getCost(edge e) const
Returns the cost of e.
Decralation of GraphElement and GraphList classes.
void delCore(node e)
Remove a core edge.
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
T getCoreCapacity(node v) const
Get capacity of a core edge.
void push(edge e)
Puts a new element in the buffer.
Approximation(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, const FullComponentWithExtraStore< T, double > &fullCompStore, const std::minstd_rand &rng, double eps=1e-8)
Initialize everything.
node getSource() const
Returns the source node.
Definition of ogdf::steiner_tree::goemans::BlowupGraph class template.
node source() const
Returns the source node of the edge.
Doubly linked lists (maintaining the length of the list).
RegisteredArray for nodes, edges and adjEntries of a graph.
Obtain and provides information about components in a given blowup graph.
const List< node > & m_terminals
node getTarget() const
Returns the target node.
bool isLoopFree(const Graph &G)
Returns true iff G contains no self-loop.
edge add(node v, node w, T cost, int capacity)
Add a temporary edge to the blowup graph.
int getLCM() const
Returns the least common multiple of all denominators.
void updateSpecialCapacities()
Updates capacities from source to terminals and terminals to pseudotarget.
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...
Basic declarations, included by all source files.
void contract(node &v, node t)
Contracts node v and terminal t into v.
const EdgeArray< int > & capacities() const
Returns a reference to the edge array containing all capacities.
constexpr double gamma
The Euler-Mascheroni constant gamma.
bool isTerminal(node v) const
Returns true if and only if v is a terminal.
const NodeArray< bool > & m_isTerminal
Augments any data elements of type X with keys of type Priority. This class is also its own Comparer.
Class for the representation of edges.
BlowupGraph< T > & m_blowupGraph
Computes a random set of core edges.
A special-purpose blowup graph for gammoid computation: directed, with special source and target,...
Definition of ogdf::steiner_tree::goemans::CoreEdgeRandomSpanningTree class template.
TCap computeValue(const EdgeArray< TCap > &cap, const node &s, const node &t)
Compute only the value of the flow.
const FullComponentWithExtraStore< T, double > & m_fullCompStore
all enumerated full components, with solution
node target() const
Returns the target node of the edge.
Declarations for Comparer objects.
Class for the representation of nodes.
~TemporaryEdges()
Remove the edges again.
Declaration of simple graph algorithms.
double computeCoreWeight(node v) const
Compute the weight of a core edge.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
The actual 1.39-approximation algorithm by Goemans et al. with a set of terminalized nodes as result.
int getCapacity(edge e) const
Returns the capacity of e.