75template<
typename TWeight>
89 std::string& error)
override {
91 error =
"The graph is not simple";
95 error =
"The graph is not connected";
99 error =
"The stretch must be >= 1.0";
162 m_G = &
GA.constGraph();
201 (*m_inSpanner)[e] =
m_E1[e] ||
m_E2[e];
220 for (
int i = 0; i < max; i++) {
238 logger.
lout() <<
"add unsettled thick edges" << std::endl;
290 }
else if (!
m_E2[e]) {
298 }
else if (!
m_E1[e]) {
314 <<
" thin edges not in E2" << std::endl;
317 <<
" thick edges not in E1" << std::endl;
319#if defined(OGDF_DEBUG)
345 if (
sd == std::numeric_limits<TWeight>::max()
346 ||
td == std::numeric_limits<TWeight>::max()) {
413 m_osi->messageHandler()->setLogLevel(0);
414 m_osi->setObjSense(1);
440 m_osi->initialSolve();
449 if (
m_osi->isProvenOptimal()) {
450 logger.
lout() <<
"-> optimal (" <<
m_osi->getObjValue() <<
")" << std::endl;
461 logger.
lout() <<
"-> Found solution\n" << std::endl;
467 logger.
lout() <<
"-> New constraint" << std::endl;
474 }
else if (
m_osi->isProvenPrimalInfeasible()) {
475 logger.
lout() <<
"-> Infeasible" << std::endl;
479 }
else if (
m_osi->isProvenDualInfeasible()) {
483 logger.
lout() <<
"-> No solution found" << std::endl;
497 logger.
lout() <<
" OPT is too large. Abort." << std::endl;
501 logger.
lout() <<
" Set OPT to " <<
m_OPT <<
" (" << std::fixed << std::setprecision(2)
504 m_osi->setRowBounds(0, 0.0,
562 c->insert(indices[e], 1);
565 m_osi->addRow(*c,
'G', 1, 0);
598 &&
e_t != std::numeric_limits<TWeight>::max()
649template<
typename TWeight>
Basic module for spanner algorithms.
static OsiSolverInterface * createCorrectOsiSolverInterface()
Get a new solver and set its initial log level according to the level of CoinLog.
static constexpr LPSolver whichLPSolver()
Returns the LP-solver used by OGDF.
Dijkstra's single source shortest path algorithm.
void callUnbound(const Graph &G, const EdgeArray< T > &weight, const List< node > &sources, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed=false, bool arcsReversed=false)
Calculates, based on the graph G with corresponding edge costs and source nodes, the shortest paths a...
void callBound(const Graph &G, const EdgeArray< T > &weight, const List< node > &sources, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed, bool arcsReversed, node target, T maxLength=std::numeric_limits< T >::max())
Calculates, based on the graph G with corresponding edge costs and source nodes, the shortest paths a...
Dynamic arrays indexed with edges.
void init()
Reinitializes the array. Associates the array with no graph.
Class for the representation of edges.
node target() const
Returns the target node of the edge.
node source() const
Returns the source node of the edge.
std::enable_if< std::is_integral< T >::value, bool >::type leq(const T &x, const T &y) const
Compare if x is LEQ than y for integral types.
std::enable_if< std::is_integral< T >::value, bool >::type geq(const T &x, const T &y) const
Compare if x is GEQ to y for integral types.
std::enable_if< std::is_integral< T >::value, bool >::type less(const T &x, const T &y) const
Compare if x is LESS than y for integral types.
Stores additional attributes of a graph (like layout information).
bool directed() const
Returns if the graph is directed.
Copies of graphs with mapping between nodes and edges.
edge newEdge(edge eOrig)
Creates a new edge in the graph copy with original edge eOrig.
virtual void delEdge(edge e) override
Removes edge e.
node copy(node v) const
Returns the node in the graph copy corresponding to v.
node newNode(node vOrig)
Creates a new node in the graph copy with original node vOrig.
void createEmpty(const Graph &G)
Re-initializes the copy using G, but does not create any nodes or edges.
Data type for general directed graphs (adjacency list representation).
node chooseNode(std::function< bool(node)> includeNode=[](node) { return true;}, bool isFastTest=true) const
Returns a random node.
int numberOfNodes() const
Returns the number of nodes in the graph.
int numberOfEdges() const
Returns the number of edges in the graph.
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Centralized global and local logging facility working on streams like std::cout.
@ Log
the object is in logging mode, using its own localLogLevel
std::ostream & lout(Level level=Level::Default) const
stream for logging-output (local)
ReturnType
The return type of a module.
Dynamic arrays indexed with nodes.
Class for the representation of nodes.
Approximation algorithm for calculating spanners.
void randomizedSelection(const double *fractions, EdgeArray< bool > &out)
void firstPart()
First part of the algorithm: Settle all thick edges.
void printStats(bool assert=false)
EdgeArray< bool > m_isThickEdge
bool secondPart()
The second part: Settling all thin edges.
bool isSettledEdge(const edge e, const GraphCopySimple &_spanner, const EdgeArray< TWeight > &_spannerWeight)
bool isSettledEdge(const edge e)
Shortcut for calling isSettledEdge with m_spanner and the current spanner weights.
const Graph * m_G
const reference to the original graph
int m_OPT
The current guess for our optimal LP value.
SeparationResult
Used to indicate the result of the separation method.
EdgeArray< bool > m_E1
Holds the set E1 from the first part of the algorithm.
EdgeArray< bool > m_E2
Holds the set E2 from the second part of the algorithm.
NodeArray< NodeArray< TWeight > > m_outDistance
m_outDistance[v][w]: distance from v in a v-rooted out-arborescense to w
int m_thickEdgeNodeAmountLimit
n/beta
EdgeArray< TWeight > m_spannerWeight
weights for m_spanner Caches, if an edge is thick (or thin).
SeparationResult separation(const double *solution, const EdgeArray< int > &indices)
OsiSolverInterface * m_osi
the solver.
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner) override
Initializes members and create an empty spanner.
void outArborescence(const GraphAttributes &GA, node root, NodeArray< edge > &predecessor, NodeArray< TWeight > &distance)
Calculates an out-arborescense rooted at root.
virtual SpannerModule< TWeight >::ReturnType execute() override
Executes the core algorithm.
NodeArray< NodeArray< TWeight > > m_inDistance
m_inDistance[v][w]: distance from v in a v-rooted in-arborescense to w
void addUnsettledThickEdges()
void inArborescence(const GraphAttributes &GA, node root, NodeArray< edge > &predecessor, NodeArray< TWeight > &distance)
Calculates an in-arborescense rooted at root.
void addEdgeToSpanner(edge e)
Add an edge to the spanner.
virtual bool preconditionsOk(const GraphAttributes &GA, double stretch, std::string &error) override
bool setOpt(int opt)
Set a new value for m_OPT.
bool _isThickEdge(edge e)
Actually calculates whether e is thick or not.
std::vector< CoinPackedVector * > m_constraints
Holds all constraints so they can be freed at destruction.
EdgeArray< TWeight > m_weight
weights of each edge from m_G
void calculateThickEdges()
void createAntispanner(const edge unsettledThinEdge, const EdgeArray< bool > &out, EdgeArray< bool > &antispanner)
void resetLP()
Resets the LP defining variables.
double m_sqrtlog
sqrt(n) * ln(n)
TWeight distance(const GraphCopySimple &G, const EdgeArray< TWeight > &weights, const node s, const node t, int maxLookupDist)
Interface for spanner algorithms.
void assertTimeLeft()
Assert, that time is left.
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner)
Initializes members and create an empty spanner.
const GraphAttributes * m_GA
EdgeArray< bool > * m_inSpanner
static TWeight getWeight(const GraphAttributes &GA, edge e)
GraphCopySimple * m_spanner
Definition of ogdf::CoinManager.
Declaration of extended graph algorithms.
bool isConnected(const Graph &G)
Returns true iff G is connected.
bool isSimple(const Graph &G)
Returns true iff G contains neither self-loops nor parallel edges.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
double randomDouble(double low, double high)
Returns a random double value from the interval [low, high).
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
Declaration of simple graph algorithms.