.FIX T68
.FIX T67 .FIX T65 Modifed astar main for benchmark. Experimented with map of best visited and confirmed: -it is faster by 25% -observed that it founds best resoult -loses some non best resoults Added convinent method at() to get property from RecordAccessor. Method requires value_ref() method on property object.
This commit is contained in:
parent
df0bf6fa5f
commit
530be96b36
@ -8,20 +8,21 @@ public:
|
||||
static constexpr Flags type = Flags::Bool;
|
||||
|
||||
Bool(bool value);
|
||||
Bool(const Bool& other) = default;
|
||||
Bool(const Bool &other) = default;
|
||||
|
||||
bool value() const;
|
||||
|
||||
bool const &value_ref() const;
|
||||
|
||||
explicit operator bool() const;
|
||||
|
||||
bool operator==(const Property& other) const override;
|
||||
bool operator==(const Property &other) const override;
|
||||
|
||||
bool operator==(const Bool& other) const;
|
||||
bool operator==(const Bool &other) const;
|
||||
|
||||
bool operator==(bool v) const;
|
||||
|
||||
std::ostream& print(std::ostream& stream) const override;
|
||||
std::ostream &print(std::ostream &stream) const override;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const Bool& prop);
|
||||
friend std::ostream &operator<<(std::ostream &stream, const Bool &prop);
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@ struct Double : public Floating<Double>
|
||||
|
||||
Double(double value) : Floating(Flags::Double), value(value) {}
|
||||
|
||||
double const &value_ref() const { return value; }
|
||||
|
||||
double value;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "storage/model/properties/floating.hpp"
|
||||
#include "storage/model/properties/double.hpp"
|
||||
#include "storage/model/properties/floating.hpp"
|
||||
|
||||
class Float : public Floating<Float>
|
||||
{
|
||||
@ -10,10 +10,9 @@ public:
|
||||
|
||||
Float(float value) : Floating(Flags::Float), value(value) {}
|
||||
|
||||
operator Double() const
|
||||
{
|
||||
return Double(value);
|
||||
}
|
||||
operator Double() const { return Double(value); }
|
||||
|
||||
float const &value_ref() const { return value; }
|
||||
|
||||
float value;
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "storage/model/properties/integral.hpp"
|
||||
#include "storage/model/properties/int64.hpp"
|
||||
#include "storage/model/properties/integral.hpp"
|
||||
|
||||
class Int32 : public Integral<Int32>
|
||||
{
|
||||
@ -10,11 +10,9 @@ public:
|
||||
|
||||
Int32(int32_t value) : Integral(Flags::Int32), value(value) {}
|
||||
|
||||
operator Int64() const
|
||||
{
|
||||
return Int64(value);
|
||||
}
|
||||
operator Int64() const { return Int64(value); }
|
||||
|
||||
int32_t const &value_ref() const { return value; }
|
||||
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,7 @@ public:
|
||||
|
||||
Int64(int64_t value) : Integral(Flags::Int64), value(value) {}
|
||||
|
||||
int64_t const &value_ref() const { return value; }
|
||||
|
||||
int64_t value;
|
||||
};
|
||||
|
||||
|
@ -7,23 +7,25 @@ class String : public Property
|
||||
public:
|
||||
static constexpr Flags type = Flags::String;
|
||||
|
||||
String(const String&) = default;
|
||||
String(String&&) = default;
|
||||
String(const String &) = default;
|
||||
String(String &&) = default;
|
||||
|
||||
String(const std::string& value);
|
||||
String(std::string&& value);
|
||||
String(const std::string &value);
|
||||
String(std::string &&value);
|
||||
|
||||
operator const std::string&() const;
|
||||
operator const std::string &() const;
|
||||
|
||||
bool operator==(const Property& other) const override;
|
||||
bool operator==(const Property &other) const override;
|
||||
|
||||
bool operator==(const String& other) const;
|
||||
bool operator==(const String &other) const;
|
||||
|
||||
bool operator==(const std::string& other) const;
|
||||
bool operator==(const std::string &other) const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const String& prop);
|
||||
friend std::ostream &operator<<(std::ostream &stream, const String &prop);
|
||||
|
||||
std::ostream& print(std::ostream& stream) const override;
|
||||
std::ostream &print(std::ostream &stream) const override;
|
||||
|
||||
std::string const &value_ref() const { return value; }
|
||||
|
||||
std::string value;
|
||||
};
|
||||
|
@ -75,6 +75,12 @@ public:
|
||||
|
||||
Properties &properties() const { return record->data.props; }
|
||||
|
||||
template <class V>
|
||||
auto at(const std::string &key) const
|
||||
{
|
||||
return properties().at(key).template as<V>().value_ref();
|
||||
}
|
||||
|
||||
explicit operator bool() const { return record != nullptr; }
|
||||
|
||||
T const *operator->() const { return record; }
|
||||
|
115
poc/astar.cpp
115
poc/astar.cpp
@ -17,7 +17,7 @@
|
||||
using namespace std;
|
||||
typedef Vertex::Accessor VertexAccessor;
|
||||
void load_graph_dummy(Db &db);
|
||||
void load_csv(Db &db, char *file_path, char *edge_file_path);
|
||||
int load_csv(Db &db, char *file_path, char *edge_file_path);
|
||||
|
||||
class Node
|
||||
{
|
||||
@ -32,6 +32,25 @@ public:
|
||||
: cost(cost), vacc(vacc), parent(parent), depth(parent->depth + 1)
|
||||
{
|
||||
}
|
||||
|
||||
double sum_vertex_score()
|
||||
{
|
||||
auto now = this;
|
||||
double sum = 0;
|
||||
do {
|
||||
sum += now->vacc.at<Double>("score");
|
||||
now = now->parent;
|
||||
} while (now != nullptr);
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
class Score
|
||||
{
|
||||
public:
|
||||
Score() : value(std::numeric_limits<double>::max()) {}
|
||||
Score(double v) : value(v) {}
|
||||
double value;
|
||||
};
|
||||
|
||||
// class Iterator : public Crtp<Iterator>
|
||||
@ -74,9 +93,12 @@ public:
|
||||
// Node *head;
|
||||
// };
|
||||
|
||||
void found_result(Node *bef)
|
||||
void found_result(Node *res)
|
||||
{
|
||||
std::cout << "{score: " << bef->cost << endl;
|
||||
double sum = res->sum_vertex_score();
|
||||
|
||||
std::cout << "{score: " << sum << endl;
|
||||
auto bef = res;
|
||||
while (bef != nullptr) {
|
||||
std::cout << " " << *(bef->vacc.operator->()) << endl;
|
||||
bef = bef->parent;
|
||||
@ -86,7 +108,7 @@ void found_result(Node *bef)
|
||||
double calc_heuristic_cost_dummy(Edge::Accessor &edge, Vertex::Accessor &vertex)
|
||||
{
|
||||
assert(!vertex.empty());
|
||||
return 1 - vertex->data.props.at("score").as<Double>().value;
|
||||
return 1 - vertex.at<Double>("score");
|
||||
}
|
||||
|
||||
typedef bool (*EdgeFilter)(DbAccessor &t, Edge::Accessor &, Node *before);
|
||||
@ -144,14 +166,16 @@ bool vertex_filter_contained(DbAccessor &t, Vertex::Accessor &v, Node *before)
|
||||
// Vertex filter ima max_depth funkcija te edge filter ima max_depth funkcija.
|
||||
// Jedan za svaku dubinu.
|
||||
// Filtri vracaju true ako element zadovoljava uvjete.
|
||||
void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
||||
auto a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
||||
VertexFilter v_filter[],
|
||||
double (*calc_heuristic_cost)(Edge::Accessor &edge,
|
||||
Vertex::Accessor &vertex),
|
||||
int limit)
|
||||
{
|
||||
DbAccessor t(db);
|
||||
auto best_found = new std::map<Id, Score>[max_depth];
|
||||
|
||||
std::vector<Node *> best;
|
||||
auto cmp = [](Node *left, Node *right) { return left->cost > right->cost; };
|
||||
std::priority_queue<Node *, std::vector<Node *>, decltype(cmp)> queue(cmp);
|
||||
|
||||
@ -169,14 +193,22 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
||||
// }
|
||||
|
||||
if (max_depth <= now->depth) {
|
||||
found_result(now);
|
||||
best.push_back(now);
|
||||
count++;
|
||||
if (count >= limit) {
|
||||
return;
|
||||
return best;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// { // FOUND FILTER
|
||||
// Score &bef = best_found[now->depth][now->vacc.id()];
|
||||
// if (bef.value <= now->cost) {
|
||||
// continue;
|
||||
// }
|
||||
// bef.value = now->cost;
|
||||
// }
|
||||
|
||||
iter::for_all(now->vacc.out(), [&](auto edge) {
|
||||
if (e_filter[now->depth](t, edge, now)) {
|
||||
VertexAccessor va = edge.to();
|
||||
@ -188,10 +220,11 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
||||
}
|
||||
});
|
||||
} while (!queue.empty());
|
||||
std::cout << "Found: " << count << " resoults\n";
|
||||
// std::cout << "Found: " << count << " resoults\n";
|
||||
// TODO: GUBI SE MEMORIJA JER SE NODOVI NEBRISU
|
||||
|
||||
t.commit();
|
||||
return best;
|
||||
}
|
||||
|
||||
// class Data
|
||||
@ -207,23 +240,66 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
|
||||
// const int &get_key() { return key; }
|
||||
// };
|
||||
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
std::cout << "Not enough input values\n";
|
||||
return 0;
|
||||
} else if (argc > 4) {
|
||||
std::cout << "To much input values\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
Db db;
|
||||
load_csv(db, "neo4j_nodes_export_2000.csv", "neo4j_edges_export_2000.csv");
|
||||
//
|
||||
// load_graph_dummy(db);
|
||||
//
|
||||
auto vertex_no = load_csv(db, argv[argc - 2], argv[argc - 1]);
|
||||
|
||||
EdgeFilter e_filters[] = {&edge_filter_dummy, &edge_filter_dummy,
|
||||
&edge_filter_dummy, &edge_filter_dummy};
|
||||
VertexFilter f_filters[] = {
|
||||
&vertex_filter_contained, &vertex_filter_contained,
|
||||
&vertex_filter_contained, &vertex_filter_contained};
|
||||
auto begin = clock();
|
||||
a_star(db, 0, 3, e_filters, f_filters, &calc_heuristic_cost_dummy, 10);
|
||||
clock_t end = clock();
|
||||
double elapsed_ms = (double(end - begin) / CLOCKS_PER_SEC) * 1000;
|
||||
std::cout << "A-star: " << elapsed_ms << " [ms]\n";
|
||||
|
||||
// CONF
|
||||
std::srand(time(0));
|
||||
auto best_n = 10;
|
||||
auto bench_n = 1000;
|
||||
auto best_print_n = 10;
|
||||
bool pick_best_found = argc > 3 ? true : false;
|
||||
|
||||
double sum = 0;
|
||||
std::vector<Node *> best;
|
||||
for (int i = 0; i < bench_n; i++) {
|
||||
auto start_vertex_index = std::rand() % vertex_no;
|
||||
|
||||
auto begin = clock();
|
||||
auto found = a_star(db, start_vertex_index, 3, e_filters, f_filters,
|
||||
&calc_heuristic_cost_dummy, best_n);
|
||||
clock_t end = clock();
|
||||
|
||||
double elapsed_ms = (double(end - begin) / CLOCKS_PER_SEC) * 1000;
|
||||
sum += elapsed_ms;
|
||||
|
||||
if ((best.size() < best_print_n && found.size() > best.size()) ||
|
||||
(pick_best_found && found.size() > 0 &&
|
||||
found.front()->sum_vertex_score() >
|
||||
best.front()->sum_vertex_score())) {
|
||||
best = found;
|
||||
}
|
||||
|
||||
// Just to be safe
|
||||
if (i + 1 == bench_n && best.size() == 0) {
|
||||
bench_n++;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\nSearch for best " << best_n
|
||||
<< " results has runing time of:\n avg: " << sum / bench_n
|
||||
<< " [ms]\n";
|
||||
std::cout << "\nExample of best result:\n";
|
||||
for (int i = 0; i < best_print_n && best.size() > 0; i++) {
|
||||
found_result(best.front());
|
||||
best.erase(best.begin());
|
||||
}
|
||||
|
||||
// RhHashMultiMap benchmark
|
||||
// const int n_pow2 = 20;
|
||||
@ -262,7 +338,7 @@ vector<string> split(const string &s, char delim)
|
||||
return elems;
|
||||
}
|
||||
|
||||
void load_csv(Db &db, char *file_path, char *edge_file_path)
|
||||
int load_csv(Db &db, char *file_path, char *edge_file_path)
|
||||
{
|
||||
std::fstream file(file_path);
|
||||
std::fstream e_file(edge_file_path);
|
||||
@ -341,6 +417,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
|
||||
<< endl;
|
||||
|
||||
t.commit();
|
||||
return v_count;
|
||||
}
|
||||
|
||||
void load_graph_dummy(Db &db)
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "storage/model/properties/bool.hpp"
|
||||
|
||||
const bool TRUE = true;
|
||||
const bool FALSE = false;
|
||||
|
||||
Bool::Bool(bool value) : Property(value ? Flags::True : Flags::False) {}
|
||||
|
||||
bool Bool::value() const
|
||||
@ -15,32 +18,25 @@ bool Bool::value() const
|
||||
return (underlying_cast(flags) - underlying_cast(Flags::True)) == 0;
|
||||
}
|
||||
|
||||
Bool::operator bool() const
|
||||
{
|
||||
return value();
|
||||
}
|
||||
bool const &Bool::value_ref() const { return value() ? TRUE : FALSE; }
|
||||
|
||||
bool Bool::operator==(const Property& other) const
|
||||
Bool::operator bool() const { return value(); }
|
||||
|
||||
bool Bool::operator==(const Property &other) const
|
||||
{
|
||||
return other.is<Bool>() && operator==(other.as<Bool>());
|
||||
}
|
||||
|
||||
bool Bool::operator==(const Bool& other) const
|
||||
{
|
||||
return other.flags == flags;
|
||||
}
|
||||
bool Bool::operator==(const Bool &other) const { return other.flags == flags; }
|
||||
|
||||
bool Bool::operator==(bool v) const
|
||||
{
|
||||
return value() == v;
|
||||
}
|
||||
bool Bool::operator==(bool v) const { return value() == v; }
|
||||
|
||||
std::ostream& Bool::print(std::ostream& stream) const
|
||||
std::ostream &Bool::print(std::ostream &stream) const
|
||||
{
|
||||
return operator<<(stream, *this);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const Bool& prop)
|
||||
std::ostream &operator<<(std::ostream &stream, const Bool &prop)
|
||||
{
|
||||
return stream << prop.value();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user