157 m_activeComponentIterators.clear();
158 m_activeComponents.clear();
159 m_componentMapping.init(*m_pGraph);
160 m_priorities.init(*m_pGraph, 0);
165 return m_pComponents->find(m_componentMapping[v]);
170 return m_activeComponentIterators[component].valid();
175 m_activeComponentIterators[
comp] = m_activeComponents.pushBack(
comp);
180 int compV = getComponent(v);
181 int compW = getComponent(w);
184 if (isActive(
compV)) {
185 m_activeComponents.del(m_activeComponentIterators[
compV]);
187 if (isActive(
compW)) {
188 m_activeComponents.del(m_activeComponentIterators[
compW]);
193 if (!m_activeComponents.empty()) {
201 m_pGraph->allNodes(nodes);
202 for (
node v : nodes) {
203 if (isActive(getComponent(v))) {
204 m_priorities(v) += eps;
211 double result = MAX_VALUE;
215 m_pGraph->allEdges(edges);
216 for (
edge e : edges) {
217 node v = e->source();
218 node w = e->target();
219 int compV = getComponent(v);
220 int compW = getComponent(w);
222 double value = m_pGraph->weight(e) - m_priorities(v) - m_priorities(w);
229 if (*
nextEdge ==
nullptr || value < result) {
243 m_pTerminals = &terminals;
244 m_pIsTerminal = &isTerminal;
255 m_pGraph->allNodes(nodes);
256 for (
node v : nodes) {
257 int comp = m_pComponents->makeSet();
258 m_componentMapping[v] =
comp;
264#ifdef OGDF_MINSTEINERTREE_PRIMAL_DUAL_LOGGING
265 std::cout <<
"Goemans primal-dual starting..." << std::endl;
266 std::cout <<
"terminals:";
267 for (
node v : *m_pTerminals) {
268 std::cout <<
" " << v;
270 std::cout << std::endl;
272 std::cout <<
"loop starting... " << std::endl;
276 while (!m_activeComponents.empty()) {
277#ifdef OGDF_MINSTEINERTREE_PRIMAL_DUAL_LOGGING
278 std::cout <<
"active component exists" << std::endl;
282 double minValue = getNextEdge(&
minEdge);
285#ifdef OGDF_MINSTEINERTREE_PRIMAL_DUAL_LOGGING
286 std::cout <<
"minEdge found: " <<
minEdge <<
", weight is " << m_pGraph->weight(
minEdge)
287 <<
", adjusted weight is " << minValue << std::endl;
301 T weight = m_pGraph->weight(
minEdge);
305 m_lowerBound += m_activeComponents.size() * minValue;
307 mergeComponents(v, w);
309 updatePriorities(minValue);
311 result -= this->pruneAllDanglingSteinerPaths(*
finalSteinerTree, *m_pIsTerminal);
313#ifdef OGDF_MINSTEINERTREE_PRIMAL_DUAL_LOGGING
314 std::cout <<
"calculation finished!" << std::endl;
Implementation of disjoint sets data structures (union-find functionality).
Extends the GraphCopy concept to weighted graphs.
Declaration of ogdf::MinSteinerTreeModule.
A Union/Find data structure for maintaining disjoint sets.
Class for the representation of edges.
Indexed arrays using hashing for element access.
Doubly linked lists (maintaining the length of the list).
Serves as an interface for various methods to compute or approximate minimum Steiner trees on undirec...
virtual T call(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree)
Calls the Steiner tree algorithm for nontrivial cases but handles trivial cases directly.
Primal-Dual approximation algorithm for Steiner tree problems.
const NodeArray< bool > * m_pIsTerminal
virtual T call(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree) override
Calls the Steiner tree algorithm for nontrivial cases but handles trivial cases directly.
List< int > m_activeComponents
void mergeComponents(const node v, const node w)
Merges two disjoint components.
int getComponent(const node v) const
Finds the biggest set including node v.
void updatePriorities(double eps)
Must be called after merging any two components.
NodeArray< int > m_componentMapping
double getLastLowerBound() const
Returns the lower bound calculated while solving the last problem.
HashArray< int, ListIterator< int > > m_activeComponentIterators
double getNextEdge(edge *nextEdge)
Idendifies the next edge with a tight-to-be packing constraint.
NodeArray< double > m_priorities
void init()
Initializes all required datastructes.
bool isActive(int component) const
Returns whether the given component is active.
const EdgeWeightedGraph< T > * m_pGraph
const List< node > * m_pTerminals
void makeActive(int component)
Marks the specified component as active.
virtual T computeSteinerTree(const EdgeWeightedGraph< T > &G, const List< node > &terminals, const NodeArray< bool > &isTerminal, EdgeWeightedGraphCopy< T > *&finalSteinerTree) override
Builds a minimum Steiner tree given a weighted graph and a list of terminals.
DisjointSets * m_pComponents
Dynamic arrays indexed with nodes.
Class for the representation of nodes.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.