UCR is an exact, output-sensitive algorithm for maintaining the
Each vertex keeps two
Every result produced by the experiments is verified to be identical to a from-scratch Batagelj–Zaveršnik (BZ) recomputation (0 mismatches).
- A C++17 compiler with OpenMP (e.g.
g++9 or newer) - Python 3 with
matplotlibandnumpy(only needed to regenerate the figures)
UCR/
├── src/ # header-only implementation
│ ├── graph.hpp # static graph (sorted-vector adjacency)
│ ├── graph_fast.hpp # cache-friendly adjacency variant
│ ├── partial_loader.hpp # streaming edge-list loader
│ ├── config.hpp # dataset registry + output directory
│ ├── bz.hpp # Batagelj–Zaveršnik static decomposition (ground truth)
│ ├── ucr_rs.hpp # UCR: r/s counters + localized peeling (main algorithm)
│ ├── ucr_rs_g.hpp # UCR templated over the graph type
│ ├── ucr_par.hpp # UCR with parallel cold-start + component-parallel insert
│ ├── par_core.hpp # parallel peeling (exact, used by the cold start)
│ ├── mcd.hpp, mcd_g.hpp # MCD/PCD traversal baseline
│ └── order_based_real.hpp # order-based baseline (Zhang et al., ICDE 2017)
├── exp/ # experiment drivers and correctness tests
├── plot/ # figure generation (Matplotlib)
├── results/ # experiment output (.txt) consumed by the plots
├── datasets/ # input graphs (you provide; see below)
├── build.sh # compile experiments and tests
└── README.md
Each input is a plain-text temporal edge list, one edge per line:
u v t # source destination integer-timestamp (whitespace-separated)
Lines beginning with # or % are ignored; self-loops are skipped. Put each file
under datasets/ with the names referenced in src/config.hpp:
Name in config.hpp |
Source |
|---|---|
sx-superuser |
SNAP (snap.stanford.edu/data) |
sx-stackoverflow |
SNAP |
wiki-talk-temporal |
SNAP |
cit-Patents |
SNAP |
soc-LiveJournal1 |
SNAP |
bitcoin-temporal |
public temporal-graph repositories |
temporal-reddit-reply |
public temporal-graph repositories |
social_media_100M |
synthetic (TGX temporal-graph toolkit) |
Any temporal edge list in the u v t format will work — edit config.hpp to add your own.
./build.sh # compile all experiments + correctness tests into ./bin/
./build.sh tests # only the correctness testsOr compile a single driver manually:
g++ -O2 -std=c++17 -fopenmp exp/exp_sliding_fast.cpp -o bin/exp_sliding_fastRun from the repository root; each driver writes a .txt into results/ and validates
its output against BZ at every step.
Experiment (./bin/…) |
Output file | Paper result |
|---|---|---|
exp_batch_fast |
results/exp_batch_fast.txt |
batch-update time (UCR vs MCD/PCD) |
exp_orderbased |
results/exp_orderbased.txt |
search region: UCR vs order-based/MCD |
exp_sliding_fast |
results/exp_sliding_fast.txt |
sliding-window speedup over BZ |
exp_parallel_cold |
results/exp_parallel.txt |
parallel cold-start speedup |
exp_boundary |
results/exp_boundary.txt |
crossover |
exp_case_study |
results/exp_case_study.txt |
interactive analyst workflow |
exp_vertexaccess |
results/exp_vertexaccess.txt |
vertices visited per batch |
Then regenerate the figures:
python3 plot/plot_results.py # main result figures
python3 plot/plot_running_example.py # the worked r/s example#include "src/graph.hpp"
#include "src/ucr_rs.hpp"
StaticGraph g;
g.init(num_vertices);
for (auto [u, v] : initial_edges) g.addEdge(u, v);
UCRrs ucr;
ucr.init(&g); // cold-start decomposition + r/s
ucr.removeEdges(expired); // a sliding-window step:
ucr.insertEdges(arrived); // delete then insert (as a batch)
const std::vector<int>& core = ucr.getCoreNumbers();For the parallel cold start and component-parallel insertion, use UCRPar from
src/ucr_par.hpp.
Correctness is verified two ways: (1) every experiment compares UCR's full core-number vector to a BZ recomputation at each batch/slide and reports any mismatch; (2) dedicated tests exhaustively check small graphs, long random insert/delete sequences, batch paths, and adversarial clique/bowtie cases:
./bin/test_ucr_rs # UCR vs BZ + r/s invariants (0 mismatches expected)
./bin/test_r1_adversarial # clique / Lemma-1 adversarial cases
./bin/test_order_based # order-based baseline vs BZMIT License.