Skip to content

Commit

Permalink
Update to Kotlin 1.9.20
Browse files Browse the repository at this point in the history
This commit includes the following changes:

- Update the codebase to Kotlin 1.9.20
- Split `Graph` into `VertexSet` and `Successors` interfaces
- Update the existing algorithms to work on generic types
- Introduce `Directed` and `Undirected` interfaces
- Add random walk and weighted random walk algorithms
  • Loading branch information
alexandrepiveteau committed Nov 26, 2023
1 parent c1c1b56 commit fc75380
Show file tree
Hide file tree
Showing 36 changed files with 646 additions and 293 deletions.
214 changes: 143 additions & 71 deletions api/kotlin-graphs.api

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
kotlin("multiplatform") version "1.8.20"
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.13.0"
id("org.jetbrains.dokka") version "1.8.10"
kotlin("multiplatform") version "1.9.21"
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.13.2"
id("org.jetbrains.dokka") version "1.9.10"
id("com.vanniktech.maven.publish") version "0.25.2"
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.github.alexandrepiveteau.graphs

/** A marker interface for [Graph]s that are directed. */
public interface Directed {

/** Returns true if the given [arc] is contained in this [Directed] graph, and false otherwise. */
public operator fun contains(arc: Arc): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import io.github.alexandrepiveteau.graphs.builder.buildDirectedGraph
import io.github.alexandrepiveteau.graphs.builder.buildUndirectedGraph

/** A [DirectedGraph] is a [Graph] where [Vertex]s are linked using [Arc]s. */
public interface DirectedGraph : Graph {

/** Returns true if the given [arc] is contained in this [DirectedGraph], and false otherwise. */
public operator fun contains(arc: Arc): Boolean
public interface DirectedGraph : Graph, Directed {

/**
* An object which serves as the companion of [DirectedGraph], and which provides a number of
Expand All @@ -22,13 +19,15 @@ public interface DirectedGraph : Graph {
* Transforms the [DirectedGraph] into an [UndirectedGraph], by adding an edge between each pair of
* vertices that are connected by an arc.
*/
public fun DirectedGraph.toUndirectedGraph(): UndirectedGraph = buildUndirectedGraph {
forEachVertex { addVertex() }
forEachArc { (u, v) -> addEdge(u edgeTo v) }
}
public fun <G> G.toUndirectedGraph(): UndirectedGraph where G : Directed, G : Successors =
buildUndirectedGraph {
forEachVertex { addVertex() }
forEachArc { (u, v) -> addEdge(u edgeTo v) }
}

/** Returns the transposed [DirectedGraph], where the direction of arcs has been reversed. */
public fun DirectedGraph.transposed(): DirectedGraph = buildDirectedGraph {
forEachVertex { addVertex() }
forEachArc { addArc(it.reversed()) }
}
public fun <G> G.transposed(): DirectedGraph where G : Directed, G : Successors =
buildDirectedGraph {
forEachVertex { addVertex() }
forEachArc { addArc(it.reversed()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ package io.github.alexandrepiveteau.graphs
/** A [DirectedNetwork] is a [Network] and a [DirectedGraph]. */
public interface DirectedNetwork : Network, DirectedGraph {

/**
* Returns the weight of the [Arc].
*
* @throws NoSuchVertexException if [arc] is not a valid arc for this [UndirectedNetwork].
* @throws NoSuchEdgeException if there is no arc between the two vertices.
*/
public fun weight(arc: Arc): Int = weight(arc.from, arc.to)

/**
* An object which serves as the companion of the [DirectedNetwork], and which provides a number
* of methods to create [DirectedNetwork]s.
*/
public companion object
}

/**
* Returns the weight of the [Arc].
*
* @throws NoSuchVertexException if [arc] is not a valid arc for this [UndirectedNetwork].
* @throws NoSuchEdgeException if there is no arc between the two vertices.
*/
public fun <N> N.successorWeight(
arc: Arc,
): Int where N : Directed, N : SuccessorsWeight = successorWeight(arc.from, arc.to)
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,4 @@ package io.github.alexandrepiveteau.graphs
* links by their index. This is useful for algorithms which need to iterate over the vertices and
* links of the graph without having to create an explicit iterator.
*/
public interface Graph {

/** The number of vertices in this [Graph]. */
public val size: Int

/** Returns true if the given [vertex] is contained in this [Graph], and false otherwise. */
public operator fun contains(vertex: Vertex): Boolean = index(vertex) in 0 until size

/**
* Returns the index of the given [vertex] in this [Graph]. If the vertex is not contained in this
* [Graph], a [NoSuchVertexException] is thrown.
*/
public fun index(vertex: Vertex): Int

/**
* Returns the [Vertex] at the given [index] in this [Graph]. If the index is not contained in
* this [Graph], an [IndexOutOfBoundsException] is thrown.
*/
public fun vertex(index: Int): Vertex

/**
* Returns the number of edges leaving the [Vertex] at the given index in this [Graph]. If the
* vertex is not contained in this [Graph], an [IndexOutOfBoundsException] is thrown.
*/
public fun successorsSize(index: Int): Int

/**
* Returns the number of edges leaving the given [vertex] in this [Graph]. If the vertex is not
* contained in this [Graph], a [NoSuchVertexException] is thrown.
*/
public fun successorsSize(vertex: Vertex): Int = successorsSize(index(vertex))

/**
* Returns the [Vertex] at the given [neighborIndex] index in the list of neighbors of the
* [Vertex] at the given [index] in this [Graph]. If the vertex is not contained in this [Graph],
* an [IndexOutOfBoundsException] is thrown.
*/
public fun successor(index: Int, neighborIndex: Int): Vertex

/**
* Returns the [Vertex] at the given [neighborIndex] index in the list of neighbors of the given
* [vertex] in this [Graph]. If the vertex is not contained in this [Graph], a
* [NoSuchVertexException], and if the neighbor index is not contained in the list of neighbors of
* the vertex, an [IndexOutOfBoundsException] is thrown.
*/
public fun successor(
vertex: Vertex,
neighborIndex: Int,
): Vertex = successor(index(vertex), neighborIndex)
}
public interface Graph : VertexSet, Successors
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,4 @@ package io.github.alexandrepiveteau.graphs
* A [Network] is a [Graph] with some weights associated to each link. The weights are represented
* as [Int] values.
*/
public interface Network : Graph {

/**
* Returns the weight of the edge between the [Vertex] at [index] and the [Vertex] at
* [neighborIndex].
*
* @throws IndexOutOfBoundsException if [index] or [neighborIndex] are not valid indices.
*/
public fun weight(index: Int, neighborIndex: Int): Int

/**
* Returns the weight of the edge between the [Vertex] at [index] and its [neighbor].
*
* @throws IndexOutOfBoundsException if [index] is not a valid index.
* @throws NoSuchVertexException if [neighbor] is not a valid vertex.
*/
public fun weight(index: Int, neighbor: Vertex): Int

/**
* Returns the weight of the edge between the [vertex] and its [neighbor].
*
* @throws NoSuchVertexException if [vertex] or [neighbor] are not valid vertices.
* @throws NoSuchEdgeException if there is no edge between [vertex] and [neighbor].
*/
public fun weight(vertex: Vertex, neighbor: Vertex): Int = weight(index(vertex), neighbor)

/**
* Returns the weight of the edge between the [vertex] and the [Vertex] at [neighborIndex].
*
* @throws NoSuchVertexException if [vertex] is not a valid vertex.
* @throws IndexOutOfBoundsException if [neighborIndex] is not a valid index.
*/
public fun weight(vertex: Vertex, neighborIndex: Int): Int = weight(index(vertex), neighborIndex)
}
public interface Network : Graph, SuccessorsWeight
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.github.alexandrepiveteau.graphs

/**
* [Predecessors] are a [VertexSet] where each [Vertex] has a list of neighbors, which can be
* accessed by their index.
*/
public interface Predecessors : VertexSet {

/**
* Returns the number of edges entering the [Vertex] at the given index in this [Predecessors]. If
* the vertex is not contained in this [Predecessors], an [IndexOutOfBoundsException] is thrown.
*/
public fun predecessorsSize(index: Int): Int

/**
* Returns the number of edges entering the given [vertex] in this [Predecessors]. If the vertex
* is not contained in this [Predecessors], a [NoSuchVertexException] is thrown.
*/
public fun predecessorsSize(vertex: Vertex): Int = predecessorsSize(index(vertex))

/**
* Returns the [Vertex] at the given [neighborIndex] index in the list of neighbors of the
* [Vertex] at the given [index] in this [Predecessors]. If the vertex is not contained in this
* [Predecessors], an [IndexOutOfBoundsException] is thrown.
*/
public fun predecessor(index: Int, neighborIndex: Int): Vertex

/**
* Returns the [Vertex] at the given [neighborIndex] index in the list of neighbors of the given
* [vertex] in this [Predecessors]. If the vertex is not contained in this [Predecessors], a
* [NoSuchVertexException], and if the neighbor index is not contained in the list of neighbors of
* the vertex, an [IndexOutOfBoundsException] is thrown.
*/
public fun predecessor(
vertex: Vertex,
neighborIndex: Int,
): Vertex = predecessor(index(vertex), neighborIndex)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package io.github.alexandrepiveteau.graphs

/**
* [Successors] are a [VertexSet] where each [Vertex] has a list of neighbors, which can be accessed
* by their index.
*/
public interface Successors : VertexSet {

/**
* Returns the number of edges leaving the [Vertex] at the given index in this [Successors]. If
* the vertex is not contained in this [Successors], an [IndexOutOfBoundsException] is thrown.
*/
public fun successorsSize(index: Int): Int

/**
* Returns the number of edges leaving the given [vertex] in this [Successors]. If the vertex is
* not contained in this [Successors], a [NoSuchVertexException] is thrown.
*/
public fun successorsSize(vertex: Vertex): Int = successorsSize(index(vertex))

/**
* Returns the index of the vertex at the given [neighborIndex] index in the list of neighbors of
* the [Vertex] in this [Successors]. If the vertex is not contained in this [Successors], an
* [IndexOutOfBoundsException] is thrown.
*/
public fun successorIndex(index: Int, neighborIndex: Int): Int

/**
* Returns the index of the vertex at the given [neighborIndex] index in the list of neighbors of
* the [Vertex] in this [Successors]. If the vertex is not contained in this [Successors], a
* [NoSuchVertexException], and if the neighbor index is not contained in the list of neighbors of
* the vertex, an [IndexOutOfBoundsException] is thrown.
*/
public fun successorIndex(
vertex: Vertex,
neighborIndex: Int,
): Int = successorIndex(index(vertex), neighborIndex)

/**
* Returns the [Vertex] at the given [neighborIndex] index in the list of neighbors of the
* [Vertex] at the given [index] in this [Successors]. If the vertex is not contained in this
* [Successors], an [IndexOutOfBoundsException] is thrown.
*/
public fun successorVertex(index: Int, neighborIndex: Int): Vertex

/**
* Returns the [Vertex] at the given [neighborIndex] index in the list of neighbors of the given
* [vertex] in this [Successors]. If the vertex is not contained in this [Successors], a
* [NoSuchVertexException], and if the neighbor index is not contained in the list of neighbors of
* the vertex, an [IndexOutOfBoundsException] is thrown.
*/
public fun successorVertex(
vertex: Vertex,
neighborIndex: Int,
): Vertex = successorVertex(index(vertex), neighborIndex)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.github.alexandrepiveteau.graphs

/**
* [SuccessorsWeight] are a [Successors] where each link has a weight, which can be accessed by
* their index.
*/
public interface SuccessorsWeight : Successors {

/**
* Returns the weight of the edge between the [Vertex] at [index] and the [Vertex] at
* [neighborIndex].
*
* @throws IndexOutOfBoundsException if [index] or [neighborIndex] are not valid indices.
*/
public fun successorWeight(index: Int, neighborIndex: Int): Int

/**
* Returns the weight of the edge between the [Vertex] at [index] and its [neighbor].
*
* @throws IndexOutOfBoundsException if [index] is not a valid index.
* @throws NoSuchVertexException if [neighbor] is not a valid vertex.
*/
public fun successorWeight(index: Int, neighbor: Vertex): Int

/**
* Returns the weight of the edge between the [vertex] and its [neighbor].
*
* @throws NoSuchVertexException if [vertex] or [neighbor] are not valid vertices.
* @throws NoSuchEdgeException if there is no edge between [vertex] and [neighbor].
*/
public fun successorWeight(vertex: Vertex, neighbor: Vertex): Int =
successorWeight(index(vertex), neighbor)

/**
* Returns the weight of the edge between the [vertex] and the [Vertex] at [neighborIndex].
*
* @throws NoSuchVertexException if [vertex] is not a valid vertex.
* @throws IndexOutOfBoundsException if [neighborIndex] is not a valid index.
*/
public fun successorWeight(vertex: Vertex, neighborIndex: Int): Int =
successorWeight(index(vertex), neighborIndex)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.github.alexandrepiveteau.graphs

/** A marker interface for [Graph]s that are undirected. */
public interface Undirected {

/** Returns true if the given [edge] is contained in this [Undirected] graph, and false otherwise. */
public operator fun contains(edge: Edge): Boolean
}
Loading

0 comments on commit fc75380

Please sign in to comment.