{"id":34599267,"url":"https://github.com/mtresnik/graph","last_synced_at":"2026-04-19T20:33:36.015Z","repository":{"id":181510571,"uuid":"348187516","full_name":"mtresnik/graph","owner":"mtresnik","description":"A graph theory and Maze library for kotlin JVM","archived":false,"fork":false,"pushed_at":"2023-08-19T20:50:14.000Z","size":1871,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-08-19T21:53:17.892Z","etag":null,"topics":["astar","astar-algorithm","bfs","dfs","dijkstras","dijkstras-algorithm","jvm","kotlin","kruskal-algorithm","kruskals","maze","maze-generator","maze-solver","prims","prims-algorithm"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mtresnik.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}},"created_at":"2021-03-16T02:23:52.000Z","updated_at":"2022-03-18T02:50:15.000Z","dependencies_parsed_at":"2023-07-15T23:26:02.114Z","dependency_job_id":"3534a9b3-9c28-415e-bdd8-d22c4df9fb89","html_url":"https://github.com/mtresnik/graph","commit_stats":null,"previous_names":["mtresnik/graph"],"tags_count":1,"template":null,"template_full_name":null,"purl":"pkg:github/mtresnik/graph","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtresnik%2Fgraph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtresnik%2Fgraph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtresnik%2Fgraph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtresnik%2Fgraph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mtresnik","download_url":"https://codeload.github.com/mtresnik/graph/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtresnik%2Fgraph/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28002250,"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","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["astar","astar-algorithm","bfs","dfs","dijkstras","dijkstras-algorithm","jvm","kotlin","kruskal-algorithm","kruskals","maze","maze-generator","maze-solver","prims","prims-algorithm"],"created_at":"2025-12-24T12:07:58.290Z","updated_at":"2025-12-24T12:08:12.516Z","avatar_url":"https://github.com/mtresnik.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# graph\r\n\r\n[![build status](https://github.com/mtresnik/graph/actions/workflows/gradle.yml/badge.svg)](https://github.com/mtresnik/graph/actions/workflows/gradle.yml/)\r\n[![version](https://img.shields.io/badge/version-1.0.0-blue)](https://github.com/mtresnik/graph/packages/1423284)\r\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://github.com/mtresnik/graph/blob/main/LICENSE)\r\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-green.svg?style=flat-square)](https://makeapullrequest.com)\r\n\r\nA novel Graph-Theory and Maze Solution library made for kotlin JVM.\r\n\u003chr\u003e\r\n\r\n\r\n## Dependencies\r\n\u003e Please compile against [com.resnik.math:1.0.0](https://github.com/mtresnik/math/packages/1409888) and [com.resnik.intel:1.0.0](https://github.com/mtresnik/intel/packages/1423052) as well as this project.\r\n\r\n## Getting Started\r\n\r\n\u003e This is a slightly different process to that of [com.resnik.intel](https://github.com/mtresnik/intel/).\r\n\r\n## Maven\r\n\r\n**~/.m2/settings.xml:**\r\n```xml\r\n\u003csettings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"\r\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n  xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0\r\n                      http://maven.apache.org/xsd/settings-1.0.0.xsd\"\u003e\r\n    ...\r\n  \u003cactiveProfiles\u003e\r\n    \u003cactiveProfile\u003egithub\u003c/activeProfile\u003e\r\n  \u003c/activeProfiles\u003e\r\n    ...\r\n  \u003cservers\u003e\r\n    \u003cserver\u003e\r\n      \u003cid\u003egithub\u003c/id\u003e\r\n      \u003cusername\u003eGITHUB_USERNAME\u003c/username\u003e\r\n      \u003cpassword\u003eGITHUB_PAT\u003c/password\u003e\r\n    \u003c/server\u003e\r\n  \u003c/servers\u003e\r\n\u003c/settings\u003e\r\n```\r\n\r\n**pom.xml:**\r\n```xml\r\n\u003crepository\u003e\r\n    \u003cid\u003egithub\u003c/id\u003e\r\n    \u003curl\u003ehttps://maven.pkg.github.com/mtresnik/math\u003c/url\u003e\r\n    \u003csnapshots\u003e\r\n        \u003cenabled\u003etrue\u003c/enabled\u003e\r\n    \u003c/snapshots\u003e\r\n\u003c/repository\u003e\r\n\r\n\u003crepository\u003e\r\n    \u003cid\u003egithub\u003c/id\u003e\r\n    \u003curl\u003ehttps://maven.pkg.github.com/mtresnik/intel\u003c/url\u003e\r\n    \u003csnapshots\u003e\r\n        \u003cenabled\u003etrue\u003c/enabled\u003e\r\n    \u003c/snapshots\u003e\r\n\u003c/repository\u003e\r\n\r\n\u003crepository\u003e\r\n    \u003cid\u003egithub\u003c/id\u003e\r\n    \u003curl\u003ehttps://maven.pkg.github.com/mtresnik/graph\u003c/url\u003e\r\n    \u003csnapshots\u003e\r\n        \u003cenabled\u003etrue\u003c/enabled\u003e\r\n    \u003c/snapshots\u003e\r\n\u003c/repository\u003e\r\n...\r\n\u003cdependency\u003e\r\n    \u003cgroupId\u003ecom.resnik\u003c/groupId\u003e\r\n    \u003cartifactId\u003emath\u003c/artifactId\u003e\r\n    \u003cversion\u003e1.0.0\u003c/version\u003e\r\n\u003c/dependency\u003e\r\n\r\n\u003cdependency\u003e\r\n    \u003cgroupId\u003ecom.resnik\u003c/groupId\u003e\r\n    \u003cartifactId\u003eintel\u003c/artifactId\u003e\r\n    \u003cversion\u003e1.0.0\u003c/version\u003e\r\n\u003c/dependency\u003e\r\n\r\n\u003cdependency\u003e\r\n    \u003cgroupId\u003ecom.resnik\u003c/groupId\u003e\r\n    \u003cartifactId\u003egraph\u003c/artifactId\u003e\r\n    \u003cversion\u003e1.0.0\u003c/version\u003e\r\n\u003c/dependency\u003e\r\n```\r\n\r\n## Gradle (groovy)\r\n\r\n**~/.gradle/gradle.properties:**\r\n```groovy\r\ngpr.user=GITHUB_USERNAME\r\ngpr.token=GITHUB_PAT\r\n```\r\n\r\n**build.gradle:**\r\n```groovy\r\nrepositories {\r\n    ...\r\n    maven {\r\n        url= uri(\"https://maven.pkg.github.com/mtresnik/math\")\r\n        credentials {\r\n            // Runner stored in env, else stored in ~/.gradle/gradle.properties\r\n            username = System.getenv(\"USERNAME\") ?: findProperty(\"gpr.user\") ?: \"\u003cGITHUB_USERNAME\u003e\"\r\n            password = System.getenv(\"TOKEN\") ?: findProperty(\"gpr.token\")\r\n        }\r\n    }\r\n    ...\r\n    maven {\r\n        url= uri(\"https://maven.pkg.github.com/mtresnik/intel\")\r\n        credentials {\r\n            // Runner stored in env, else stored in ~/.gradle/gradle.properties\r\n            username = System.getenv(\"USERNAME\") ?: findProperty(\"gpr.user\") ?: \"\u003cGITHUB_USERNAME\u003e\"\r\n            password = System.getenv(\"TOKEN\") ?: findProperty(\"gpr.token\")\r\n        }\r\n    }\r\n    maven {\r\n        url= uri(\"https://maven.pkg.github.com/mtresnik/graph\")\r\n        credentials {\r\n            // Runner stored in env, else stored in ~/.gradle/gradle.properties\r\n            username = System.getenv(\"USERNAME\") ?: findProperty(\"gpr.user\") ?: \"\u003cGITHUB_USERNAME\u003e\"\r\n            password = System.getenv(\"TOKEN\") ?: findProperty(\"gpr.token\")\r\n        }\r\n    }\r\n}\r\n\r\ndependencies {\r\n    ...\r\n    implementation group: 'com.resnik', name: 'math', version: '1.0.0'\r\n    implementation group: 'com.resnik', name: 'intel', version: '1.0.0'\r\n    implementation group: 'com.resnik', name: 'graph', version: '1.0.0'\r\n    ...\r\n}\r\n```\r\n\r\n\u003chr\u003e\r\n\r\n# Mazes\r\n\r\n## Maze Generation\r\n\r\n### Minimum Spanning Trees (MST's)\r\n\r\n| Prim's Algorithm (40x40) | Kruskal's Algorithm (40x40) | \r\n| -------- |-------- |\r\n| \u003cimg src=\"https://i.imgur.com/vIca2nz.png\" width=\"300\"\u003e     |\u003cimg src=\"https://i.imgur.com/PTpO31E.png\" width=\"300\"\u003e     |\r\n\r\nThe obvious benefit to MST's is that every node can be reached from any other node, meaning all produced mazes are consistent (able to be solved).\r\n\r\n| \"Recursive\" Subdivision (40x40) | Aldous-Broder Algorithm |\r\n| -------- |-------- |\r\n| \u003cimg src=\"https://i.imgur.com/EPrUePe.png\" width=\"300\"\u003e     | \u003cimg src=\"https://i.imgur.com/2pDalGG.png\" width=\"300\"\u003e     |\r\n\r\n**Recursive** is in quotes here because the actual process of generating the Maze uses Depth First Search in a single method rather than programatically calling itself.\r\n\r\nThe Aldous-Broder Algorithm is slightly modified such that neighboring frontiers are connected. This produces a more uniform spanning tree.\r\n\r\n\u003e WIP : Recursive DFS for Maze Generation\r\n\r\n\r\n## Maze To Graph Conversions\r\n\r\n| Initial Maze | Graph Representation |\r\n| -------- | -------- |\r\n| \u003cimg src=\"https://i.imgur.com/sz2smzf.png\" width=\"300\"\u003e | \u003cimg src=\"https://i.imgur.com/KS33Nej.png\" width=\"300\"\u003e |\r\n\r\n```kotlin \r\nval maze : Maze = // Somehow generated maze...\r\nval graph = MazeToGraphProvider(maze).build()\r\n```\r\n\r\nThe resulting graph represents the initial maze, where a `MazeCell` is represented by a `Vertex` and a `MazeBorder` determines the `Edge`'s.\r\n\r\n| Maze Solution | Graph Solution |\r\n| -------- | -------- |\r\n| \u003cimg src=\"https://i.imgur.com/IkCbjGr.png\" width=\"300\"\u003e | \u003cimg src=\"https://i.imgur.com/vW6NIsA.png\" width=\"300\"\u003e |\r\n\r\nAll `GraphAlgorithms` can be used on `Graphs` and all `Mazes` can be converted into `Graphs`.\r\n\r\n## Traversals\r\n\r\n### Path Finding\r\n* Breadth-First Search\r\n* Depth-First Search\r\n* Dijkstra\r\n* A* Search\r\n\r\n### Minimum Spanning Trees (MST)\r\n\r\n| Kruskal's Algorithm | Prim's Algorithm |\r\n| -------- | -------- |\r\n| \u003cimg src=\"https://i.imgur.com/wgCCtWD.png\" width=\"300\"\u003e     | \u003cimg src=\"https://i.imgur.com/zQy0Kmh.png\" width=\"300\"\u003e     | \r\n\r\n\u003e Generated using `PartiallyConnectedGraph` with V=20 and (E/V)\u003c=10\r\n\r\nIn general, the `MST` algorithms accept a base `Graph` and return a cloned `Graph` representing the Tree. (Formally this is written as G \\ T)\r\n\r\n### Traveling Salesperson Problem (TSP)\r\n\r\n* Brute Force Search - O(n!) **uses recursion**\r\n* Permutation Search - O(n!) **linear search**\r\n* Random Search - O(N * (|V| + |E|))\r\n* Greedy Search (sub optimal) - O(|V| + |E|)\r\n* Greedy Twice-Around (uses Prim's MST) - O(|V|^2 + MST)\r\n* Two-Opt (reduces edge cross over)\r\n\r\n## Serialization\r\n\r\nVertices, Edges, Paths, and Graphs are both `Clonable` and `Serializable`.\r\n\r\nSaving an `Identifyable` Item to an `ItemizedLongStorable` will set an auto-incementing ID (long) to the Item and store it within its internal collection. In general, there is `VertexStorage`, `EdgeStorage`, `PathStorage`, and `GraphStorage`.\r\n\r\n```kotlin \r\n/*\r\n * Where xyzStorage could be: \r\n * VertexStorage, \r\n * EdgeStorage, \r\n * PathStorage, or GraphStorage\r\n * */\r\nval outputStream = ByteArrayOutputStream()\r\nxyzStorage.writeTo(outputStream)\r\n\r\n// or to file...\r\nval parent = File(\"PATH/TO/GRAPH/STORAGE\")\r\nxyzStorage.saveFromParent(parent)\r\n```\r\n\r\n### VertexStorage\r\n\r\n#### Usage\r\n```kotlin \r\nval vertexStorage = graph.storage.vertexStorage\r\n// or\r\nval vertexStorage2 = VertexStorage()\r\nvertexStorage2.save(v1)\r\nvertexStorage2.save(v2)\r\n// ...\r\nvertexStorage2.save(vn)\r\n\r\nvertexStorageX.forEach{ vertex -\u003e doSomething(vertex) }\r\n```\r\n\r\n```\r\nheader v size 3 \r\nheader v bbox 0.1 1.0 11.0 2.0 \r\nv 1 0.5 1.0 | 1 5 11\r\nv 2 0.1 2.0\r\nv 3 11.0 2.0 | 12\r\n```\r\n\r\n### EdgeStorage\r\n\r\n#### Usage\r\n```kotlin \r\nval edgeStorage = graph.storage.edgeStorage\r\n// or\r\nval vertexStorage = VertexStorage()\r\nval edgeStorage2 = EdgeStorage(vertexStorage)\r\nvertexStorage.save(v1)\r\nvertexStorage.save(v2)\r\nval edge1 = Edge(v1, v2)\r\nedgeStorage2.save(edge1)\r\n\r\nedgeStorageX.forEach { edge -\u003e doSomething(edge) }\r\n```\r\n\r\n```\r\nheader e size 3 \r\ne 1 1 2 0.0\r\ne 2 2 3 0.0\r\ne 3 3 1 0.0\r\n```\r\n\r\n### GraphStorage\r\n\r\n```\r\nheader g v PATH\\TO\\VERTICES\\file.rgv\r\nheader g e PATH\\TO\\EDGES\\file.rge \r\nheader g t PATH\\TO\\PATHS\\file.rgt \r\n```\r\n\r\n## Graph Providers\r\n```kotlin\r\nval graphProvider = BoundedGraphProvider(bbox, width, height)\r\nval graph = graphProvider.build()\r\n\r\n// Prune input by 20%\r\nval prunedProvider = RandomPruneGraphProvider(graph, 0.20)\r\n\r\n// Uses a cloned graph for pruning\r\nval pruned1 = prunedProvider.build()\r\nval pruned2 = prunedProvider.build()\r\n// ...\r\nval prunedN = prunedProvider.build()\r\n```\r\n\r\n\r\n## Nearest Neighbor\r\n\r\n```kotlin \r\nval vertexStorage = graph.storage.vertexStorage\r\n\r\n// O(|V|)\r\nval start = vertexStorage.nearestNeighbor(ArrayPoint(0.5, 1.0))\r\nval dest = vertexStorage.nearestNeighbor(ArrayPoint(10.5, -20))\r\n\r\n// kNN checks : O(k*|V|)\r\nval closest3 = vertexStorage.kNearestNeighbors(ArrayPoint(3.0, 4.0), 6)\r\n\r\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtresnik%2Fgraph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmtresnik%2Fgraph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtresnik%2Fgraph/lists"}