mirror of https://gitee.com/bigwinds/arangodb
Further implementation of Shortest Path. The Shortest path is found in cpp conversion to JS not yet working
This commit is contained in:
parent
1a71382f1e
commit
6f81b0add1
|
@ -27,4 +27,11 @@
|
||||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef ARANGODB_V8_TRAVERSER_H
|
||||||
|
#define ARANGODB_V8_TRAVERSER_H 1
|
||||||
|
|
||||||
|
#include "Basics/Common.h"
|
||||||
|
|
||||||
|
void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "v8-vocindex.h"
|
#include "v8-vocindex.h"
|
||||||
#include "v8-collection.h"
|
#include "v8-collection.h"
|
||||||
#include "v8-voccursor.h"
|
#include "v8-voccursor.h"
|
||||||
|
#include "V8Traverser.h"
|
||||||
|
|
||||||
#include "Aql/Query.h"
|
#include "Aql/Query.h"
|
||||||
#include "Aql/QueryList.h"
|
#include "Aql/QueryList.h"
|
||||||
|
@ -1482,7 +1483,7 @@ static void JS_QueryIsKilledAql (const v8::FunctionCallbackInfo<v8::Value>& args
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
// TRI_RunDijkstraSearch(args);
|
TRI_RunDijkstraSearch(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,9 @@ void Traverser::insertNeighbor (ThreadInfo& info,
|
||||||
neighbor,
|
neighbor,
|
||||||
LookupInfo(weight, edge, predecessor)
|
LookupInfo(weight, edge, predecessor)
|
||||||
);
|
);
|
||||||
|
info.queue.insert(
|
||||||
|
QueueInfo(neighbor, weight)
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (it->second.done) {
|
if (it->second.done) {
|
||||||
|
@ -63,8 +66,8 @@ void Traverser::insertNeighbor (ThreadInfo& info,
|
||||||
};
|
};
|
||||||
|
|
||||||
void Traverser::lookupPeer (ThreadInfo& info,
|
void Traverser::lookupPeer (ThreadInfo& info,
|
||||||
VertexId neighbor,
|
VertexId& neighbor,
|
||||||
EdgeWeight weight) {
|
EdgeWeight& weight) {
|
||||||
std::lock_guard<std::mutex> guard(info.mutex);
|
std::lock_guard<std::mutex> guard(info.mutex);
|
||||||
auto it = info.lookup.find(neighbor);
|
auto it = info.lookup.find(neighbor);
|
||||||
if (it == info.lookup.end()) {
|
if (it == info.lookup.end()) {
|
||||||
|
@ -90,28 +93,32 @@ void Traverser::searchFromVertex (
|
||||||
ThreadInfo myInfo,
|
ThreadInfo myInfo,
|
||||||
ThreadInfo peerInfo,
|
ThreadInfo peerInfo,
|
||||||
VertexId start,
|
VertexId start,
|
||||||
Direction dir
|
ExpanderFunction expander
|
||||||
) {
|
) {
|
||||||
insertNeighbor(myInfo, start, "", "", 0);
|
insertNeighbor(myInfo, start, "", "", 0);
|
||||||
auto nextVertex = myInfo.queue.begin();
|
auto nextVertexIt = myInfo.queue.begin();
|
||||||
std::vector<Neighbor> neighbors;
|
std::vector<Neighbor> neighbors;
|
||||||
|
|
||||||
// Iterate while no bingo found and
|
// Iterate while no bingo found and
|
||||||
// there still is a vertex on the stack.
|
// there still is a vertex on the stack.
|
||||||
while (!bingo && nextVertex != myInfo.queue.end()) {
|
while (!bingo && nextVertexIt != myInfo.queue.end()) {
|
||||||
myInfo.queue.erase(nextVertex);
|
auto nextVertex = *nextVertexIt;
|
||||||
_neighborFunction(nextVertex->vertex, dir, neighbors);
|
myInfo.queue.erase(nextVertexIt);
|
||||||
|
expander(nextVertex.vertex, neighbors);
|
||||||
for (auto neighbor : neighbors) {
|
for (auto neighbor : neighbors) {
|
||||||
insertNeighbor(myInfo, neighbor.neighbor, nextVertex->vertex,
|
insertNeighbor(myInfo, neighbor.neighbor, nextVertex.vertex,
|
||||||
neighbor.edge, nextVertex->weight + neighbor.weight);
|
neighbor.edge, nextVertex.weight + neighbor.weight);
|
||||||
}
|
}
|
||||||
lookupPeer(peerInfo, nextVertex->vertex, nextVertex->weight);
|
lookupPeer(peerInfo, nextVertex.vertex, nextVertex.weight);
|
||||||
myInfo.mutex.lock();
|
myInfo.mutex.lock();
|
||||||
// Can move nextVertexLookup up?
|
// Can move nextVertexLookup up?
|
||||||
auto nextVertexLookup = myInfo.lookup.find(nextVertex->vertex);
|
auto nextVertexLookup = myInfo.lookup.find(nextVertex.vertex);
|
||||||
|
|
||||||
|
TRI_ASSERT(nextVertexLookup != myInfo.lookup.end());
|
||||||
|
|
||||||
nextVertexLookup->second.done = true;
|
nextVertexLookup->second.done = true;
|
||||||
myInfo.mutex.unlock();
|
myInfo.mutex.unlock();
|
||||||
nextVertex = myInfo.queue.begin();
|
nextVertexIt = myInfo.queue.begin();
|
||||||
}
|
}
|
||||||
// No possible path, can possibly terminate other thread
|
// No possible path, can possibly terminate other thread
|
||||||
};
|
};
|
||||||
|
@ -126,6 +133,7 @@ Traverser::Path* Traverser::ShortestPath (VertexId const& start,
|
||||||
std::vector<VertexId> r_vertices;
|
std::vector<VertexId> r_vertices;
|
||||||
std::vector<VertexId> r_edges;
|
std::vector<VertexId> r_edges;
|
||||||
highscore = 1e50;
|
highscore = 1e50;
|
||||||
|
bingo = false;
|
||||||
|
|
||||||
// Forward
|
// Forward
|
||||||
_forwardLookup.clear();
|
_forwardLookup.clear();
|
||||||
|
@ -137,13 +145,12 @@ Traverser::Path* Traverser::ShortestPath (VertexId const& start,
|
||||||
ThreadInfo backwardInfo(_backwardLookup, _backwardQueue, _backwardMutex);
|
ThreadInfo backwardInfo(_backwardLookup, _backwardQueue, _backwardMutex);
|
||||||
|
|
||||||
std::thread forwardSearcher(&Traverser::searchFromVertex,
|
std::thread forwardSearcher(&Traverser::searchFromVertex,
|
||||||
this, forwardInfo, backwardInfo, start, FORWARD);
|
this, forwardInfo, backwardInfo, start, forwardExpander);
|
||||||
std::thread backwardSearcher(&Traverser::searchFromVertex,
|
std::thread backwardSearcher(&Traverser::searchFromVertex,
|
||||||
this, backwardInfo, forwardInfo, target, BACKWARD);
|
this, backwardInfo, forwardInfo, target, backwardExpander);
|
||||||
forwardSearcher.join();
|
forwardSearcher.join();
|
||||||
backwardSearcher.join();
|
backwardSearcher.join();
|
||||||
|
|
||||||
// TODO Return result
|
|
||||||
if (!bingo) {
|
if (!bingo) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -152,20 +159,23 @@ Traverser::Path* Traverser::ShortestPath (VertexId const& start,
|
||||||
// FORWARD Go path back from intermediate -> start.
|
// FORWARD Go path back from intermediate -> start.
|
||||||
// Insert all vertices and edges at front of vector
|
// Insert all vertices and edges at front of vector
|
||||||
// Do NOT! insert the intermediate vertex
|
// Do NOT! insert the intermediate vertex
|
||||||
do {
|
TRI_ASSERT(pathLookup != _forwardLookup.end());
|
||||||
|
if (pathLookup->second.predecessor != "") {
|
||||||
|
r_edges.insert(r_edges.begin(), pathLookup->second.edge);
|
||||||
|
pathLookup = _forwardLookup.find(pathLookup->second.predecessor);
|
||||||
|
}
|
||||||
|
while (pathLookup->second.predecessor != "") {
|
||||||
r_edges.insert(r_edges.begin(), pathLookup->second.edge);
|
r_edges.insert(r_edges.begin(), pathLookup->second.edge);
|
||||||
r_vertices.insert(r_vertices.begin(), pathLookup->first);
|
r_vertices.insert(r_vertices.begin(), pathLookup->first);
|
||||||
pathLookup = _forwardLookup.find(pathLookup->second.predecessor);
|
pathLookup = _forwardLookup.find(pathLookup->second.predecessor);
|
||||||
} while (pathLookup->second.predecessor != "");
|
}
|
||||||
r_vertices.insert(r_vertices.begin(), pathLookup->first);
|
r_vertices.insert(r_vertices.begin(), pathLookup->first);
|
||||||
|
|
||||||
// BACKWARD Go path back from intermediate -> target.
|
// BACKWARD Go path back from intermediate -> target.
|
||||||
// Insert all vertices and edges at back of vector
|
// Insert all vertices and edges at back of vector
|
||||||
// Also insert the intermediate vertex
|
// Also insert the intermediate vertex
|
||||||
pathLookup = _backwardLookup.find(intermediate);
|
pathLookup = _backwardLookup.find(intermediate);
|
||||||
r_vertices.push_back(intermediate);
|
TRI_ASSERT(pathLookup != _backwardLookup.end());
|
||||||
r_edges.push_back(pathLookup->second.edge);
|
|
||||||
pathLookup = _backwardLookup.find(pathLookup->second.predecessor);
|
|
||||||
while (pathLookup->second.predecessor != "") {
|
while (pathLookup->second.predecessor != "") {
|
||||||
r_vertices.push_back(pathLookup->first);
|
r_vertices.push_back(pathLookup->first);
|
||||||
r_edges.push_back(pathLookup->second.edge);
|
r_edges.push_back(pathLookup->second.edge);
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace triagens {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
typedef enum {FORWARD, BACKWARD} Direction;
|
typedef enum {FORWARD, BACKWARD} Direction;
|
||||||
|
|
||||||
typedef std::function<void(VertexId source, Direction dir, std::vector<Neighbor>& result)>
|
typedef std::function<void(VertexId source, std::vector<Neighbor>& result)>
|
||||||
ExpanderFunction;
|
ExpanderFunction;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -103,13 +103,22 @@ namespace triagens {
|
||||||
/// @brief create the Traverser
|
/// @brief create the Traverser
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Traverser (ExpanderFunction const& n) : _neighborFunction(n) {
|
Traverser (
|
||||||
|
ExpanderFunction const& forwardExpander,
|
||||||
|
ExpanderFunction const& backwardExpander
|
||||||
|
) : highscore(1e50),
|
||||||
|
bingo(false),
|
||||||
|
intermediate(""),
|
||||||
|
forwardExpander(forwardExpander),
|
||||||
|
backwardExpander(backwardExpander) {
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief destructor
|
/// @brief destructor
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
~Traverser ();
|
~Traverser () {
|
||||||
|
// TODO: Implement!!
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- public methods
|
// --SECTION-- public methods
|
||||||
|
@ -198,9 +207,9 @@ namespace triagens {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ExpanderFunction const& _neighborFunction;
|
ExpanderFunction const& forwardExpander;
|
||||||
|
ExpanderFunction const& backwardExpander;
|
||||||
|
|
||||||
// Are they needed anyway??
|
|
||||||
// ShortestPath will create these variables
|
// ShortestPath will create these variables
|
||||||
std::unordered_map<VertexId, LookupInfo> _forwardLookup;
|
std::unordered_map<VertexId, LookupInfo> _forwardLookup;
|
||||||
std::set<QueueInfo, std::less<QueueInfo>> _forwardQueue;
|
std::set<QueueInfo, std::less<QueueInfo>> _forwardQueue;
|
||||||
|
@ -219,13 +228,13 @@ namespace triagens {
|
||||||
);
|
);
|
||||||
|
|
||||||
void lookupPeer ( ThreadInfo& info,
|
void lookupPeer ( ThreadInfo& info,
|
||||||
VertexId neighbor,
|
VertexId& neighbor,
|
||||||
EdgeWeight weight
|
EdgeWeight& weight
|
||||||
);
|
);
|
||||||
void searchFromVertex ( ThreadInfo myInfo,
|
void searchFromVertex ( ThreadInfo myInfo,
|
||||||
ThreadInfo peerInfo,
|
ThreadInfo peerInfo,
|
||||||
VertexId start,
|
VertexId start,
|
||||||
Direction dir
|
ExpanderFunction expander
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue