diff --git a/Sources/SwiftGraph/Graph.swift b/Sources/SwiftGraph/Graph.swift index 4dcf770..575d6fe 100644 --- a/Sources/SwiftGraph/Graph.swift +++ b/Sources/SwiftGraph/Graph.swift @@ -236,6 +236,28 @@ extension Graph { removeVertexAtIndex(i) } } + + /// How many edges end at the vertex at this index? Undirected edges are considered as ending at both vertices. + /// + /// - Parameter index: Index of the vertex. + /// - Returns: The count of edges that end at that vertex. + public func indegreeOfVertex(at index: Int) -> Int { + var count = 0 + for edgesForVertex in edges { + for edge in edgesForVertex where edge.v == index { + count += 1 + } + } + return count + } + + /// How many edges start at the vertex at this index? Undirected edges are considered as starting at both vertices. + /// + /// - Parameter index: Index of the vertex. + /// - Returns: The count of edges that start at that vertex. + public func outdegreeOfVertex(at index: Int) -> Int { + edges[index].count + } /// Check whether an edge is in the graph or not. /// diff --git a/Tests/SwiftGraphTests/SwiftGraphTests.swift b/Tests/SwiftGraphTests/SwiftGraphTests.swift index 114d987..55a28ca 100644 --- a/Tests/SwiftGraphTests/SwiftGraphTests.swift +++ b/Tests/SwiftGraphTests/SwiftGraphTests.swift @@ -71,7 +71,44 @@ class SwiftGraphTests: XCTestCase { XCTAssertEqual(g.vertexCount, 2, "2 total vertices") XCTAssertEqual(g.edgeCount, 1, "1 total edges") } - + + func testIndegreeAndOutdegree() { + var g = UnweightedGraph() + let atlantaIndex = g.addVertex("Atlanta") + let nyIndex = g.addVertex("New York") + let miamiIndex = g.addVertex("Miami") + let sfIndex = g.addVertex("San Francisco") + let arezzoIndex = g.addVertex("Arezzo") + g.addEdge(from: "Atlanta", to: "New York", directed: true) + let nyAtlantaEdge = UnweightedEdge(u: nyIndex, v: atlantaIndex, directed: true) + g.addEdge(nyAtlantaEdge, directed: true) + g.addEdge(from: "Miami", to: "Atlanta", directed: true) + g.addEdge(from: "New York", to: "Miami", directed: false) + g.addEdge(from: "Atlanta", to: "Miami", directed: true) + g.addEdge(from: "San Francisco", to: "Miami", directed: false) + XCTAssertEqual(g.indegreeOfVertex(at: atlantaIndex), 2, "2 edges end at Atlanta") + XCTAssertEqual(g.indegreeOfVertex(at: miamiIndex), 3, "3 edges end at Miami") + XCTAssertEqual(g.indegreeOfVertex(at: sfIndex), 1, "1 edge ends at San Francisco") + XCTAssertEqual(g.indegreeOfVertex(at: nyIndex), 2, "2 edges end at New York") + XCTAssertEqual(g.indegreeOfVertex(at: arezzoIndex), 0, "0 edges end at Arezzo") + XCTAssertEqual(g.outdegreeOfVertex(at: atlantaIndex), 2, "2 edges start from Atlanta") + XCTAssertEqual(g.outdegreeOfVertex(at: miamiIndex), 3, "3 edges start from Miami") + XCTAssertEqual(g.outdegreeOfVertex(at: sfIndex), 1, "1 edge starts from San Francisco") + XCTAssertEqual(g.outdegreeOfVertex(at: nyIndex), 2, "2 edges start from New York") + XCTAssertEqual(g.outdegreeOfVertex(at: arezzoIndex), 0, "0 edges start from Arezzo") + g.removeEdge(nyAtlantaEdge) + XCTAssertEqual(g.indegreeOfVertex(at: atlantaIndex), 1, "1 edgee ends at Atlanta") + XCTAssertEqual(g.indegreeOfVertex(at: miamiIndex), 3, "3 edges end at Miami") + XCTAssertEqual(g.indegreeOfVertex(at: sfIndex), 1, "1 edge ends at San Francisco") + XCTAssertEqual(g.indegreeOfVertex(at: nyIndex), 2, "2 edges end at New York") + XCTAssertEqual(g.indegreeOfVertex(at: arezzoIndex), 0, "0 edges end at Arezzo") + XCTAssertEqual(g.outdegreeOfVertex(at: atlantaIndex), 2, "2 edges start from Atlanta") + XCTAssertEqual(g.outdegreeOfVertex(at: miamiIndex), 3, "3 edges start from Miami") + XCTAssertEqual(g.outdegreeOfVertex(at: sfIndex), 1, "1 edge starts from San Francisco") + XCTAssertEqual(g.outdegreeOfVertex(at: nyIndex), 1, "1 edge starts from New York") + XCTAssertEqual(g.outdegreeOfVertex(at: arezzoIndex), 0, "0 edges start from Arezzo") + } + func testSubscript() { let g: UnweightedGraph = UnweightedGraph() _ = g.addVertex("Atlanta")