From 5491532aa9e12c84c130ae6a5a7bb897077a28f4 Mon Sep 17 00:00:00 2001 From: liumengxing Date: Sun, 19 Jun 2016 20:04:43 +0800 Subject: [PATCH] single-source shortest path examples --- Makefile | 9 +++++- examples/sssp.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++ tools/add_weights.cpp | 45 ++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 examples/sssp.cpp create mode 100644 tools/add_weights.cpp diff --git a/Makefile b/Makefile index ec7f128..3b81474 100644 --- a/Makefile +++ b/Makefile @@ -6,11 +6,18 @@ CXX?= g++ CXXFLAGS?= -O3 -Wall -std=c++11 -g -fopenmp -I$(ROOT_DIR) HEADERS= $(shell find . -name '*.hpp') -all: $(TARGETS) +all: $(TARGETS) bin/addweight bin/sssp + + +bin/addweight: tools/add_weights.cpp $(HEADERS) + $(CXX) $(CXXFLAGS) -o $@ $< $(SYSLIBS) bin/preprocess: tools/preprocess.cpp $(HEADERS) $(CXX) $(CXXFLAGS) -o $@ $< $(SYSLIBS) +bin/sssp: examples/sssp.cpp $(HEADERS) + $(CXX) $(CXXFLAGS) -o $@ $< $(SYSLIBS) + bin/bfs: examples/bfs.cpp $(HEADERS) $(CXX) $(CXXFLAGS) -o $@ $< $(SYSLIBS) diff --git a/examples/sssp.cpp b/examples/sssp.cpp new file mode 100644 index 0000000..4c25925 --- /dev/null +++ b/examples/sssp.cpp @@ -0,0 +1,68 @@ +/************************************************************************* + > File Name: sssp.cpp + > Author: Mengxing Liu + > Mail: liumengxing2010@qq.com + > Created Time: Sun Jun 19 19:23:36 2016 + ************************************************************************/ + +#include +#include "core/graph.hpp" + +using namespace std; +#define MAX_DEPTH 100000000 + +int main(int argc, char ** argv) { + if (argc<3) { + fprintf(stderr, "usage: bfs [path] [start vertex id] [memory budget in GB]\n"); + exit(-1); + } + std::string path = argv[1]; + VertexId start_vid = atoi(argv[2]); + long memory_bytes = (argc>=4)?atol(argv[3])*1024l*1024l*1024l:8l*1024l*1024l*1024l; + + Graph graph(path); + graph.set_memory_bytes(memory_bytes); + Bitmap * active_in = graph.alloc_bitmap(); + Bitmap * active_out = graph.alloc_bitmap(); + BigVector depth(graph.path+"/depth", graph.vertices); + graph.set_vertex_data_bytes( graph.vertices * sizeof(VertexId) ); + + active_out->clear(); + active_out->set_bit(start_vid); + depth.fill(MAX_DEPTH); + depth[start_vid] = 0; + VertexId active_vertices = 1; + + double start_time = get_time(); + int iteration = 0; + while (active_vertices!=0 && iteration< 100) { + iteration++; + printf("%7d: %d\n", iteration, active_vertices); + std::swap(active_in, active_out); + active_out->clear(); + graph.hint(depth); + + active_vertices = graph.stream_edges([&](Edge & e){ + int r = depth[e.target]; + int n = depth[e.source]+ e.weight; + if(n < r){ + if (cas(&depth[e.target], r, n)) { + active_out->set_bit(e.target); + return 1; + } + } + return 0; + }, active_in); + } + double end_time = get_time(); + + int discovered_vertices = graph.stream_vertices([&](VertexId i){ + return depth[i] < MAX_DEPTH; + }); + printf("discovered %d vertices from %d in %.2f seconds.\n", discovered_vertices, start_vid, end_time - start_time); + + for (int i=0; i<100; i++){ + printf("%d %d\n", i, depth[i]); + } + return 0; +} \ No newline at end of file diff --git a/tools/add_weights.cpp b/tools/add_weights.cpp new file mode 100644 index 0000000..9dd86d3 --- /dev/null +++ b/tools/add_weights.cpp @@ -0,0 +1,45 @@ +#include +#include + +typedef int VertexId; +typedef float Weight; // you may modify the weight type for different application requirements + +struct xorshift128plus { + unsigned long s[2]; + void init(int seed) { + s[0] = +seed; + s[1] = -seed; + } + unsigned long next() { + unsigned long x = s[0]; + unsigned long const y = s[1]; + s[0] = y; + x ^= x << 23; + x ^= x >> 17; + x ^= y ^ (y >> 26); + s[1] = x; + return x + y; + } +}; + +int main(int argc, char ** argv) { + if (argc < 3) { + fprintf(stderr, "usage: [executable] [input] [output]\n"); + exit(-1); + } + FILE * fin = fopen(argv[1], "rb"); + FILE * fout = fopen(argv[2], "wb"); + xorshift128plus rng; + rng.init(1); + while (true) { + VertexId src, dst; + if (fread(&src, sizeof(src), 1, fin)==0) break; + if (fread(&dst, sizeof(dst), 1, fin)==0) break; + fwrite(&src, sizeof(src), 1, fout); + fwrite(&dst, sizeof(dst), 1, fout); + Weight wgh = rng.next() % 10000 / 100; // generate a random weight within [0, 100) + fwrite(&wgh, sizeof(wgh), 1, fout); + } + fclose(fin); + fclose(fout); +}