One Mork project per problem (CPH, CWP, MMDP, MDP). Each project
re-implements the same algorithm logic as the corresponding project in
../jmh, but running on top of Mork's
experimentation and instance-loading infrastructure instead of the hand-written experiment
runner.
Implementation guide:
../../docs/mork-experiments.mddocuments how these projects were derived from thejmh"proto-framework" — first the general concept-by-concept conversion, then a section per problem.
Each project uses Mork for everything around the algorithm, and keeps the algorithm itself a
faithful, hand-written port of jmh:
| Concern | Provided by Mork | Ported from jmh (hand-written) |
|---|---|---|
| Instance model + loading | Instance, InstanceImporter |
the parser and the data model |
| Solution + objective | Solution, Objective (FMode) |
the representation, score & neighbourhood |
| Reproducible randomness | RandomManager, CollectionUtil |
— |
| Time control | TimeLimitCalculator, TimeControl |
the 10 s / 2 s budget per problem |
| Experiment runner, reports, dashboard | AbstractExperiment, Mork.start, Excel/JSON, web UI |
which algorithms to compare |
| The algorithm | (not used yet) | multi-start local search / Scatter Search |
Important — no reusable Mork algorithm components (yet). The algorithms deliberately do not
use Mork's ready-made building blocks (SimpleAlgorithm, LocalSearchBestImprovement /
LocalSearchFirstImprovement, GraspBuilder, MultiStartAlgorithm, ScatterSearchBuilder, VND,
…). Instead each project contains a custom Algorithm that orchestrates hand-written constructive
and improvement classes mirroring jmh. Migrating these to Mork's reusable components is a
planned later step (that is where Move/Neighborhood will be exercised by Mork's own local
searches; today a Move type exists only to declare the Objective).
Nodes are modelled as int indices with distances on the Instance (idiomatic Mork, as in the
official TSP example) for CPH/CWP/MMDP; MDP keeps its MDPNode domain objects because its Scatter
Search port relies on them.
| Project | Problem | Sense | Algorithm (custom port) | Entry point |
|---|---|---|---|---|
CPH |
Capacitated p-hub | minimize | multi-start local search | es.urjc.etsii.grafo.cph.Main |
CWP |
Cutwidth | minimize | multi-start local search | es.urjc.etsii.grafo.cwp.Main |
MMDP |
MaxMin Diversity | maximize | multi-start local search | es.urjc.etsii.grafo.mmdp.Main |
MDP |
Maximum Diversity | maximize | Scatter Search | es.urjc.etsii.grafo.mdp.Main |
Each project has the standard Mork layout: model/ (Instance, Importer, Solution, Move, Validator),
constructives/ + improve/ (or algorithm/ for MDP), algorithms/ (the custom Algorithm),
experiments/ (the AbstractExperiment + a TimeLimitCalculator), Main, and
src/main/resources/{application.yml,serializers.yml}. Benchmark instances live under each
project's instances/ folder.
- JDK 25 (Mork 0.22).
- Maven (or the bundled toolchain). The projects depend on
es.urjc.etsii.grafo:mork:0.22viamork-parent:0.22(resolved from Maven Central).
cd CPH # or CWP, MMDP, MDP
mvn clean package # builds target/<Project>-1.0-SNAPSHOT.jar
java -jar target/<Project>-1.0-SNAPSHOT.jarOn start, Mork opens a live dashboard at http://localhost:8080/ and, when finished, writes an
Excel report under results/. Runs are reproducible for a fixed solver.seed.
Useful overrides (Spring Boot style, --key=value):
--instances.path.default=instances/<subset>— solve a different instance set or a single file.--solver.repetitions=N— repeat each (instance, algorithm). Default is 1 here, because each multi-start algorithm already performs 5000 internal restarts (Scatter Search runs to its time budget), reproducing onejmhrun.-D<problem>.timeLimitMillis=MS(JVM property, before-jar) — the per-(instance, algorithm) time budget (default 10 s for CPH/CWP/MMDP, 2 s for MDP, matchingjmh). Lower it for quick smoke runs, e.g.java -Dcph.timeLimitMillis=800 -jar ....
Notes:
solver.benchmarkis disabled inapplication.ymlfor a faster start; enable it to normalize time limits across machines.- Algorithm short-names are limited by Mork to 30 characters.