{"id":19982648,"url":"https://github.com/zabuzard/maglev","last_synced_at":"2026-05-14T19:06:23.195Z","repository":{"id":57735424,"uuid":"219193189","full_name":"Zabuzard/Maglev","owner":"Zabuzard","description":"Maglev is a library that provides fast and generic solutions for shortest path problems (SPP)","archived":false,"fork":false,"pushed_at":"2023-12-11T10:35:59.000Z","size":75,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-12T10:48:29.175Z","etag":null,"topics":["api","astar","dijkstra","landmarks","library","routing","shortest-path-algorithm","shortest-path-problem","shortest-paths"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Zabuzard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-02T18:01:12.000Z","updated_at":"2023-12-11T10:36:03.000Z","dependencies_parsed_at":"2024-11-13T04:13:04.711Z","dependency_job_id":"b2087608-8033-4ff6-aa33-2bfdaa79e87f","html_url":"https://github.com/Zabuzard/Maglev","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zabuzard%2FMaglev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zabuzard%2FMaglev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zabuzard%2FMaglev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zabuzard%2FMaglev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zabuzard","download_url":"https://codeload.github.com/Zabuzard/Maglev/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241418356,"owners_count":19959736,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","astar","dijkstra","landmarks","library","routing","shortest-path-algorithm","shortest-path-problem","shortest-paths"],"created_at":"2024-11-13T04:12:26.360Z","updated_at":"2026-05-14T19:06:23.164Z","avatar_url":"https://github.com/Zabuzard.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Maglev\n\n[![codefactor](https://img.shields.io/codefactor/grade/github/Zabuzard/Maglev)](https://www.codefactor.io/repository/github/zabuzard/maglev)\n[![maven-central](https://img.shields.io/maven-central/v/io.github.zabuzard.maglev/maglev)](https://search.maven.org/search?q=g:io.github.zabuzard.maglev)\n[![javadoc](https://javadoc.io/badge2/io.github.zabuzard.maglev/maglev/javadoc.svg?style=flat\u0026color=AA82FF)](https://javadoc.io/doc/io.github.zabuzard.maglev/maglev)\n![Java](https://img.shields.io/badge/Java-11%2B-ff696c)\n[![license](https://img.shields.io/github/license/Zabuzard/Maglev)](https://github.com/Zabuzard/Maglev/blob/master/LICENSE)\n\nMaglev is a simple library that provides fast and generic solutions for shortest path problems (SPP). It is designed\ngeneric and can easily be modified and extended.\n\nIt is able to compute shortest paths on a given graph structure. It offers:\n\n* `1-1` - one source to one destination\n* `n-1` - the closest source to one destination\n* `1-*` - one source to all reachable nodes\n* `n-*` - the closest sources to all reachable nodes\n\nand the opposite directions by offering an implicit `Graph#reverse()`:\n\n* `1-n` - one source to the closest destination\n* `*-1` - all from destination reachable nodes to destination\n* `*-n` - all from any destination reachable nodes to the closest destination\n\nBy utilizing efficient and well known algorithms, such as:\n\n* Dijkstra\n* A-Star\n* ALT (A-Star with landmarks)\n\nand providing a high degree of customizability by offering ways to manipulate the algorithm using extensions called\n_Dijkstra modules_.\n\nThe main interface of the algorithms provide the following methods:\n\n* `Collection\u003cN\u003e searchSpace(Collection\u003c? extends N\u003e sources, N destination)`\n* `Collection\u003cN\u003e searchSpace(N source, N destination)`\n* `Optional\u003cPath\u003cN, E\u003e\u003e shortestPath(Collection\u003c? extends N\u003e sources, N destination)`\n* `Optional\u003cPath\u003cN, E\u003e\u003e shortestPath(N source, N destination)`\n* `Optional\u003cDouble\u003e shortestPathCost(Collection\u003c? extends N\u003e sources, N destination)`\n* `Optional\u003cDouble\u003e shortestPathCost(N source, N destination)`\n* `Map\u003cN, ? extends HasPathCost\u003e shortestPathCostsReachable(Collection\u003c? extends N\u003e sources)`\n* `Map\u003cN, ? extends HasPathCost\u003e shortestPathCostsReachable(N source)`\n* `PathTree\u003cN, E\u003e shortestPathReachable(Collection\u003c? extends N\u003e sources)`\n* `PathTree\u003cN, E\u003e shortestPathReachable(N source)`\n\n# Requirements\n\n* Requires at least **Java 11**\n\n# Download\n\nMaven:\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.zabuzard.maglev\u003c/groupId\u003e\n    \u003cartifactId\u003emaglev\u003c/artifactId\u003e\n    \u003cversion\u003e1.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nJar downloads are available from the [release section](https://github.com/ZabuzaW/Maglev/releases).\n\n# Documentation\n\n* [API Javadoc](https://javadoc.io/doc/io.github.zabuzard.maglev/maglev)\n  or alternatively from the [release section](https://github.com/ZabuzaW/Maglev/releases)\n\n# Getting started\n\n1. Integrate **Maglev** into your project. The API is contained in the module `io.github.zabuzard.maglev`.\n2. Create an implementation of `Graph\u003cN, E\u003e` for your custom graphs or use `SimpleGraph\u003cN, E\u003e` for a quick start\n3. Populate your graph\n4. Create an algorithm using `ShortestPathComputationBuilder`\n5. Execute shortest path computations using the methods offered by `ShortestPathComputation`\n\n# Examples\n\nConsider the following simple graph setup:\n\n![Graph example](https://i.imgur.com/lumZoLj.png)\n\n```java\nSimpleGraph\u003cInteger, SimpleEdge\u003cInteger\u003e\u003e graph = new SimpleGraph\u003c\u003e();\n\ngraph.addNode(1);\ngraph.addNode(2);\ngraph.addNode(3);\ngraph.addNode(4);\ngraph.addNode(5);\n\ngraph.addEdge(new SimpleEdge\u003c\u003e(1, 2, 8));\ngraph.addEdge(new SimpleEdge\u003c\u003e(1, 3, 1));\ngraph.addEdge(new SimpleEdge\u003c\u003e(2, 5, 2));\ngraph.addEdge(new SimpleEdge\u003c\u003e(3, 4, 2));\ngraph.addEdge(new SimpleEdge\u003c\u003e(4, 2, 1));\ngraph.addEdge(new SimpleEdge\u003c\u003e(4, 5, 5));\n```\n\nNext, we create an algorithm by using the builder with default settings:\n\n```java\nvar algo = new ShortestPathComputationBuilder\u003c\u003e(graph)\n    .build();\nvar path = algo.shortestPath(1, 5);\nSystem.out.println(path);\n```\n\nThe algorithm correctly computes the shortest path from node `1` to `5` (as highlighted in the picture).\n\n***\n\nThe next example demonstrates how to ignore node `4` in all computations:\n\n```java\nvar algo = new ShortestPathComputationBuilder\u003c\u003e(graph)\n    .addModuleIgnoreEdgeIf(edge -\u003e edge.getDestination().equals(4))\n    .build();\nvar path = algo.shortestPath(1, 5);\nSystem.out.println(path);\n```\n\n***\n\nThe third example shows how to compute all reachable shortest path costs, starting from node `1`, but aborting as soon\nas node `4` has been settled:\n\n```java\nvar algo = new ShortestPathComputationBuilder\u003c\u003e(graph)\n    .addModuleAbortAfterIf(dist -\u003e dist.getNode().equals(4))\n    .build();\nvar nodeToCost = algo.shortestPathCostsReachable(1);\n\nnodeToCost.entrySet().stream()\n    .map(entry -\u003e entry.getKey() + \"=\" + entry.getValue().getPathCost())\n    .forEach(System.out::println);\n```\n\n***\n\nThe last example uses ordinary Dijkstra without any modules or optimizations:\n\n```java\nvar algo = new ShortestPathComputationBuilder\u003c\u003e(graph)\n    .resetOrdinaryDijkstra()\n    .build();\nvar path = algo.shortestPath(1, 5);\nSystem.out.println(path);\n```\n\n***\n\n## Advanced\n\nLastly, we show how to create an A-Star algorithm that uses\nthe [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance) (_as the crow flies_)\non a graph consisting of points in a 2-dimensional space.\n\nConsider the following simple class for points in a 2-dimensional space\n\n```java\nclass Point { \n    private final int x;\n    private final int y;\n\n    // constructor, getter, equals, hashCode and toString ommitted\n}\n```\n\nNext, we define our heuristic metric\n\n```java\nclass EuclideanDistance implements Metric\u003cPoint\u003e {\n    @Override\n    public double distance(Point a, Point b) { \n        return Math.sqrt(Math.pow(b.getX() - a.getX(), 2) + Math.pow(b.getY() - a.getY(), 2));\n    }\n}\n```\n\nNow a simple graph consisting of such points:\n\n```java\nSimpleGraph\u003cPoint, SimpleEdge\u003cPoint\u003e\u003e graph = new SimpleGraph\u003c\u003e();\n\nvar a = Point.of(1, 2);\nvar b = Point.of(5, 7);\nvar c = Point.of(-10, 4);\n\ngraph.add(a);\ngraph.add(b);\ngraph.add(c);\n\ngraph.addEdge(new SimpleEdge\u003c\u003e(a, b, 1));\ngraph.addEdge(new SimpleEdge\u003c\u003e(b, c, 1));\ngraph.addEdge(new SimpleEdge\u003c\u003e(a, c, 5));\n```\n\nand finally the algorithm operating on this graph by using A-Star with the Euclidean distance:\n\n```java\nvar algo = new ShortestPathComputationBuilder\u003c\u003e(graph)\n    .setMetric(new EuclideanDistance())\n    .build();\nvar path = algo.shortestPath(a, c);\nSystem.out.println(path);\n```\n\n***\n\n# Graph\n\nThe algorithms operate on a generic `Graph` interface which must be implemented by a user.\n\nTo ease development, `AbstractGraph` can be used as base class. It implements almost all methods already, based on\nabstract\n`Map\u003cN, Set\u003cE\u003e\u003e getNodeToIncomingEdges()` and `Map\u003cN, Set\u003cE\u003e\u003e getNodeToOutgoingEdges`\nmethods which can easily be given by any implementing class.\n\nFurther, there is `SimpleGraph` which already provides a full implementation of the interface.\n\n***\n\nGraphs are defined on a generic node type `N`, no restrictions, and an `Edge\u003cN\u003e` interface. The class `SimpleEdge`\nprovides a full implementation of the interface.\n\n# Builder\n\nThe algorithm builder `ShortestPathComputationBuilder` offers highly customizable algorithms based on _Dijkstra_,\ncalled _Module-Dijkstra_. That is a regular Dijkstra algorithm which can be extended using extension modules that modify\nits behavior. Offered modules are:\n\n* `AbortBeforeIfModule` - Aborts further computation as soon as a node that matches a given predicate would be settled\n* `AbortAfterIfModule` - Aborts further computation as soon as a node that matches a given predicate has been settled\n* `AbortAfterRangeModule` - Only explores shortest paths up to the given range\n* `IgnoreEdgeIfModule` - Ignores exploring edges that match the given predicate\n* `AStarModule` - Optimization of the algorithm by utilizing a given heuristic metric\n\nIt is also possible to add custom modules by simply implementing the interface `DijkstraModule`. Modules can be added by\nusing `addModule(DijkstraModule)` and the other `addModuleXXX` methods.\n\n***\n\nIf the `AStarModule` was chosen, a heuristic metric must be given. Offered metrics are:\n\n* `LandmarkMetric` - Dynamic heuristic computed based on the underlying graph model (also known as _ALT_ algorithm)\n\nIt is also possible to use a custom metric by simply implementing the `Metric` interface, for example a metric based on\nthe _Euclidean distance_. A metric can be set by using `setMetric(Metric)` and the other `setMetricXXX` methods.\n\n***\n\nIf the `LandmarkMetric` was chosen, the amount of landmarks must be set, which can be done\nusing `setAmountOfLandmarks(int)`. Additionally, a landmark provider must be given. Offered landmark providers are:\n\n* `GreedyFarthestLandmarkProvider` - Chooses landmarks that are optimally spread across the graph by dynamically\n  utilizing its structure\n* `RandomLandmarkProvider` - Randomly selects nodes as landmarks\n\nIt is also possible to use a custom landmark provider by simply implementing the `LandmarkProvider` interface. A\nlandmark provider can be set by using `setLandmarkProvider(LandmarkProvider)`\nand the other `setLandmarkProviderXXX` methods.\n\n***\n\nFinally, an algorithm using the selected properties can be created using `build()`. The initial construction might take\na while, depending on the graph size. Results are cached and further constructions will try to utilize the cache\nwhenever possible.\n\nThe **default configuration** of the builder is:\n\n* `AStarModule`\n* `LandmarkMetric`\n* 20 landmarks\n* `RandomLandmarkProvider`\n\nThe method `resetDefault()` can be used to restore the default settings. Likewise `resetOrdinaryDijkstra()` can be used\nto get a configuration that just uses the ordinary Dijkstra algorithm without any modules.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzabuzard%2Fmaglev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzabuzard%2Fmaglev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzabuzard%2Fmaglev/lists"}