Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions docqueries/depthFirstSearch/doc-pgr_depthFirstSearch.result
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,5 @@ BEGIN;
BEGIN
SET client_min_messages TO NOTICE;
SET
--q1
SELECT * FROM pgr_depthFirstSearch(
'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id',
2
);
seq | depth | start_vid | node | edge | cost | agg_cost
-----+-------+-----------+------+------+------+----------
(0 rows)

--q2
SELECT * FROM pgr_depthFirstSearch(
'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id',
ARRAY[13,2], max_depth := 3
);
seq | depth | start_vid | node | edge | cost | agg_cost
-----+-------+-----------+------+------+------+----------
(0 rows)

--q3
SELECT * FROM pgr_depthFirstSearch(
'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id',
0
);
seq | depth | start_vid | node | edge | cost | agg_cost
-----+-------+-----------+------+------+------+----------
(0 rows)

ROLLBACK;
ROLLBACK
15 changes: 0 additions & 15 deletions docqueries/depthFirstSearch/doc-pgr_depthFirstSearch.test.sql
Original file line number Diff line number Diff line change
@@ -1,15 +0,0 @@
\echo --q1
SELECT * FROM pgr_depthFirstSearch(
'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id',
2
);
\echo --q2
SELECT * FROM pgr_depthFirstSearch(
'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id',
ARRAY[13,2], max_depth := 3
);
\echo --q3
SELECT * FROM pgr_depthFirstSearch(
'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id',
0
);
121 changes: 121 additions & 0 deletions include/depthFirstSearch/pgr_depthFirstSearch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*PGR-GNU*****************************************************************
File: pgr_depthFirstSearch.hpp

Copyright (c) 2020 pgRouting developers
Mail: project@pgrouting.org

Copyright (c) 2020 Ashish Kumar
Mail: ashishkr23438@gmail.com

------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
********************************************************************PGR-GNU*/

#ifndef INCLUDE_DEPTHFIRSTSEARCH_PGR_DEPTHFIRSTSEARCH_HPP_
#define INCLUDE_DEPTHFIRSTSEARCH_PGR_DEPTHFIRSTSEARCH_HPP_
#pragma once


#include <visitors/dfs_visitor_with_root.hpp>
#include <boost/graph/depth_first_search.hpp>

#include <vector>

#include "cpp_common/pgr_base_graph.hpp"
#include "cpp_common/pgr_messages.h"

namespace pgrouting {
namespace functions {

template <class G>
class Pgr_depthFirstSearch : public pgrouting::Pgr_messages {
public:
typedef typename G::V V;
typedef typename G::E E;

// TODO(ashish): Use both boost::depth_first_search and boost::undirected_dfs below,
// for directed and undirected graphs.

std::vector<pgr_mst_rt> depthFirstSearch(
G &graph,
std::vector<int64_t> roots,
int64_t depth) {
std::vector<pgr_mst_rt> results;
using dfs_visitor = visitors::Dfs_visitor_with_root<V, E>;

for (auto root : roots) {
std::vector<E> visited_order;

if (graph.has_vertex(root)) {
results.push_back({root, 0, root, -1, 0.0, 0.0});
try {
boost::depth_first_search(
graph.graph,
visitor(dfs_visitor(graph.get_V(root), visited_order))
.root_vertex(graph.get_V(root)));
} catch(found_goals &) {
{}
} catch (boost::exception const& ex) {
(void)ex;
throw;
} catch (std::exception &e) {
(void)e;
throw;
} catch (...) {
throw;
}
auto result = get_results(visited_order, root, depth, graph);
results.insert(results.end(), result.begin(), result.end());
}
}

return results;
}

private:
template <typename T>
std::vector<pgr_mst_rt> get_results(
T order,
int64_t source,
int64_t max_depth,
const G &graph) {
std::vector<pgr_mst_rt> results;

std::vector<double> agg_cost(graph.num_vertices(), 0);
std::vector<int64_t> depth(graph.num_vertices(), 0);

for (const auto edge : order) {
auto u = graph.source(edge);
auto v = graph.target(edge);

agg_cost[v] = agg_cost[u] + graph[edge].cost;
depth[v] = depth[u] + 1;

if (max_depth >= depth[v]) {
results.push_back({
source,
depth[v],
graph[v].id,
graph[edge].id,
graph[edge].cost,
agg_cost[v]
});
}
}
return results;
}
};
} // namespace functions
} // namespace pgrouting

#endif // INCLUDE_DEPTHFIRSTSEARCH_PGR_DEPTHFIRSTSEARCH_HPP_
8 changes: 6 additions & 2 deletions pgtap/depthFirstSearch/depthFirstSearch-innerQuery.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
\i setup.sql

SELECT plan(54);
SELECT plan(1);

SELECT style_dijkstra('pgr_depthFirstSearch', ', 5)');
SELECT todo_start('Complete the inner query tests');

SELECT pass('Sample Test');

SELECT todo_end();

SELECT finish();
ROLLBACK;
78 changes: 2 additions & 76 deletions pgtap/depthFirstSearch/no_crash_test-depthFirstSearch.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
\i setup.sql

SELECT plan(86);
SELECT plan(2);

PREPARE edges AS
SELECT id, source, target, cost, reverse_cost FROM edge_table;
Expand All @@ -20,82 +20,8 @@ DECLARE
params TEXT[];
subs TEXT[];
BEGIN
PERFORM todo_start('Modify the no crash test');
-- depthFirstSearch
params = ARRAY[
'$$SELECT id, source, target, cost, reverse_cost FROM edge_table$$',
'5'
]::TEXT[];
subs = ARRAY[
'NULL',
'(SELECT id FROM edge_table_vertices_pgr WHERE id IN (-1))'
]::TEXT[];
PERFORM todo_start('Complete the no crash test');

RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

params[1] := '$$edges$$';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

subs[2] := 'NULL::INTEGER';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

-- depthFirstSearch with depth
params = ARRAY[
'$$SELECT id, source, target, cost, reverse_cost FROM edge_table$$',
'5',
'3'
]::TEXT[];
subs = ARRAY[
'NULL',
'(SELECT id FROM edge_table_vertices_pgr WHERE id IN (-1))',
'NULL::INTEGER'
]::TEXT[];

RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

params[1] := '$$edges$$';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

subs[2] := 'NULL::BIGINT';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

-- depthFirstSearch Multiple vertices
params = ARRAY[
'$$SELECT id, source, target, cost, reverse_cost FROM edge_table$$',
'ARRAY[5,3]'
]::TEXT[];
subs = ARRAY[
'NULL',
'(SELECT array_agg(id) FROM edge_table_vertices_pgr WHERE id IN (-1))'
]::TEXT[];

RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

params[1] := '$$edges$$';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

subs[2] := 'NULL::BIGINT';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

-- depthFirstSearch with depth Multiple vertices
params = ARRAY[
'$$SELECT id, source, target, cost, reverse_cost FROM edge_table$$',
'ARRAY[5,3]',
'3'
]::TEXT[];
subs = ARRAY[
'NULL',
'(SELECT array_agg(id) FROM edge_table_vertices_pgr WHERE id IN (-1))',
'NULL::INTEGER'
]::TEXT[];

RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

params[1] := '$$edges$$';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);

subs[2] := 'NULL::BIGINT[]';
RETURN query SELECT * FROM no_crash_test('pgr_depthFirstSearch', params, subs);
PERFORM todo_end();
END
$BODY$
Expand Down
64 changes: 58 additions & 6 deletions src/depthFirstSearch/depthFirstSearch_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#include "drivers/depthFirstSearch/depthFirstSearch_driver.h"

#include <sstream>
#include <deque>
#include <vector>
#include <algorithm>
#include <string>

#include "cpp_common/pgr_alloc.hpp"
#include "cpp_common/pgr_assert.h"

#include "spanningTree/pgr_prim.hpp"
#include "spanningTree/details.hpp"

#include "depthFirstSearch/pgr_depthFirstSearch.hpp"


/**********************************************************************/
/*
pgr_depthFirstSearch(
edges_sql TEXT,
root_vids ANYARRAY,
max_depth BIGINT DEFAULT 9223372036854775807,
directed BOOLEAN DEFAULT true
);
*/
/**********************************************************************/

template < class G >
std::vector<pgr_mst_rt>
pgr_depthFirstSearch(
G &graph,
std::vector < int64_t > roots,
int64_t max_depth,
std::string &log) {
std::sort(roots.begin(), roots.end());
roots.erase(
std::unique(roots.begin(), roots.end()),
roots.end());

pgrouting::functions::Pgr_depthFirstSearch< G > fn_depthFirstSearch;
auto results = fn_depthFirstSearch.depthFirstSearch(
graph, roots, max_depth);
log += fn_depthFirstSearch.get_log();
return results;
}

// TODO(krashish8): Use the data_edges, max_depth and directed parameter below.
void
do_pgr_depthFirstSearch(
pgr_edge_t *data_edges,
Expand Down Expand Up @@ -73,6 +100,31 @@ do_pgr_depthFirstSearch(

std::vector<pgr_mst_rt> results;

graphType gType = directed ? DIRECTED : UNDIRECTED;

std::string logstr;
if (directed) {
log << "Working with directed Graph\n";
pgrouting::DirectedGraph digraph(gType);
digraph.insert_edges(data_edges, total_edges);
results = pgr_depthFirstSearch(
digraph,
roots,
max_depth,
logstr);
} else {
log << "Working with Undirected Graph\n";
pgrouting::UndirectedGraph undigraph(gType);
undigraph.insert_edges(data_edges, total_edges);

results = pgr_depthFirstSearch(
undigraph,
roots,
max_depth,
logstr);
}
log << logstr;

#if 0
pgrouting::UndirectedGraph undigraph(UNDIRECTED);
undigraph.insert_min_edges_no_parallel(data_edges, total_edges);
Expand Down