Defend against Dijkstra returning reverse paths
This commit is contained in:
parent
ca8f702a1b
commit
ef478079e7
2 changed files with 43 additions and 19 deletions
|
|
@ -204,11 +204,13 @@ commodity_history_t::find_price(const commodity_t& source,
|
||||||
DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol());
|
DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol());
|
||||||
DEBUG("history.find", "tv commodity = " << get(namemap, tv)->symbol());
|
DEBUG("history.find", "tv commodity = " << get(namemap, tv)->symbol());
|
||||||
|
|
||||||
std::vector<vertex_descriptor> predecessors(num_vertices(fg));
|
std::size_t vector_len(num_vertices(fg));
|
||||||
std::vector<long> distances(num_vertices(fg));
|
std::vector<vertex_descriptor> predecessors(vector_len);
|
||||||
|
std::vector<long> distances(vector_len);
|
||||||
PredecessorMap predecessorMap(&predecessors[0]);
|
|
||||||
DistanceMap distanceMap(&distances[0]);
|
FIndexMap indexMap(get(vertex_index, fg));
|
||||||
|
FPredecessorMap predecessorMap(&predecessors[0], indexMap);
|
||||||
|
FDistanceMap distanceMap(&distances[0], indexMap);
|
||||||
|
|
||||||
dijkstra_shortest_paths(fg, /* start= */ sv,
|
dijkstra_shortest_paths(fg, /* start= */ sv,
|
||||||
predecessor_map(predecessorMap)
|
predecessor_map(predecessorMap)
|
||||||
|
|
@ -217,10 +219,15 @@ commodity_history_t::find_price(const commodity_t& source,
|
||||||
|
|
||||||
// Extract the shortest path and performance the calculations
|
// Extract the shortest path and performance the calculations
|
||||||
datetime_t least_recent = moment;
|
datetime_t least_recent = moment;
|
||||||
amount_t price;
|
amount_t price;
|
||||||
|
|
||||||
const commodity_t * last_target = ⌖
|
const commodity_t * last_target = ⌖
|
||||||
|
|
||||||
|
typedef tuple<const commodity_t *, const commodity_t *,
|
||||||
|
const price_point_t *> results_tuple;
|
||||||
|
std::vector<results_tuple> results;
|
||||||
|
bool results_reversed = false;
|
||||||
|
|
||||||
vertex_descriptor v = tv;
|
vertex_descriptor v = tv;
|
||||||
for (vertex_descriptor u = predecessorMap[v];
|
for (vertex_descriptor u = predecessorMap[v];
|
||||||
u != v;
|
u != v;
|
||||||
|
|
@ -229,8 +236,24 @@ commodity_history_t::find_price(const commodity_t& source,
|
||||||
std::pair<Graph::edge_descriptor, bool> edgePair = edge(u, v, fg);
|
std::pair<Graph::edge_descriptor, bool> edgePair = edge(u, v, fg);
|
||||||
Graph::edge_descriptor edge = edgePair.first;
|
Graph::edge_descriptor edge = edgePair.first;
|
||||||
|
|
||||||
|
const commodity_t * u_comm = get(namemap, u);
|
||||||
|
const commodity_t * v_comm = get(namemap, v);
|
||||||
const price_point_t& point(get(pricemap, edge));
|
const price_point_t& point(get(pricemap, edge));
|
||||||
|
|
||||||
|
if (v == tv && u_comm != last_target && v_comm != last_target)
|
||||||
|
results_reversed = true;
|
||||||
|
|
||||||
|
results.push_back(results_tuple(u_comm, v_comm, &point));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results_reversed)
|
||||||
|
std::reverse(results.begin(), results.end());
|
||||||
|
|
||||||
|
foreach (const results_tuple& edge, results) {
|
||||||
|
const commodity_t * u_comm = edge.get<0>();
|
||||||
|
const commodity_t * v_comm = edge.get<1>();
|
||||||
|
const price_point_t& point(*edge.get<2>());
|
||||||
|
|
||||||
bool first_run = false;
|
bool first_run = false;
|
||||||
if (price.is_null()) {
|
if (price.is_null()) {
|
||||||
least_recent = point.when;
|
least_recent = point.when;
|
||||||
|
|
@ -240,8 +263,8 @@ commodity_history_t::find_price(const commodity_t& source,
|
||||||
least_recent = point.when;
|
least_recent = point.when;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("history.find", "u commodity = " << get(namemap, u)->symbol());
|
DEBUG("history.find", "u commodity = " << u_comm->symbol());
|
||||||
DEBUG("history.find", "v commodity = " << get(namemap, v)->symbol());
|
DEBUG("history.find", "v commodity = " << v_comm->symbol());
|
||||||
DEBUG("history.find", "last target = " << last_target->symbol());
|
DEBUG("history.find", "last target = " << last_target->symbol());
|
||||||
|
|
||||||
// Determine which direction we are converting in
|
// Determine which direction we are converting in
|
||||||
|
|
@ -250,12 +273,12 @@ commodity_history_t::find_price(const commodity_t& source,
|
||||||
|
|
||||||
if (! first_run) {
|
if (! first_run) {
|
||||||
DEBUG("history.find", "price was = " << price.unrounded());
|
DEBUG("history.find", "price was = " << price.unrounded());
|
||||||
if (pprice.commodity() != *last_target)
|
if (pprice.commodity_ptr() != last_target)
|
||||||
price *= pprice.inverted();
|
price *= pprice.inverted();
|
||||||
else
|
else
|
||||||
price *= pprice;
|
price *= pprice;
|
||||||
}
|
}
|
||||||
else if (pprice.commodity() != *last_target) {
|
else if (pprice.commodity_ptr() != last_target) {
|
||||||
price = pprice.inverted();
|
price = pprice.inverted();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -263,10 +286,10 @@ commodity_history_t::find_price(const commodity_t& source,
|
||||||
}
|
}
|
||||||
DEBUG("history.find", "price is = " << price.unrounded());
|
DEBUG("history.find", "price is = " << price.unrounded());
|
||||||
|
|
||||||
if (*last_target == *get(namemap, v))
|
if (last_target == v_comm)
|
||||||
last_target = get(namemap, u);
|
last_target = u_comm;
|
||||||
else
|
else
|
||||||
last_target = get(namemap, v);
|
last_target = v_comm;
|
||||||
|
|
||||||
DEBUG("history.find", "last target now = " << last_target->symbol());
|
DEBUG("history.find", "last target now = " << last_target->symbol());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,13 +156,8 @@ public:
|
||||||
typedef graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
typedef graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||||
typedef graph_traits<Graph>::edge_descriptor edge_descriptor;
|
typedef graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||||
|
|
||||||
typedef property_map<Graph, vertex_index_t>::type IndexMap;
|
|
||||||
typedef property_map<Graph, vertex_name_t>::type NameMap;
|
typedef property_map<Graph, vertex_name_t>::type NameMap;
|
||||||
|
typedef property_map<Graph, vertex_index_t>::type IndexMap;
|
||||||
typedef iterator_property_map<vertex_descriptor*, IndexMap,
|
|
||||||
vertex_descriptor,
|
|
||||||
vertex_descriptor&> PredecessorMap;
|
|
||||||
typedef iterator_property_map<long*, IndexMap, long, long&> DistanceMap;
|
|
||||||
|
|
||||||
typedef property_map<Graph, edge_weight_t>::type EdgeWeightMap;
|
typedef property_map<Graph, edge_weight_t>::type EdgeWeightMap;
|
||||||
typedef property_map<Graph, edge_price_point_t>::type PricePointMap;
|
typedef property_map<Graph, edge_price_point_t>::type PricePointMap;
|
||||||
|
|
@ -175,7 +170,13 @@ public:
|
||||||
typedef filtered_graph<Graph, recent_edge_weight<EdgeWeightMap,
|
typedef filtered_graph<Graph, recent_edge_weight<EdgeWeightMap,
|
||||||
PricePointMap,
|
PricePointMap,
|
||||||
PriceRatioMap> > FGraph;
|
PriceRatioMap> > FGraph;
|
||||||
|
|
||||||
typedef property_map<FGraph, vertex_name_t>::type FNameMap;
|
typedef property_map<FGraph, vertex_name_t>::type FNameMap;
|
||||||
|
typedef property_map<FGraph, vertex_index_t>::type FIndexMap;
|
||||||
|
typedef iterator_property_map<vertex_descriptor*, FIndexMap,
|
||||||
|
vertex_descriptor,
|
||||||
|
vertex_descriptor&> FPredecessorMap;
|
||||||
|
typedef iterator_property_map<long*, FIndexMap, long, long&> FDistanceMap;
|
||||||
|
|
||||||
commodity_history_t()
|
commodity_history_t()
|
||||||
: indexmap(get(vertex_index, price_graph)),
|
: indexmap(get(vertex_index, price_graph)),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue