59class EdgeWeightedGraph;
149 std::minstd_rand rng(m_seed);
152 Main main(G, sortedTerminals, isTerminal, m_restricted, m_use2approx, m_separateCycles);
153 return main.getApproximation(finalSteinerTree, rng, m_preprocess);
189 void find3RestrictedComponents();
191 void findFullComponentsDW();
193 void findFullComponentsEMV();
195 template<
typename FCG>
196 void retrieveComponents(
const FCG& fcg);
198 void findFullComponents();
206 for (
int k = m_fullCompStore.size() - 1; k >= 0; --k) {
208 if (m_fullCompStore.extra(k) <= m_eps) {
209 m_fullCompStore.remove(k);
217 for (
int i = ids.
size() - 1; i >= 0; --i) {
218 m_fullCompStore.remove(ids[i]);
224 m_fullCompStore.foreachNode(
id, [&](
node v) { isNewTerminal[v] =
true; });
235 for (
int i = 0; i < m_fullCompStore.size(); ++i) {
236 const node center =
H.newNode();
240 for (
node vG : m_fullCompStore.terminals(i)) {
246 H.newEdge(vH, center);
261 innerNodes += (adj->twinNode()->degree() != 1);
263 if (innerNodes <= 1) {
265 addComponent(isNewTerminal,
id[c]);
268 inactive.
push(
id[c]);
277 removeComponents(inactive);
288 , m_isTerminal(isTerminal)
289 , m_terminals(terminals)
290 , m_fullCompStore(G, m_terminals, isTerminal)
294 , m_approx2SteinerTree(nullptr)
295 , m_approx2Weight(0) {
298 m_approx2Weight = mstT.
call(m_G, m_terminals, m_isTerminal, m_approx2SteinerTree);
305 findFullComponents();
319 const bool doPreprocessing =
true);
338 fcg.
call(m_G, m_terminals, m_isTerminal, distance, pred,
344 minComp.
newEdge(minComp.
newNode(t0), minCenterC, distance[t0][minCenter]);
345 minComp.
newEdge(minComp.
newNode(t1), minCenterC, distance[t1][minCenter]);
346 minComp.
newEdge(minComp.
newNode(t2), minCenterC, distance[t2][minCenter]);
347 m_fullCompStore.insert(minComp);
359 findFull2Components(distance, pred);
361 findFull3Components(distance, pred);
366template<
typename FCG>
372 terminalSubset.
list(terminals);
373 fcg.getSteinerTreeFor(terminals, component);
374 if (fcg.isValidComponent(component)) {
375 m_fullCompStore.insert(component);
390 retrieveComponents(fcg);
398 retrieveComponents(fcg);
405 m_G.numberOfEdges())) {
406 findFullComponentsEMV();
408 findFullComponentsDW();
411 find3RestrictedComponents();
417 const std::minstd_rand& rng,
const bool doPreprocessing) {
420 finalSteinerTree = m_approx2SteinerTree;
421 return m_approx2Weight;
424 removeInactiveComponents();
427 for (
node v : m_terminals) {
428 isNewTerminal[v] =
true;
431 if (doPreprocessing) {
432 preprocess(isNewTerminal);
435 if (!m_fullCompStore.isEmpty()) {
437 m_fullCompStore, rng, m_eps);
438 approx.
solve(isNewTerminal);
444 if (m_approx2Weight < cost) {
445 delete finalSteinerTree;
446 finalSteinerTree = m_approx2SteinerTree;
447 cost = m_approx2Weight;
449 delete m_approx2SteinerTree;
Definition of ogdf::steiner_tree::goemans::Approximation class template.
Declaration and implementation of ArrayBuffer class.
Extends the GraphCopy concept to weighted graphs.
Definition of ogdf::steiner_tree::Full2ComponentGenerator class template.
Definition of ogdf::steiner_tree::Full3ComponentGeneratorVoronoi class template.
Definition of the FullComponentDecisions class.
Definition of the FullComponentGeneratorCaller class template.
Definition of the ogdf::steiner_tree::FullComponentGeneratorDreyfusWagner class template.
Definition of the ogdf::steiner_tree::FullComponentGeneratorDreyfusWagnerWithoutMatrix class template...
Definition of the FullComponentStore class template.
Includes declaration of graph class.
Decralation of GraphElement and GraphList classes.
Definition of ogdf::steiner_tree::LPRelaxationSER class template.
Declaration of doubly linked lists and iterators.
Declaration of ogdf::MinSteinerTreeModule.
Implementation of the 2(1-1/l)-approximation algorithm for the minimum Steiner tree problem by Matsuy...
A class that allows to enumerate k-subsets.
Basic declarations, included by all source files.
Class for adjacency list elements.
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
void push(E e)
Puts a new element in the buffer.
void quicksort()
Sorts buffer using Quicksort.
INDEX size() const
Returns number of elements in the buffer.
edge newEdge(node u, node v, T weight)
void setOriginalGraph(const Graph *wG) override
Re-initializes the copy using G (which might be null), but does not create any nodes or edges.
node newNode(node vOrig)
Creates a new node in the graph copy with original node vOrig.
Data type for general directed graphs (adjacency list representation).
Doubly linked lists (maintaining the length of the list).
int size() const
Returns the number of elements in the list.
iterator pushBack(const E &x)
Adds element x at the end of the list.
void del(iterator it)
Removes it from the list.
Encapsulates a pointer to a list element.
bool valid() const
Returns true iff the iterator points to an element.
ListIteratorBase< E, isConst, isReverse > succ() const
Returns successor iterator.
iterator begin()
Returns an iterator to the first element of the list.
Class managing LP-based approximation.
const List< node > & m_terminals
List of terminals.
T getApproximation(EdgeWeightedGraphCopy< T > *&finalSteinerTree, const std::minstd_rand &rng, const bool doPreprocessing=true)
Obtain an (1.39+epsilon)-approximation based on the LP solution.
void removeComponents(ArrayBuffer< int > &ids)
Remove the full components with the given ids.
void addComponent(NodeArray< bool > &isNewTerminal, int id)
Add a full component to the final solution (by changing nonterminals to terminals)
const NodeArray< bool > & m_isTerminal
const EdgeWeightedGraph< T > & m_G
const double m_eps
epsilon for double operations
void removeInactiveComponents()
Remove inactive components from m_fullCompStore (since we do not need them any longer)
void find3RestrictedComponents()
Find 3-restricted components.
void retrieveComponents(const FCG &fcg)
Auxiliary function to retrieve components by Dreyfus-Wagner/Erickson et al implementation.
void findFullComponents()
Find full components.
steiner_tree::FullComponentWithExtraStore< T, double > m_fullCompStore
all enumerated full components, with solution
void findFull2Components(const NodeArray< NodeArray< T > > &distance, const NodeArray< NodeArray< edge > > &pred)
Find full components of size 2.
EdgeWeightedGraphCopy< T > * m_approx2SteinerTree
void findFullComponentsEMV()
Find full components using algorithm by Erickson et al.
Main(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, int restricted, bool use2approx, bool separateCycles, double eps=1e-8)
Initialize all attributes, sort the terminal list.
void preprocess(NodeArray< bool > &isNewTerminal)
Preprocess LP solution.
void findFullComponentsDW()
Find full components using algorithm by Dreyfus-Wagner.
void findFull3Components(const NodeArray< NodeArray< T > > &distance, const NodeArray< NodeArray< edge > > &pred)
Find full components of size 3.
Approx2State m_use2approx
This class implements the (1.39+epsilon)-approximation algorithm for the Steiner tree problem by Goem...
void setSeed(int seed)
Set seed for the random number generation.
void setMaxComponentSize(int k)
Sets the maximal number of terminals in a full component.
virtual ~MinSteinerTreeGoemans139()
void separateCycles(bool separateCycles=true)
Use stronger LP relaxation (not recommended in general)
void disablePreprocessing(bool preprocess=true)
Disable preprocessing of LP solutions.
MinSteinerTreeGoemans139()
virtual T computeSteinerTree(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree) override
Builds a minimum Steiner tree for a given weighted graph with terminals.
void use2Approximation(bool use2approx=true)
Use Takahashi-Matsuyama 2-approximation as upper bounds.
Serves as an interface for various methods to compute or approximate minimum Steiner trees on undirec...
static void sortTerminals(List< node > &terminals)
Sort terminals by index.
This class implements the minimum Steiner tree 2-approximation algorithm by Takahashi and Matsuyama w...
virtual T call(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree, const node startNode)
An extended call method with specific start node.
Class for the representation of nodes.
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
Enumerator for k-subsets of a given type.
void begin(int low, int high)
Initializes the SubsetEnumerator to enumerate subsets of cardinalities from low to high.
bool valid() const
Checks if the current subset is valid. If not, the subset is either not initialized or all subsets ha...
void list(List< T > &subset) const
Obtains (appends) a list of the subset members.
void next()
Obtains the next subset if possible. The result should be checked using the valid() method.
RegisteredArray for nodes, edges and adjEntries of a graph.
Trivial full 2-component generation by lookups of shortest paths between terminal pairs.
void call(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< NodeArray< T > > &distance, const NodeArray< NodeArray< edge > > &pred, std::function< void(node, node, T)> generateFunction) const
Generate full 2-components and call generateFunction for each full 2-component.
Full 3-component generation using Voronoi regions.
void call(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, const NodeArray< NodeArray< T > > &distance, const NodeArray< NodeArray< edge > > &pred, std::function< void(node, node, node, node, T)> generateFunction) const
Generate full components and call generateFunction for each full component.
static void computeDistanceMatrix(NodeArray< NodeArray< T > > &distance, NodeArray< NodeArray< edge > > &pred, const EdgeWeightedGraph< T > &graph, const List< node > &terminals, const NodeArray< bool > &isTerminal, int restricted)
Computes distance and predecessor matrix.
A generator for restricted full components (for Steiner tree approximations) based on the Dreyfus-Wag...
void call(int restricted)
A generator for restricted full components (for Steiner tree approximations) based on the Dreyfus-Wag...
void call(int restricted)
void insert(const EdgeWeightedGraphCopy< T > &comp)
Inserts a component. Note that comp is copied and degree-2 nodes are removed.
Class managing the component-based subtour elimination LP relaxation for the Steiner tree problem and...
bool solve()
Solve the LP. The solution will be written to the extra data of the full component store.
The actual 1.39-approximation algorithm by Goemans et al. with a set of terminalized nodes as result.
void solve(NodeArray< bool > &isNewTerminal)
Perform the actual approximation algorithm on the LP solution.
Algorithms used by at least two functions of Steiner tree code or its internal helpers.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
T obtainFinalSteinerTree(const EdgeWeightedGraph< T > &G, const NodeArray< bool > &isTerminal, const NodeArray< bool > &isOriginalTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree)
The namespace for all OGDF objects.
static bool shouldUseErickson(int n, int m)
Returns true iff the rule of thumb predicts to use the algorithm by Erickson et al instead of the Dre...