QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgsgraphanalyzer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgraphanalyzer.cpp
3 --------------------------------------
4 Date : 2011-04-14
5 Copyright : (C) 2010 by Yakushev Sergey
6 Email : YakushevS <at> list.ru
7****************************************************************************
8* *
9* This program is free software; you can redistribute it and/or modify *
10* it under the terms of the GNU General Public License as published by *
11* the Free Software Foundation; either version 2 of the License, or *
12* (at your option) any later version. *
13* *
14***************************************************************************/
15
16#include "qgsgraphanalyzer.h"
17
18#include <limits>
19
20#include "qgsgraph.h"
21
22#include <QMap>
23#include <QPair>
24#include <QVector>
25
26void QgsGraphAnalyzer::dijkstra( const QgsGraph *source, int startPointIdx, int criterionNum, QVector<int> *resultTree, QVector<double> *resultCost )
27{
28 if ( startPointIdx < 0 || startPointIdx >= source->vertexCount() )
29 {
30 // invalid start point
31 return;
32 }
33
34 QVector<double> *result = nullptr;
35 if ( resultCost )
36 {
37 result = resultCost;
38 }
39 else
40 {
41 result = new QVector<double>();
42 }
43
44 result->clear();
45 result->insert( result->begin(), source->vertexCount(), std::numeric_limits<double>::infinity() );
46 ( *result )[startPointIdx] = 0.0;
47
48 if ( resultTree )
49 {
50 resultTree->clear();
51 resultTree->insert( resultTree->begin(), source->vertexCount(), -1 );
52 }
53
54 // QMultiMap< cost, vertexIdx > not_begin
55 // I use it and don't create any struct or class
56 QMultiMap<double, int> not_begin;
57 QMultiMap<double, int>::iterator it;
58
59 not_begin.insert( 0.0, startPointIdx );
60
61 while ( !not_begin.empty() )
62 {
63 it = not_begin.begin();
64 const double curCost = it.key();
65 const int curVertex = it.value();
66 not_begin.erase( it );
67
68 // edge index list
69 const QgsGraphEdgeIds &outgoingEdges = source->vertex( curVertex ).outgoingEdges();
70 for ( const int edgeId : outgoingEdges )
71 {
72 const QgsGraphEdge &arc = source->edge( edgeId );
73 const double cost = arc.cost( criterionNum ).toDouble() + curCost;
74
75 if ( cost < ( *result )[arc.toVertex()] )
76 {
77 ( *result )[arc.toVertex()] = cost;
78 if ( resultTree )
79 {
80 ( *resultTree )[arc.toVertex()] = edgeId;
81 }
82 not_begin.insert( cost, arc.toVertex() );
83 }
84 }
85 }
86 if ( !resultCost )
87 {
88 delete result;
89 }
90}
91
92QgsGraph *QgsGraphAnalyzer::shortestTree( const QgsGraph *source, int startVertexIdx, int criterionNum )
93{
94 QgsGraph *treeResult = new QgsGraph();
95 QVector<int> tree;
96
97 QgsGraphAnalyzer::dijkstra( source, startVertexIdx, criterionNum, &tree );
98
99 // sourceVertexIdx2resultVertexIdx
100 QVector<int> source2result( tree.size(), -1 );
101
102 // Add reachable vertices to the result
103 source2result[startVertexIdx] = treeResult->addVertex( source->vertex( startVertexIdx ).point() );
104 int i = 0;
105 for ( i = 0; i < source->vertexCount(); ++i )
106 {
107 if ( tree[i] != -1 )
108 {
109 source2result[i] = treeResult->addVertex( source->vertex( i ).point() );
110 }
111 }
112
113 // Add arcs to the result
114 for ( i = 0; i < source->vertexCount(); ++i )
115 {
116 if ( tree[i] != -1 )
117 {
118 const QgsGraphEdge &arc = source->edge( tree[i] );
119
120 treeResult->addEdge( source2result[arc.fromVertex()], source2result[arc.toVertex()], arc.strategies() );
121 }
122 }
123
124 return treeResult;
125}
static void dijkstra(const QgsGraph *source, int startVertexIdx, int criterionNum, QVector< int > *resultTree=nullptr, QVector< double > *resultCost=nullptr)
Solve shortest path problem using Dijkstra algorithm.
static QgsGraph * shortestTree(const QgsGraph *source, int startVertexIdx, int criterionNum)
Returns shortest path tree with root-node in startVertexIdx.
Represents an edge in a graph.
Definition qgsgraph.h:44
int fromVertex() const
Returns the index of the vertex at the start of this edge.
Definition qgsgraph.cpp:180
QVector< QVariant > strategies() const
Returns array of available strategies.
Definition qgsgraph.cpp:175
int toVertex() const
Returns the index of the vertex at the end of this edge.
Definition qgsgraph.cpp:185
QVariant cost(int strategyIndex) const
Returns edge cost calculated using specified strategy.
Definition qgsgraph.cpp:170
QgsGraphEdgeIds outgoingEdges() const
Returns outgoing edge ids, i.e.
Definition qgsgraph.cpp:200
QgsPointXY point() const
Returns point associated with graph vertex.
Definition qgsgraph.cpp:205
Mathematical graph representation.
Definition qgsgraph.h:131
const QgsGraphVertex & vertex(int idx) const
Returns the vertex at the given index.
Definition qgsgraph.cpp:48
int addEdge(int fromVertexIdx, int toVertexIdx, const QVector< QVariant > &strategies)
Add an edge to the graph, going from the fromVertexIdx to toVertexIdx.
Definition qgsgraph.cpp:31
const QgsGraphEdge & edge(int idx) const
Returns the edge at the given index.
Definition qgsgraph.cpp:77
int addVertex(const QgsPointXY &pt)
Add a vertex to the graph.
Definition qgsgraph.cpp:25
int vertexCount() const
Returns number of graph vertices.
Definition qgsgraph.cpp:116
QList< int > QgsGraphEdgeIds
Definition qgsgraph.h:81