Skip to content

Commit 905dd1a

Browse files
Fix formatting, implement methods to lookup edges.
1 parent ebc4508 commit 905dd1a

File tree

5 files changed

+97
-120
lines changed

5 files changed

+97
-120
lines changed

Graph/Graph Adjacency Matrix.playground/Contents.swift

Lines changed: 0 additions & 59 deletions
This file was deleted.

Graph/Graph Adjacency Matrix.playground/contents.xcplayground

Lines changed: 0 additions & 4 deletions
This file was deleted.

Graph/Graph Adjacency Matrix.playground/timeline.xctimeline

Lines changed: 0 additions & 6 deletions
This file was deleted.

Graph/Graph.playground/Pages/Adjacency List.xcplaygroundpage/Contents.swift

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,51 @@ A graph implementation, using an adjacency list.
44

55
In an adjacency list implementation, each vertex stores an array of edges, indicating to which vertices it has an edge (note the directionality). The edge stores the source and destination vertices, as well as a weight.
66

7-
Connected vertices in this implementation is O(1).
7+
Connecting vertices in this implementation is O(1).
88

99
*/
1010

11+
var uniqueIDCounter: Int = 0
12+
1113
public struct GraphEdge<T> {
1214
public let from: GraphVertex<T>
1315
public let to: GraphVertex<T>
1416
public let weight: Double
1517
}
1618

19+
1720
public struct GraphVertex<T> {
1821
public var data: T
19-
public private(set) var edges: [GraphEdge<T>] = [] // This is a simple adjacency list, rather than matrix
22+
public private(set) var edges: [GraphEdge<T>] = [] // This is an adjacency list, rather than matrix
23+
24+
private let uniqueID: Int
2025

2126
public init(data: T) {
2227
self.data = data
28+
uniqueID = uniqueIDCounter
29+
uniqueIDCounter += 1
2330
}
2431

2532
// Creates a directed edge self -----> dest
26-
public mutating func connectTo(destinationVertex: GraphVertex<T>, withWeight weight: Double = 0) {
33+
public mutating func connectTo(destinationVertex: GraphVertex<T>, withWeight weight: Double = 1.0) {
2734
edges.append(GraphEdge(from: self, to: destinationVertex, weight: weight))
2835
}
2936

3037
// Creates an undirected edge by making 2 directed edges: self ----> other, and other ----> self
31-
public mutating func connectBetween(inout otherVertex: GraphVertex<T>, withWeight weight: Double = 0) {
38+
public mutating func connectBetween(inout otherVertex: GraphVertex<T>, withWeight weight: Double = 1.0) {
3239
edges.append(GraphEdge(from: self, to: otherVertex, weight: weight))
3340
otherVertex.edges.append(GraphEdge(from: otherVertex, to: self, weight: weight))
3441
}
42+
43+
public func edgeTo(otherVertex: GraphVertex<T>) -> GraphEdge<T>? {
44+
for e in edges {
45+
if e.to.uniqueID == otherVertex.uniqueID {
46+
return e
47+
}
48+
}
49+
50+
return nil
51+
}
3552
}
3653

3754

@@ -43,15 +60,25 @@ var v3 = GraphVertex(data: 3)
4360
var v4 = GraphVertex(data: 4)
4461

4562
// Setup a cycle like so:
46-
// v1 ---> v2 ---> v3 ---> v4
47-
// ^ |
48-
// | V
49-
// -----------<------------|
63+
// v1 ---(1)---> v2 ---(1)---> v3 ---(4.5)---> v4
64+
// ^ |
65+
// | V
66+
// ---------<-----------<---------(2.8)----<----|
67+
68+
v1.connectTo(v2, withWeight: 1.0)
69+
v2.connectTo(v3, withWeight: 1.0)
70+
v3.connectTo(v4, withWeight: 4.5)
71+
v4.connectTo(v1, withWeight: 2.8)
72+
73+
// Returns the weight of the edge from v1 to v2 (1.0)
74+
v1.edgeTo(v2)?.weight
5075

51-
v1.connectTo(v2)
52-
v2.connectTo(v3)
53-
v3.connectTo(v4)
54-
v4.connectTo(v1)
76+
// Returns the weight of the edge from v1 to v3 (nil, since there is not an edge)
77+
v1.edgeTo(v3)?.weight
5578

79+
// Returns the weight of the edge from v3 to v4 (4.5)
80+
v3.edgeTo(v4)?.weight
5681

82+
// Returns the weight of the edge from v4 to v1 (2.8)
83+
v4.edgeTo(v1)?.weight
5784
//: [Next](@next)

Graph/Graph.playground/Pages/Adjacency Matrix.xcplaygroundpage/Contents.swift

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,49 @@ Connecting vertices os O(1).
1111
*/
1212

1313
public struct GraphVertex<T> {
14-
public var data: T
15-
private let uniqueID: Int
14+
public var data: T
15+
private let uniqueID: Int
1616
}
1717

1818
public struct Graph<T> {
19+
20+
// nil entries are used to mark that two vertices are NOT connected.
21+
// If adjacencyMatrix[i][j] is not nil, then there is an edge from vertex i to vertex j.
22+
private var adjacencyMatrix: [[Double?]] = []
23+
24+
public init() { }
25+
26+
public mutating func createVertex(data: T) -> GraphVertex<T> {
27+
let vertex = GraphVertex(data: data, uniqueID: adjacencyMatrix.count)
1928

20-
// nil entries are used to mark that two vertices are NOT connected.
21-
private var adjacencyMatrix: [[Double?]] = []
22-
23-
public init() { }
24-
25-
public mutating func createVertex(data: T) -> GraphVertex<T> {
26-
let vertex = GraphVertex(data: data, uniqueID: adjacencyMatrix.count)
27-
28-
// Expand each existing row to the right one column
29-
for i in 0..<adjacencyMatrix.count {
30-
adjacencyMatrix[i].append(nil)
31-
}
32-
33-
// Add one new row at the bottom
34-
let newRow = [Double?](count: adjacencyMatrix.count + 1, repeatedValue: nil)
35-
adjacencyMatrix.append(newRow)
36-
37-
return vertex
29+
// Expand each existing row to the right one column
30+
for i in 0..<adjacencyMatrix.count {
31+
adjacencyMatrix[i].append(nil)
3832
}
3933

40-
// Creates a directed edge source -----> dest. Represented by M[source][dest] = weight
41-
public mutating func connect(sourceVertex: GraphVertex<T>, toDestinationVertex: GraphVertex<T>, withWeight weight: Double = 0) {
42-
adjacencyMatrix[sourceVertex.uniqueID][toDestinationVertex.uniqueID] = weight
43-
}
34+
// Add one new row at the bottom
35+
let newRow = [Double?](count: adjacencyMatrix.count + 1, repeatedValue: nil)
36+
adjacencyMatrix.append(newRow)
4437

45-
// Creates an undirected edge by making 2 directed edges: some ----> other, and other ----> some
46-
public mutating func connect(someVertex: GraphVertex<T>, withVertex: GraphVertex<T>, withWeight weight: Double = 0) {
47-
adjacencyMatrix[someVertex.uniqueID][withVertex.uniqueID] = weight
48-
adjacencyMatrix[withVertex.uniqueID][someVertex.uniqueID] = weight
49-
50-
}
38+
return vertex
39+
}
40+
41+
// Creates a directed edge source -----> dest. Represented by M[source][dest] = weight
42+
public mutating func connect(sourceVertex: GraphVertex<T>, toDestinationVertex: GraphVertex<T>, withWeight weight: Double = 0) {
43+
adjacencyMatrix[sourceVertex.uniqueID][toDestinationVertex.uniqueID] = weight
44+
}
45+
46+
// Creates an undirected edge by making 2 directed edges: some ----> other, and other ----> some
47+
public mutating func connect(someVertex: GraphVertex<T>, symmetricallyWithVertex withVertex: GraphVertex<T>, withWeight weight: Double = 0) {
48+
adjacencyMatrix[someVertex.uniqueID][withVertex.uniqueID] = weight
49+
adjacencyMatrix[withVertex.uniqueID][someVertex.uniqueID] = weight
50+
51+
}
52+
53+
public func weightFrom(sourceVertex: GraphVertex<T>, toDestinationVertex: GraphVertex<T>) -> Double? {
54+
return adjacencyMatrix[sourceVertex.uniqueID][toDestinationVertex.uniqueID]
55+
}
56+
5157
}
5258

5359

@@ -60,12 +66,25 @@ let v3 = graph.createVertex(3)
6066
let v4 = graph.createVertex(4)
6167

6268
// Setup a cycle like so:
63-
// v1 ---> v2 ---> v3 ---> v4
64-
// ^ |
65-
// | V
66-
// -----------<------------|
67-
68-
graph.connect(v1, toDestinationVertex: v2)
69-
graph.connect(v2, toDestinationVertex: v3)
70-
graph.connect(v3, toDestinationVertex: v4)
71-
graph.connect(v4, toDestinationVertex: v1)
69+
// v1 ---(1)---> v2 ---(1)---> v3 ---(4.5)---> v4
70+
// ^ |
71+
// | V
72+
// ---------<-----------<---------(2.8)----<----|
73+
74+
graph.connect(v1, toDestinationVertex: v2, withWeight: 1.0)
75+
graph.connect(v2, toDestinationVertex: v3, withWeight: 1.0)
76+
graph.connect(v3, toDestinationVertex: v4, withWeight: 4.5)
77+
graph.connect(v4, toDestinationVertex: v1, withWeight: 2.8)
78+
79+
// Returns the weight of the edge from v1 to v2 (1.0)
80+
graph.weightFrom(v1, toDestinationVertex: v2)
81+
82+
// Returns the weight of the edge from v1 to v3 (nil, since there is not an edge)
83+
graph.weightFrom(v1, toDestinationVertex: v3)
84+
85+
// Returns the weight of the edge from v3 to v4 (4.5)
86+
graph.weightFrom(v3, toDestinationVertex: v4)
87+
88+
// Returns the weight of the edge from v4 to v1 (2.8)
89+
graph.weightFrom(v4, toDestinationVertex: v1)
90+

0 commit comments

Comments
 (0)