#ifndef _LEVEL_GRAPH_HPP #define _LEVEL_GRAPH_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class LevelGraph; class Node{ public: Node(LevelGraph& graph, bool chosen, size_t level, int index, std::vector& next_level_nodes) : _graph(graph), _chosen(chosen), _level(level), _idx(index) { _out_edges = std::move(next_level_nodes); } //void mark(){ // _visited = true; //} inline void mark(); void unmark(){ _visited = false; } bool check_status() { return _visited; } void print_node(){ std::cout << "Node: " << _idx << " out_edges: "; for(const auto& out_edge: _out_edges){ std::cout << out_edge << "\t"; } std::cout << "\n" << "in_edges"; for(const auto& in_edge: _in_edges){ std::cout << "(" << in_edge.first << "," << in_edge.second << ")\t"; } std::cout << "Status:" << _visited << std::endl; std::cout << std::endl; } int index() const { return _idx; } int level() const { return _level; } int* edge_ptr(int edge_idx) { return &_out_edges[edge_idx]; } std::vector> _in_edges; std::vector _out_edges; private: LevelGraph& _graph; bool _chosen {false}; size_t _level; int _idx; bool _visited {false}; }; class LevelGraph { public: LevelGraph(size_t length, size_t level, float threshold = 0.0f){ _level_num = level; _length_num = length; std::mt19937 g(0); // fixed the seed for graph generator std::srand(0); for(size_t l=0; l cur_nodes; std::vector next_level_nodes; for(size_t i=0; i= length){ end = length; re_shuffle = true; } else{ end = start + edge_num; } //std::cout << "Level\t" << l << "\tidx\t" << i << "\tedge_num\t" << edge_num << "\tstart\t" << start << "\tend\t" << end << std::endl; std::vector edges(next_level_nodes.begin()+start, next_level_nodes.begin()+end); //choose a node to do some work float rv = std::rand()/(RAND_MAX + 1u); bool chosen = false; if(rv < threshold){ chosen = true; } cur_nodes.emplace_back(*this, chosen, l, i, edges); //create nodes if(re_shuffle){ std::shuffle(next_level_nodes.begin(), next_level_nodes.end(), g); start = 0; re_shuffle = false; } else{ start = end; } } _graph.push_back(std::move(cur_nodes)); } for(size_t l=0; level > 0 && l idx_list; std::queue idx_queue; int dst_idx = dst.level()*_length_num + dst.index(); idx_queue.push(dst_idx); idx_list.insert(dst_idx); while(!idx_queue.empty()){ int child = idx_queue.front(); int child_level = child / _length_num; int child_index = child % _length_num; //std::cout << "Node level: " << child_level << " idx: " << child_index << std::endl; idx_queue.pop(); const Node& n = _graph[child_level][child_index]; for(size_t i=0; child_level>0 && i> _graph; }; inline void Node::mark(){ _visited = true; if(_chosen == true){ _graph.BFS(*this); } } std::chrono::microseconds measure_time_taskflow(LevelGraph&, unsigned); std::chrono::microseconds measure_time_omp(LevelGraph&, unsigned); std::chrono::microseconds measure_time_tbb(LevelGraph&, unsigned); #endif