Skip to content

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

42 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The University of St Andrews

Understanding and Evaluating Variants of the McSplit Algorithm for the Maximum Common Subgraph Problem

Tara Relan (250016623)

Supervisor: Dr. Ruth Hoffmann

August 11th 2026

Contents

Acknowledgements

This repository contains reimplementations of the following algorithms:

All implementations were re-written in C++ based on the published papers and validated against the authors' reference binaries. Reference binaries are included in reference/ for validation purposes only and remain the property of their respective authors.

Reference Implementations

Original author code used for validation (Section 4.1 of the dissertation) was sourced as follows:

Algorithm Source
McSplit ijcai2017-partitioning-common-subgraph
McSplit+RL McSplit-RL
McSplit+LL McSplit-LL
McSplit+DAL SIGMOD25-MCSS (./McSplitDAL subfolder)
McSplit+DSB mcsplit-dsb
RRSplit SIGMOD25-MCSS (./RRSplit subfolder)
SymSplit symsplit

Your local reference/ folder should be laid out as:

reference/
├── mcsplit/
│   └── mcsp      # compiled reference binary
├── mcsplit-rl/
│   └── mcsp+RL
├── mcsplit-ll/
│   └── mcsp+ll
├── mcsplit-dal/
│   └── mcspDAL
├── mcsplit-dsb/
│   └── bin/
│       └── run.o
├── rrsplit/
│   └── mcsp
└── symsplit/
    └── bin/
        └── run.o

These paths match what hpc/run_instance.sh calls in --with-ref mode - if a reference binary isn't at the expected path, that algorithm's ref-mode comparison will silently return empty reference fields rather than erroring, so it's worth checking each path exists after building.

User Manual

This manual describes how to build and run the unified MCS solver framework. The framework implements seven algorithms (McSplit, McSplit+RL, McSplit+LL, McSplit+DAL, McSplit+DSB, RRSplit, SymSplit) and their ablation variants within a single binary.


Requirements

  • g++ 11.4.1 or later with C++17 support
  • The MIVIA/BI/LV instance set, unzipped into instances/
  • GNU Make
  • POSIX-compatible shell (bash)
  • Boost library (for HPC submission scripts only)

Building

From the project root:

make -C solvers

This produces solvers/bin/mcsp. To rebuild from scratch:

rm -f solvers/bin/mcsp
make -C solvers

Running a Single Instance

./solvers/bin/mcsp -A <algorithm> -t <timeout> [-l] -q <graph1> <graph2>

Options

Flag Long form Description
-q --quiet Suppress per-instance output; print only the solution size
-d --dimacs Read graphs in DIMACS format (default: MIVIA binary)
-l --lad Read graphs in LAD format (default: MIVIA binary)
-i --directed Treat graphs as directed
-a --labelled Use both vertex and edge labels
-x --vertex-labelled Use vertex labels only (no edge labels)
-t <seconds> --timeout Abort search after this many seconds (0 = no limit)
-A <algo> --algorithm Algorithm to run (see algorithm table below)

Available Algorithms

Flag Algorithm
mcsplit McSplit (baseline)
down McSplit-down (top-down / "big-first" search)
rl McSplit+RL
rl_pair McSplit+RL with per-pair (v,w) scoring instead of per-vertex
rl_rate McSplit+RL with rate-normalised reward
rl_down McSplit+RL branching combined with McSplit-down's search strategy
ll McSplit+LL (full: LSM + LUM)
ll_lsm McSplit+LL with LSM only
ll_lum McSplit+LL with LUM only
dal McSplit+DAL (hybrid alternating policy)
dal_rl McSplit+DAL with RL policy locked
dal_dal McSplit+DAL with DAL policy locked
dsb McSplit+DSB (RL-gated bound)
dsb_always McSplit+DSB with bound always on
dsb_never McSplit+DSB with bound always off
rrsplit RRSplit (all three reductions)
rrsplit_noveq RRSplit without vertex-equivalence reduction
rrsplit_nomax RRSplit without maximality reduction
rrsplit_nobound RRSplit without tighter bound
symsplit SymSplit (variable + value symmetry)
symsplit_varonly SymSplit with variable symmetry only
symsplit_valonly SymSplit with value symmetry only

Examples

MIVIA binary format:

./solvers/bin/mcsp -A mcsplit -t 1000 -q \
    instances/MIVIA/mcs10/bvg/b03/mcs10_b03_s40.A00 \
    instances/MIVIA/mcs10/bvg/b03/mcs10_b03_s40.B00

SIP LAD format (BI - biochemical reactions):

./solvers/bin/mcsp -A rrsplit -t 1000 -l -q \
    instances/SIP/biochemicalReactions/001.txt \
    instances/SIP/biochemicalReactions/002.txt

SIP LAD format (LV):

./solvers/bin/mcsp -A dal_dal -t 0 -l -q \
    instances/SIP/LV/g2 \
    instances/SIP/LV/g5

Output Format

One line, space-separated:

<unified_size> <unified_edges> <unified_nodes> <unified_time> <unified_aborted> <unified_nodes_to_best> <unified_time_to_best> <unified_cut_branches> <unified_bound_pruned> <unified_sym_pruned>
Field Description
unified_size Solution size (MCS vertex count)
unified_edges Edges in the common subgraph
unified_nodes Search tree nodes explored
unified_time Wall-clock time in seconds
unified_aborted 1 if timed out before proving optimality, 0 if completed
unified_nodes_to_best Nodes explored before best incumbent found
unified_time_to_best Time at which best incumbent was found (seconds)
unified_cut_branches Total branches pruned
unified_bound_pruned Branches pruned by the algorithm's bound
unified_sym_pruned Branches pruned by symmetry or redundancy reduction

When run with --with-ref on HPC (see below), four extra fields are appended: ref_size, ref_nodes, ref_time, match (PASS/FAIL/MISSING_DATA).


Running Experiments on HPC (Hypatia)

1. Sync files to Hypatia

rsync -avu --progress \
  "[source-directory]/" \
  [account]@hypatia.st-andrews.ac.uk:work/[target-directory]/

2. Connect to Hypatia

ssh [account]@hypatia.st-andrews.ac.uk

3. Build on Hypatia

cd ~/work/[target-directory]/solvers && rm -f bin/mcsp && make

4. Submit scripts

Submit one algorithm at a time so as not to hit the QOS limits. Each script accepts an optional --with-ref flag to also run the corresponding reference binary and record a PASS/FAIL/MISSING_DATA comparison alongside the unified solver's results.

cd ~/work/[target-directory]

# plain mode
bash hpc/submit_mivia.sh mcsplit
bash hpc/submit_bi.sh dsb
bash hpc/submit_lv.sh symsplit

# with reference comparison
bash hpc/submit_mivia.sh mcsplit --with-ref
bash hpc/submit_bi.sh dsb --with-ref
bash hpc/submit_lv.sh symsplit --with-ref

Wait for each array to finish (squeue -u [account]) before submitting the next, to stay within QOS limits.

5. Monitoring progress

squeue -u [account]                                    # job status
ls hpc/results/<algo>_<dataset>/ | wc -l               # instances completed (plain mode)
ls hpc/results/<algo>_<dataset>_with_ref/ | wc -l      # instances completed (ref mode)
head -5 -q hpc/results/<algo>_<dataset>/*.csv          # spot-check output

e.g. ls hpc/results/mcsplit_mivia/ | wc -l or ls hpc/results/dsb_bi_with_ref/ | wc -l.

6. Collect and merge results

Per-instance CSVs (one file per instance pair, no header) are merged into a single file with the correct header using hpc/merge_results.sh:

bash hpc/merge_results.sh <algo> <dataset> [--with-ref]

e.g.:

bash hpc/merge_results.sh dsb bi                   # → hpc/results/dsb_bi_all.csv
bash hpc/merge_results.sh symsplit lv --with-ref   # → hpc/results/symsplit_lv_with_ref_all.csv

Plain-mode header (13 columns):

instance_a,instance_b,algo,unified_size,unified_edges,unified_nodes,unified_time,unified_aborted,unified_nodes_to_best,unified_time_to_best,unified_cut_branches,unified_bound_pruned,unified_sym_pruned

Ref-mode header (17 columns):

instance_a,instance_b,algo,unified_size,unified_edges,unified_nodes,unified_time,unified_aborted,unified_nodes_to_best,unified_time_to_best,unified_cut_branches,unified_bound_pruned,unified_sym_pruned,ref_size,ref_nodes,ref_time,match

7. Copy results back to local machine

scp [account]@hypatia.st-andrews.ac.uk:work/[target-directory]/hpc/results/*_all.csv \
    "[source-directory]/"

Adding a New Algorithm

  1. Implement the algorithm in a new .cpp file in solvers/src/, following the pattern of existing implementations (entry point returning std::vector<VtxPair>).
  2. Register the dispatch in solvers/src/main.cpp - add an else if (algo == "my_algo") branch.
  3. Add the file to the compiler command in solvers/Makefile.
  4. If a reference binary exists, add it under reference/my_algo/ (see Reference Implementations for the expected layout) and add a case for it in hpc/run_instance.sh under the WITH_REF=1 block.
  5. Rebuild and validate:
make -C solvers
bash hpc/submit_mivia.sh my_algo --with-ref

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages