https://github.com/mtresnik/graph
A graph theory and Maze library for kotlin JVM
https://github.com/mtresnik/graph
astar astar-algorithm bfs dfs dijkstras dijkstras-algorithm jvm kotlin kruskal-algorithm kruskals maze maze-generator maze-solver prims prims-algorithm
Last synced: about 1 month ago
JSON representation
A graph theory and Maze library for kotlin JVM
- Host: GitHub
- URL: https://github.com/mtresnik/graph
- Owner: mtresnik
- License: apache-2.0
- Created: 2021-03-16T02:23:52.000Z (almost 5 years ago)
- Default Branch: main
- Last Pushed: 2023-08-19T20:50:14.000Z (over 2 years ago)
- Last Synced: 2023-08-19T21:53:17.892Z (over 2 years ago)
- Topics: astar, astar-algorithm, bfs, dfs, dijkstras, dijkstras-algorithm, jvm, kotlin, kruskal-algorithm, kruskals, maze, maze-generator, maze-solver, prims, prims-algorithm
- Language: Kotlin
- Homepage:
- Size: 1.78 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# graph
[](https://github.com/mtresnik/graph/actions/workflows/gradle.yml/)
[](https://github.com/mtresnik/graph/packages/1423284)
[](https://github.com/mtresnik/graph/blob/main/LICENSE)
[](https://makeapullrequest.com)
A novel Graph-Theory and Maze Solution library made for kotlin JVM.
## Dependencies
> 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.
## Getting Started
> This is a slightly different process to that of [com.resnik.intel](https://github.com/mtresnik/intel/).
## Maven
**~/.m2/settings.xml:**
```xml
...
github
...
github
GITHUB_USERNAME
GITHUB_PAT
```
**pom.xml:**
```xml
github
https://maven.pkg.github.com/mtresnik/math
true
github
https://maven.pkg.github.com/mtresnik/intel
true
github
https://maven.pkg.github.com/mtresnik/graph
true
...
com.resnik
math
1.0.0
com.resnik
intel
1.0.0
com.resnik
graph
1.0.0
```
## Gradle (groovy)
**~/.gradle/gradle.properties:**
```groovy
gpr.user=GITHUB_USERNAME
gpr.token=GITHUB_PAT
```
**build.gradle:**
```groovy
repositories {
...
maven {
url= uri("https://maven.pkg.github.com/mtresnik/math")
credentials {
// Runner stored in env, else stored in ~/.gradle/gradle.properties
username = System.getenv("USERNAME") ?: findProperty("gpr.user") ?: ""
password = System.getenv("TOKEN") ?: findProperty("gpr.token")
}
}
...
maven {
url= uri("https://maven.pkg.github.com/mtresnik/intel")
credentials {
// Runner stored in env, else stored in ~/.gradle/gradle.properties
username = System.getenv("USERNAME") ?: findProperty("gpr.user") ?: ""
password = System.getenv("TOKEN") ?: findProperty("gpr.token")
}
}
maven {
url= uri("https://maven.pkg.github.com/mtresnik/graph")
credentials {
// Runner stored in env, else stored in ~/.gradle/gradle.properties
username = System.getenv("USERNAME") ?: findProperty("gpr.user") ?: ""
password = System.getenv("TOKEN") ?: findProperty("gpr.token")
}
}
}
dependencies {
...
implementation group: 'com.resnik', name: 'math', version: '1.0.0'
implementation group: 'com.resnik', name: 'intel', version: '1.0.0'
implementation group: 'com.resnik', name: 'graph', version: '1.0.0'
...
}
```
# Mazes
## Maze Generation
### Minimum Spanning Trees (MST's)
| Prim's Algorithm (40x40) | Kruskal's Algorithm (40x40) |
| -------- |-------- |
|
|
|
The 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).
| "Recursive" Subdivision (40x40) | Aldous-Broder Algorithm |
| -------- |-------- |
|
|
|
**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.
The Aldous-Broder Algorithm is slightly modified such that neighboring frontiers are connected. This produces a more uniform spanning tree.
> WIP : Recursive DFS for Maze Generation
## Maze To Graph Conversions
| Initial Maze | Graph Representation |
| -------- | -------- |
|
|
|
```kotlin
val maze : Maze = // Somehow generated maze...
val graph = MazeToGraphProvider(maze).build()
```
The resulting graph represents the initial maze, where a `MazeCell` is represented by a `Vertex` and a `MazeBorder` determines the `Edge`'s.
| Maze Solution | Graph Solution |
| -------- | -------- |
|
|
|
All `GraphAlgorithms` can be used on `Graphs` and all `Mazes` can be converted into `Graphs`.
## Traversals
### Path Finding
* Breadth-First Search
* Depth-First Search
* Dijkstra
* A* Search
### Minimum Spanning Trees (MST)
| Kruskal's Algorithm | Prim's Algorithm |
| -------- | -------- |
|
|
|
> Generated using `PartiallyConnectedGraph` with V=20 and (E/V)<=10
In general, the `MST` algorithms accept a base `Graph` and return a cloned `Graph` representing the Tree. (Formally this is written as G \ T)
### Traveling Salesperson Problem (TSP)
* Brute Force Search - O(n!) **uses recursion**
* Permutation Search - O(n!) **linear search**
* Random Search - O(N * (|V| + |E|))
* Greedy Search (sub optimal) - O(|V| + |E|)
* Greedy Twice-Around (uses Prim's MST) - O(|V|^2 + MST)
* Two-Opt (reduces edge cross over)
## Serialization
Vertices, Edges, Paths, and Graphs are both `Clonable` and `Serializable`.
Saving 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`.
```kotlin
/*
* Where xyzStorage could be:
* VertexStorage,
* EdgeStorage,
* PathStorage, or GraphStorage
* */
val outputStream = ByteArrayOutputStream()
xyzStorage.writeTo(outputStream)
// or to file...
val parent = File("PATH/TO/GRAPH/STORAGE")
xyzStorage.saveFromParent(parent)
```
### VertexStorage
#### Usage
```kotlin
val vertexStorage = graph.storage.vertexStorage
// or
val vertexStorage2 = VertexStorage()
vertexStorage2.save(v1)
vertexStorage2.save(v2)
// ...
vertexStorage2.save(vn)
vertexStorageX.forEach{ vertex -> doSomething(vertex) }
```
```
header v size 3
header v bbox 0.1 1.0 11.0 2.0
v 1 0.5 1.0 | 1 5 11
v 2 0.1 2.0
v 3 11.0 2.0 | 12
```
### EdgeStorage
#### Usage
```kotlin
val edgeStorage = graph.storage.edgeStorage
// or
val vertexStorage = VertexStorage()
val edgeStorage2 = EdgeStorage(vertexStorage)
vertexStorage.save(v1)
vertexStorage.save(v2)
val edge1 = Edge(v1, v2)
edgeStorage2.save(edge1)
edgeStorageX.forEach { edge -> doSomething(edge) }
```
```
header e size 3
e 1 1 2 0.0
e 2 2 3 0.0
e 3 3 1 0.0
```
### GraphStorage
```
header g v PATH\TO\VERTICES\file.rgv
header g e PATH\TO\EDGES\file.rge
header g t PATH\TO\PATHS\file.rgt
```
## Graph Providers
```kotlin
val graphProvider = BoundedGraphProvider(bbox, width, height)
val graph = graphProvider.build()
// Prune input by 20%
val prunedProvider = RandomPruneGraphProvider(graph, 0.20)
// Uses a cloned graph for pruning
val pruned1 = prunedProvider.build()
val pruned2 = prunedProvider.build()
// ...
val prunedN = prunedProvider.build()
```
## Nearest Neighbor
```kotlin
val vertexStorage = graph.storage.vertexStorage
// O(|V|)
val start = vertexStorage.nearestNeighbor(ArrayPoint(0.5, 1.0))
val dest = vertexStorage.nearestNeighbor(ArrayPoint(10.5, -20))
// kNN checks : O(k*|V|)
val closest3 = vertexStorage.kNearestNeighbors(ArrayPoint(3.0, 4.0), 6)
```