@@ -108,7 +108,7 @@ inline bool Graphzero::isNeighbor(size_t u, size_t v){
108108// return next step in node2vec algo
109109inline size_t Graphzero::node2vec_step (size_t curr, size_t prev, float p, float q, const AliasTable& table){
110110 // Rejection sampling
111- float maxBias = std::max ({1 .0f ,1 .0f /p,1 .0f /q});
111+ float maxBias = ( std::max) ({1 .0f ,1 .0f /p,1 .0f /q}); // for windows max
112112
113113 while (true )
114114 {
@@ -162,16 +162,20 @@ inline std::vector<size_t> Graphzero::randomWalk(size_t start_node, size_t lengt
162162
163163// keep p = 1.0f and q = 1.0f for default values.
164164inline std::vector<size_t > Graphzero::batchRandomWalk (const std::vector<size_t >& startNodes, size_t walkLength, float p, float q){
165- std::vector<size_t > results;
166- results.reserve (walkLength*startNodes.size ());
165+ std::vector<size_t > results (walkLength*startNodes.size ());
167166
168167 // set only for random walks
169168 storage->set_access_pattern (true );
170169
171170 #pragma omp parallel for
172- for (size_t startNode: startNodes){
173- std::vector<size_t > walk = randomWalk (startNode,walkLength,p,q);
174- results.insert (results.end (),walk.begin (),walk.end ()); // extend the results
171+ for (signed long long i = 0 ; i < startNodes.size (); i++){
172+ std::vector<size_t > walk = randomWalk (startNodes[i],walkLength,p,q);
173+
174+ // thread safe
175+ size_t offset = i*walkLength;
176+ for (int j = 0 ; j < walk.size (); j++){
177+ results[j+offset] = walk[j];
178+ }
175179 }
176180
177181 // reset
@@ -180,20 +184,57 @@ inline std::vector<size_t> Graphzero::batchRandomWalk(const std::vector<size_t>&
180184}
181185
182186inline std::vector<size_t > Graphzero::batchRandomUniformWalk (const std::vector<size_t >& startNodes, size_t walkLength){
183- std::vector<size_t > results;
184- results.reserve (walkLength*startNodes.size ());
187+ std::vector<size_t > results (walkLength*startNodes.size ());
185188
186189 // set only for random walks
187190 storage->set_access_pattern (true );
188191
189192 #pragma omp parallel for
190- for (size_t startNode: startNodes){
191- std::vector<size_t > walk = ReservoirSampling (startNode,walkLength);
192- results.insert (results.end (),walk.begin (),walk.end ()); // extend the results
193+ for (signed long long i = 0 ; i < startNodes.size (); i++){
194+ // walking here
195+ size_t offset = i*walkLength;
196+ size_t curr = startNodes[i], next;
197+ results[offset] = curr;
198+ for (size_t j = 1 ; j < walkLength; ++j){
199+ auto edges = storage->get_edges (curr);
200+
201+ if (edges.size () == 0 ){
202+ results[offset+j] = curr;
203+ continue ;
204+ }
205+
206+ next = edges[RNG.rand_int (0 ,edges.size ()-1 )];
207+ results[offset + j] = next;
208+ curr = next;
209+ }
193210 }
194211
195212 // reset
196213 storage->set_access_pattern (false );
197214 return results;
198215}
216+
217+ // not walk but sampling
218+ // inline std::vector<size_t> Graphzero::batchRandomUniformWalk(const std::vector<size_t>& startNodes, size_t walkLength){
219+ // std::vector<size_t> results;
220+ // results.reserve(walkLength*startNodes.size());
221+
222+ // // set only for random walks
223+ // storage->set_access_pattern(true);
224+
225+ // #pragma omp parallel for
226+ // for(size_t i = 0; i < num_nodes; i++){
227+ // std::vector<size_t> walk = ReservoirSampling(startNode,walkLength);
228+
229+ // // thread safe
230+ // size_t offset = i*walkLength;
231+ // for(int j = 0; j < walk.size(); j++){
232+ // results[j+offset] = walk[j];
233+ // }
234+ // }
235+
236+ // // reset
237+ // storage->set_access_pattern(false);
238+ // return results;
239+ // }
199240#endif
0 commit comments