|
Open Graph Drawing Framework |
v. 2023.09 (Elderberry)
|
|
|
Go to the documentation of this file.
88 template<
typename TWeight>
102 std::string& error)
override {
104 error =
"The graph is not simple";
108 error =
"The graph is not connected";
112 error =
"The stretch must be >= 1.0";
214 (*m_inSpanner)[e] =
m_E1[e] ||
m_E2[e];
233 for (
int i = 0; i < max; i++) {
236 edge e1 = inPredecessor[v][n];
241 edge e2 = outPredecessor[v][n];
251 logger.
lout() <<
"add unsettled thick edges" << std::endl;
291 int E1amountThick = 0;
292 int E1amountThinNotInE2 = 0;
294 int E2amountThin = 0;
295 int E2amountThickNotInE1 = 0;
296 int edgesCovered = 0;
297 int duplicateCovered = 0;
303 }
else if (!
m_E2[e]) {
304 E1amountThinNotInE2++;
311 }
else if (!
m_E1[e]) {
312 E2amountThickNotInE1++;
323 logger.
lout() <<
"covered: " << edgesCovered <<
", duplicate edges: " << duplicateCovered
325 logger.
lout() <<
"E1: " << E1amount <<
" edges, " << E1amountThick <<
" thick, "
326 << (E1amount - E1amountThick) <<
" thin, " << E1amountThinNotInE2
327 <<
" thin edges not in E2" << std::endl;
328 logger.
lout() <<
"E2: " << E2amount <<
" edges, " << E2amountThin <<
" thin, "
329 << (E2amount - E2amountThin) <<
" thick, " << E2amountThickNotInE1
330 <<
" thick edges not in E1" << std::endl;
332 #if defined(OGDF_DEBUG)
334 OGDF_ASSERT((E1amountThick + E2amountThin + E1amountThinNotInE2 + E2amountThickNotInE1)
354 int amountNodesInShortestPaths = 0;
358 if (sd == std::numeric_limits<TWeight>::max()
359 || td == std::numeric_limits<TWeight>::max()) {
366 if (
m_eps.
leq((sd + td), maxDistance)) {
367 amountNodesInShortestPaths++;
390 TWeight currentSpannerDistance =
distance(_spanner, _spannerWeight, u, v, ceil(maxDistance));
391 return m_eps.
leq(currentSpannerDistance, maxDistance);
395 const node t,
int maxLookupDist) {
426 m_osi->messageHandler()->setLogLevel(0);
427 m_osi->setObjSense(1);
430 CoinPackedVector
zero;
439 CoinPackedVector* optConstraint =
new CoinPackedVector;
441 optConstraint->insert(indices[e], 1);
444 m_osi->addRow(*optConstraint,
'L', 0, 0);
450 int amountSolverCalls = 0;
452 if (amountSolverCalls == 0) {
453 m_osi->initialSolve();
461 logger.
lout() << amountSolverCalls <<
". solve... ";
462 if (
m_osi->isProvenOptimal()) {
463 logger.
lout() <<
"-> optimal (" <<
m_osi->getObjValue() <<
")" << std::endl;
474 logger.
lout() <<
"-> Found solution\n" << std::endl;
475 logger.
lout() <<
"solver calls: " << amountSolverCalls << std::endl;
480 logger.
lout() <<
"-> New constraint" << std::endl;
487 }
else if (
m_osi->isProvenPrimalInfeasible()) {
488 logger.
lout() <<
"-> Infeasible" << std::endl;
492 }
else if (
m_osi->isProvenDualInfeasible()) {
496 logger.
lout() <<
"-> No solution found" << std::endl;
510 logger.
lout() <<
" OPT is too large. Abort." << std::endl;
514 logger.
lout() <<
" Set OPT to " <<
m_OPT <<
" (" << std::fixed << std::setprecision(2)
515 << percentage <<
"% of " <<
m_nSquared <<
")" << std::endl;
517 m_osi->setRowBounds(0, 0.0,
532 int amountCoveredEdges = 0;
535 amountCoveredEdges++;
541 bool settlesAllThinEdges =
true;
542 edge unsettledThinEdge =
nullptr;
545 settlesAllThinEdges =
false;
546 unsettledThinEdge = e;
551 if (settlesAllThinEdges) {
562 double rowValue = 0.0;
565 if (antispanner[e]) {
566 rowValue += solution[i];
572 CoinPackedVector* c =
new CoinPackedVector;
574 if (antispanner[e]) {
575 c->insert(indices[e], 1);
578 m_osi->addRow(*c,
'G', 1, 0);
610 bool isInLocalSubgraph = (s_e != std::numeric_limits<TWeight>::max()
611 && e_t != std::numeric_limits<TWeight>::max()
616 if (isInLocalSubgraph && out[e]) {
622 antispanner[e] = isInLocalSubgraph && !out[e];
631 if (!antispanner[e]) {
639 antispanner[e] =
false;
645 antispanner[e] =
true;
662 template<
typename TWeight>
The namespace for all OGDF objects.
Stores additional attributes of a graph (like layout information).
Declaration of class GraphAttributes which extends a Graph by additional attributes.
Compare floating point numbers with epsilons and integral numbers with normal compare operators.
Includes declaration of graph class.
static OsiSolverInterface * createCorrectOsiSolverInterface()
Get a new solver and set its initial log level according to the level of CoinLog.
EdgeArray< TWeight > m_spannerWeight
weights for m_spanner Caches, if an edge is thick (or thin).
int m_thickEdgeNodeAmountLimit
n/beta
edge copy(edge e) const override
Returns the edge in the graph copy corresponding to e.
GraphCopySimple * m_spanner
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
void firstPart()
First part of the algorithm: Settle all thick edges.
void randomizedSelection(const double *fractions, EdgeArray< bool > &out)
EdgeArray< TWeight > m_weight
weights of each edge from m_G
double m_sqrtlog
sqrt(n) * ln(n)
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner)
Initializes members and create an empty spanner.
void printStats(bool assert=false)
SeparationResult
Used to indicate the result of the separation method.
virtual void init(const GraphAttributes &GA, double stretch, GraphCopySimple &spanner, EdgeArray< bool > &inSpanner) override
Initializes members and create an empty spanner.
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 assertTimeLeft()
Assert, that time is left.
EdgeArray< bool > m_isThickEdge
EdgeArray< bool > m_E1
Holds the set E1 from the first part of the algorithm.
bool secondPart()
The second part: Settling all thin edges.
Copies of graphs with mapping between nodes and edges.
bool isConnected(const Graph &G)
Returns true iff G is connected.
static constexpr LPSolver whichLPSolver()
Returns the LP-solver used by OGDF.
bool directed() const
Returns if the graph is directed.
std::vector< CoinPackedVector * > m_constraints
Holds all constraints so they can be freed at destruction.
const Graph & constGraph() const
Returns a reference to the associated graph.
NodeArray< NodeArray< TWeight > > m_outDistance
m_outDistance[v][w]: distance from v in a v-rooted out-arborescense to w
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...
Basic module for spanner algorithms.
NodeArray< NodeArray< TWeight > > m_inDistance
m_inDistance[v][w]: distance from v in a v-rooted in-arborescense to w
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.
Contains logging functionality.
virtual SpannerModule< TWeight >::ReturnType execute() override
Executes the core algorithm.
EdgeArray< bool > m_E2
Holds the set E2 from the second part of the algorithm.
Definition of ogdf::CoinManager.
Dijkstra's single source shortest path algorithm.
void resetLP()
Resets the LP defining variables.
@ Log
the object is in logging mode, using its own localLogLevel
int m_OPT
The current guess for our optimal LP value.
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
static void copy(const T &from, T &to)
int numberOfEdges() const
Returns the number of edges in the graph.
OsiSolverInterface * m_osi
the solver.
int numberOfNodes() const
Returns the number of nodes in the graph.
bool isSettledEdge(const edge e)
Shortcut for calling isSettledEdge with m_spanner and the current spanner weights.
Decralation of GraphElement and GraphList classes.
void calculateThickEdges()
node source() const
Returns the source node of the edge.
Declaration of graph copy classes.
RegisteredArray for nodes, edges and adjEntries of a graph.
Data type for general directed graphs (adjacency list representation).
Interface for spanner algorithms.
void addEdgeToSpanner(edge e)
Add an edge to the spanner.
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.
TWeight distance(const GraphCopySimple &G, const EdgeArray< TWeight > &weights, const node s, const node t, int maxLookupDist)
Approximation algorithm for calculating spanners.
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
void createAntispanner(const edge unsettledThinEdge, const EdgeArray< bool > &out, EdgeArray< bool > &antispanner)
Basic declarations, included by all source files.
const GraphAttributes * m_GA
virtual bool preconditionsOk(const GraphAttributes &GA, double stretch, std::string &error) override
void addUnsettledThickEdges()
Class for the representation of edges.
Implementation of Dijkstra's single source shortest path algorithm.
bool isSettledEdge(const edge e, const GraphCopySimple &_spanner, const EdgeArray< TWeight > &_spannerWeight)
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.
Centralized global and local logging facility working on streams like std::cout.
bool setOpt(int opt)
Set a new value for m_OPT.
node target() const
Returns the target node of the edge.
ReturnType
The return type of a module.
void inArborescence(const GraphAttributes &GA, node root, NodeArray< edge > &predecessor, NodeArray< TWeight > &distance)
Calculates an in-arborescense rooted at root.
Class for the representation of nodes.
edge newEdge(edge eOrig)
Creates a new edge in the graph copy with original edge eOrig.
bool isSimple(const Graph &G)
Returns true iff G contains neither self-loops nor parallel edges.
node chooseNode(std::function< bool(node)> includeNode=[](node) { return true;}, bool isFastTest=true) const
Returns a random node.
Declaration of simple graph algorithms.
bool _isThickEdge(edge e)
Actually calculates whether e is thick or not.
void outArborescence(const GraphAttributes &GA, node root, NodeArray< edge > &predecessor, NodeArray< TWeight > &distance)
Calculates an out-arborescense rooted at root.
double randomDouble(double low, double high)
Returns a random double value from the interval [low, high).
const Graph * m_G
const reference to the original graph
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
SeparationResult separation(const double *solution, const EdgeArray< int > &indices)
std::ostream & lout(Level level=Level::Default, bool indent=true) const
stream for logging-output (local)
static TWeight getWeight(const GraphAttributes &GA, edge e)