Я пытаюсь реализовать алгоритм BFS с помощью GraphLab. В моей структуре vertex_data я использую вектор для хранения пути, который был пройден до сих пор.
struct vertex_data {
std::vector<int> current_path;
bool visited;
int destination;
vertex_data() {
destination = -1;
visited = false;
}
}
Затем в функции apply () я пытаюсь вставить текущий идентификатор вершины в current_path этой конкретной вершины:
class bfs: public graphlab::ivertex_program<graph_type, graphlab::empty,
vertex_data> {
private:
vertex_data msg;
public:void apply(icontext_type& context, vertex_type& vertex, const gather_type& gather_result) {
int vid = vertex.id();
vertex.data().destination = msg.destination;
vertex.data().visited = true;
msg.current_path.push_back(vid);
vertex.data().current_path.push_back(vid);
}
}
Также определение data () в документации:
vertex_data_type & data ()
Returns a reference to the data on the vertex.
GraphLab заботится о переносе объекта vertex_data как vertex_data_type.
Когда я запускаю его, я получаю ошибку сегмента в функции push_back () для некоторых вершин.
Я проверил VID, и это всегда целое число с фактическим значением.
Запустив vertex.data (). Current_path.size (), я получаю 0.
Я пробовал несколько подходов, таких как создание локального вектора и замена в vertex.data () и изменение размера перед нажатием id. В первом случае я получаю ошибку сегмента при попытке заменить, а во втором случае изменение размера выполняется без проблем, но нажатие продолжает давать мне ошибку сегмента.
У вас есть идеи, в чем может быть проблема?
Спасибо
Классы в Graphlab должны быть сериализуемыми. Поэтому вам нужно написать свою собственную функцию загрузки и сохранения, если переменные не являются Plain Old Data (POD).
В вашем случае это должно быть так (обратите внимание, что список загрузки и сохранения должен быть в одном порядке):
struct vertex_data {
std::vector<int> current_path;
bool visited;
int destination;
vertex_data() {
destination = -1;
visited = false;
}
void save(graphlab::oarchive& oarc) const {
oarc << current_path << visited << destination;
}
void load(graphlab::iarchive& iarc) {
iarc >> current_path >> visited >> destination;
}
}