Use Array instead of Vector where possible

This commit is contained in:
hectr 2018-12-10 00:32:14 +01:00
parent 634afeca6a
commit 347691d331
8 changed files with 78 additions and 76 deletions

View File

@ -15,7 +15,7 @@ import Swift
import ElementaryCyclesSearch import ElementaryCyclesSearch
extension ElementaryCyclesSearch { extension ElementaryCyclesSearch {
static func toArray(elementaryCycles: Vector<Vector<Node>>) -> [[Node]] { static func toArray(elementaryCycles: Array<Array<Node>>) -> [[Node]] {
var cycles = [[Node]]() var cycles = [[Node]]()
for vector in elementaryCycles { for vector in elementaryCycles {
var cycle = [Node]() var cycle = [Node]()

View File

@ -18,7 +18,7 @@ public struct ElementaryCycles {
public static func find<Node: Hashable>(graph: [Node: [Node]], sort: ((Node, Node) -> Bool)? = nil) -> [[Node]] { public static func find<Node: Hashable>(graph: [Node: [Node]], sort: ((Node, Node) -> Bool)? = nil) -> [[Node]] {
let nodes = AdjacencyMatrix.getNodes(graph: graph, sort: sort) let nodes = AdjacencyMatrix.getNodes(graph: graph, sort: sort)
let adjacencyMatrix = try! AdjacencyMatrix.getAdjacencyMatrix(nodes: nodes, adjacencyDictionary: graph) let adjacencyMatrix = try! AdjacencyMatrix.getAdjacencyMatrix(nodes: nodes, adjacencyDictionary: graph)
let elementaryCycles = ElementaryCyclesSearch.getElementaryCycles(adjacencyMatrix: adjacencyMatrix, graphNodes: Vector(array: nodes)) let elementaryCycles = ElementaryCyclesSearch.getElementaryCycles(adjacencyMatrix: adjacencyMatrix, graphNodes: nodes)
return ElementaryCyclesSearch.toArray(elementaryCycles: elementaryCycles) return ElementaryCyclesSearch.toArray(elementaryCycles: elementaryCycles)
} }
} }

View File

@ -39,16 +39,16 @@ extension Matrix where Element == Int {
let list = Matrix<Int>(adjacencyMatrix.reservedLength) let list = Matrix<Int>(adjacencyMatrix.reservedLength)
for i in 0 ..< adjacencyMatrix.reservedLength { for i in 0 ..< adjacencyMatrix.reservedLength {
let v = Vector<Int>() var v = Array<Int>()
for j in 0 ..< adjacencyMatrix[i].reservedLength { for j in 0 ..< adjacencyMatrix[i].reservedLength {
if let isAdjacent = adjacencyMatrix[i]?[j], isAdjacent { if let isAdjacent = adjacencyMatrix[i]?[j], isAdjacent {
v.add(j) v.append(j)
} }
} }
list[i] = Vector(v.size) list[i] = Vector(v.count)
for j in 0 ..< v.size { for j in 0 ..< v.count {
let integer = v.get(j) let integer = v[j]
list[i][j] = integer list[i][j] = integer
} }
} }

View File

@ -77,7 +77,7 @@ class StrongConnectedComponents {
private var visited: Vector<Bool>! private var visited: Vector<Bool>!
/** Helpattribute for finding scc's */ /** Helpattribute for finding scc's */
private var stack: Vector<Int>! private var stack: Array<Int>!
/** Helpattribute for finding scc's */ /** Helpattribute for finding scc's */
private var lowlink: Vector<Int>! private var lowlink: Vector<Int>!
@ -89,7 +89,7 @@ class StrongConnectedComponents {
private var strongConnectedComponentsCounter = 0; private var strongConnectedComponentsCounter = 0;
/** Helpattribute for finding scc's */ /** Helpattribute for finding scc's */
private var currentStrongConnectedComponents: Vector<Vector<Int>>! private var currentStrongConnectedComponents: Array<Array<Int>>!
/** /**
* Constructor. * Constructor.
@ -116,9 +116,9 @@ class StrongConnectedComponents {
lowlink = Vector<Int>(self.adjacencyListOriginal.reservedLength) lowlink = Vector<Int>(self.adjacencyListOriginal.reservedLength)
number = Vector<Int>(self.adjacencyListOriginal.reservedLength) number = Vector<Int>(self.adjacencyListOriginal.reservedLength)
visited = Vector<Bool>(self.adjacencyListOriginal.reservedLength) visited = Vector<Bool>(self.adjacencyListOriginal.reservedLength)
stack = Vector<Int>() stack = Array<Int>()
currentStrongConnectedComponents = Vector<Vector<Int>>() currentStrongConnectedComponents = Array<Array<Int>>()
makeAdjacencyListSubgraph(node: node); makeAdjacencyListSubgraph(node: node);
for i in node ..< self.adjacencyListOriginal.reservedLength { for i in node ..< self.adjacencyListOriginal.reservedLength {
@ -153,17 +153,17 @@ class StrongConnectedComponents {
adjacencyList = AdjacencyList(adjacencyListOriginal.reservedLength, 0) adjacencyList = AdjacencyList(adjacencyListOriginal.reservedLength, 0)
for i in node ..< adjacencyList.reservedLength { for i in node ..< adjacencyList.reservedLength {
let successors = Vector<Int>() var successors = Array<Int>()
for j in 0 ..< self.adjacencyListOriginal[i].reservedLength { for j in 0 ..< self.adjacencyListOriginal[i].reservedLength {
guard let original = adjacencyListOriginal[i]?[j] else { continue } guard let original = adjacencyListOriginal[i]?[j] else { continue }
if original >= node { if original >= node {
successors.add(original) successors.append(original)
} }
} }
if successors.size > 0 { if successors.count > 0 {
adjacencyList[i] = Vector(successors.size) adjacencyList[i] = Vector(successors.count)
for j in 0 ..< successors.size { for j in 0 ..< successors.count {
let succ = successors.get(j) let succ = successors[j]
adjacencyList[i][j] = succ adjacencyList[i][j] = succ
} }
} }
@ -176,14 +176,14 @@ class StrongConnectedComponents {
* *
* @return Vector::Integer of the strongConnectedComponents containing the lowest nodenumber * @return Vector::Integer of the strongConnectedComponents containing the lowest nodenumber
*/ */
private func getLowestIdComponent() -> Vector<Int>? { private func getLowestIdComponent() -> Array<Int>? {
var min = adjacencyList.reservedLength; var min = adjacencyList.reservedLength;
var currScc: Vector<Int>? var currScc: Array<Int>?
for i in 0 ..< currentStrongConnectedComponents.size { for i in 0 ..< currentStrongConnectedComponents.count {
let strongConnectedComponents = currentStrongConnectedComponents.get(i) let strongConnectedComponents = currentStrongConnectedComponents[i]
for j in 0 ..< strongConnectedComponents.size { for j in 0 ..< strongConnectedComponents.count {
let node = strongConnectedComponents.get(j) let node = strongConnectedComponents[j]
if node < min { if node < min {
currScc = strongConnectedComponents currScc = strongConnectedComponents
min = node min = node
@ -199,14 +199,14 @@ class StrongConnectedComponents {
* strong connected component with least vertex in the currently viewed * strong connected component with least vertex in the currently viewed
* subgraph * subgraph
*/ */
private func getAdjList(nodes: Vector<Int>?) -> AdjacencyList? { private func getAdjList(nodes: Array<Int>?) -> AdjacencyList? {
guard let nodes = nodes else { return nil } guard let nodes = nodes else { return nil }
let lowestIdAdjacencyList = AdjacencyList(adjacencyList.reservedLength) let lowestIdAdjacencyList = AdjacencyList(adjacencyList.reservedLength)
for i in 0 ..< lowestIdAdjacencyList.reservedLength { for i in 0 ..< lowestIdAdjacencyList.reservedLength {
lowestIdAdjacencyList[i] = Vector<Int>() lowestIdAdjacencyList[i] = Vector<Int>()
} }
for i in 0 ..< nodes.size { for i in 0 ..< nodes.count {
let node = nodes.get(i) let node = nodes[i]
guard let adjListNode = adjacencyList[node] else { continue } guard let adjListNode = adjacencyList[node] else { continue }
for j in 0 ..< adjListNode.reservedLength { for j in 0 ..< adjListNode.reservedLength {
guard let succ = adjacencyList[node]?[j] else { continue } guard let succ = adjacencyList[node]?[j] else { continue }
@ -228,8 +228,8 @@ class StrongConnectedComponents {
strongConnectedComponentsCounter += 1 strongConnectedComponentsCounter += 1
lowlink[root] = strongConnectedComponentsCounter lowlink[root] = strongConnectedComponentsCounter
number[root] = strongConnectedComponentsCounter number[root] = strongConnectedComponentsCounter
visited[root] = true; visited[root] = true
stack.add(root); stack.append(root)
for i in 0 ..< adjacencyList[root].reservedLength { for i in 0 ..< adjacencyList[root].reservedLength {
guard let w = adjacencyList[root]?[i] else { continue } guard let w = adjacencyList[root]?[i] else { continue }
@ -244,19 +244,19 @@ class StrongConnectedComponents {
} }
// found strongConnectedComponents // found strongConnectedComponents
if (lowlink[root] == number[root]) && (stack.size > 0) { if (lowlink[root] == number[root]) && (stack.count > 0) {
var next = -1; var next = -1;
let strongConnectedComponents = Vector<Int>() var strongConnectedComponents = Array<Int>()
repeat { repeat {
next = stack.get(stack.size - 1) guard let popped = stack.popLast() else { break }
stack.remove(at: stack.size - 1) next = popped
strongConnectedComponents.add(next) strongConnectedComponents.append(next)
} while number[next]! > number[root]! } while number[next]! > number[root]!
// simple scc's with just one node will not be added // simple scc's with just one node will not be added
if strongConnectedComponents.size > 1 { if strongConnectedComponents.count > 1 {
currentStrongConnectedComponents.add(strongConnectedComponents); currentStrongConnectedComponents.append(strongConnectedComponents);
} }
} }
} }

View File

@ -42,13 +42,13 @@ import Swift
*/ */
public class ElementaryCyclesSearch<Node> { public class ElementaryCyclesSearch<Node> {
/** List of cycles */ /** List of cycles */
private var cycles: Vector<Vector<Node>> private var cycles: Array<Array<Node>>
/** Adjacency-list of graph */ /** Adjacency-list of graph */
private var adjacencyList: AdjacencyList private var adjacencyList: AdjacencyList
/** Graphnodes */ /** Graphnodes */
private var graphNodes: Vector<Node> private var graphNodes: Array<Node>
/** Blocked nodes, used by the algorithm of Johnson */ /** Blocked nodes, used by the algorithm of Johnson */
private var blocked: Vector<Bool> private var blocked: Vector<Bool>
@ -57,7 +57,7 @@ public class ElementaryCyclesSearch<Node> {
private var B: Matrix<Int> private var B: Matrix<Int>
/** Stack for nodes, used by the algorithm of Johnson */ /** Stack for nodes, used by the algorithm of Johnson */
private var stack: Vector<Int> private var stack: Array<Int>
/** /**
* Returns List::List::Object with the Lists of nodes of all elementary * Returns List::List::Object with the Lists of nodes of all elementary
@ -70,7 +70,7 @@ public class ElementaryCyclesSearch<Node> {
* *
* @return List::List::Object with the Lists of the elementary cycles. * @return List::List::Object with the Lists of the elementary cycles.
*/ */
public static func getElementaryCycles(adjacencyMatrix: AdjacencyMatrix, graphNodes: Vector<Node>) -> Vector<Vector<Node>> { public static func getElementaryCycles(adjacencyMatrix: AdjacencyMatrix, graphNodes: Array<Node>) -> Array<Array<Node>> {
let ecs = ElementaryCyclesSearch(adjacencyMatrix: adjacencyMatrix, graphNodes: graphNodes) let ecs = ElementaryCyclesSearch(adjacencyMatrix: adjacencyMatrix, graphNodes: graphNodes)
return ecs.getElementaryCycles() return ecs.getElementaryCycles()
} }
@ -83,13 +83,13 @@ public class ElementaryCyclesSearch<Node> {
* build sets of the elementary cycles containing the objects of the original * build sets of the elementary cycles containing the objects of the original
* graph-representation * graph-representation
*/ */
private init(adjacencyMatrix: AdjacencyMatrix, graphNodes: Vector<Node>) { private init(adjacencyMatrix: AdjacencyMatrix, graphNodes: Array<Node>) {
self.graphNodes = graphNodes; self.graphNodes = graphNodes;
self.adjacencyList = AdjacencyList.getAdjacencyList(adjacencyMatrix: adjacencyMatrix) self.adjacencyList = AdjacencyList.getAdjacencyList(adjacencyMatrix: adjacencyMatrix)
cycles = Vector<Vector<Node>>() cycles = Array<Array<Node>>()
blocked = Vector<Bool>(adjacencyList.reservedLength) blocked = Vector<Bool>(adjacencyList.reservedLength)
B = Matrix<Int>(adjacencyList.reservedLength) B = Matrix<Int>(adjacencyList.reservedLength)
stack = Vector<Int>() stack = Array<Int>()
} }
/** /**
@ -98,7 +98,7 @@ public class ElementaryCyclesSearch<Node> {
* *
* @return List::List::Object with the Lists of the elementary cycles. * @return List::List::Object with the Lists of the elementary cycles.
*/ */
private func getElementaryCycles() -> Vector<Vector<Node>> { private func getElementaryCycles() -> Array<Array<Node>> {
let sccs = StrongConnectedComponents(adjacencyList: adjacencyList) let sccs = StrongConnectedComponents(adjacencyList: adjacencyList)
var s = 0 var s = 0
@ -135,20 +135,20 @@ public class ElementaryCyclesSearch<Node> {
*/ */
private func findCycles(v: Int, s: Int, adjacencyList: AdjacencyList) -> Bool { private func findCycles(v: Int, s: Int, adjacencyList: AdjacencyList) -> Bool {
var f = false var f = false
stack.add(v) stack.append(v)
blocked[v] = true blocked[v] = true
for i in 0 ..< adjacencyList[v].size { for i in 0 ..< adjacencyList[v].size {
let w = adjacencyList[v].get(i) let w = adjacencyList[v].get(i)
// found cycle // found cycle
if w == s { if w == s {
let cycle = Vector<Node>() var cycle = Array<Node>()
for j in 0 ..< stack.size { for j in 0 ..< stack.count {
let index = stack.get(j) let index = stack[j]
guard let node = graphNodes[index] else { continue } let node = graphNodes[index] // WARNING guard
cycle.add(node) cycle.append(node)
} }
cycles.add(cycle) cycles.append(cycle)
f = true f = true
} else if !(blocked[w] ?? false) { } else if !(blocked[w] ?? false) {
if findCycles(v: w, s: s, adjacencyList: adjacencyList) { if findCycles(v: w, s: s, adjacencyList: adjacencyList) {
@ -167,8 +167,10 @@ public class ElementaryCyclesSearch<Node> {
} }
} }
} }
stack.remove(element: v) if let index = stack.index(of: v) {
stack.remove(at: index)
}
return f return f
} }

View File

@ -26,12 +26,12 @@ import ElementaryCyclesSearch
typealias Node = String typealias Node = String
private func printCycles(_ cycles: Vector<Vector<Node>>) { private func printCycles(_ cycles: Array<Array<Node>>) {
for i in 0 ..< cycles.size { for i in 0 ..< cycles.count {
let cycle = cycles.get(i) let cycle = cycles[i]
for j in 0 ..< cycle.size { for j in 0 ..< cycle.count {
let node = cycle.get(j) let node = cycle[j]
if j < (cycle.size - 1) { if j < (cycle.count - 1) {
print(node + " -> ", terminator: "") print(node + " -> ", terminator: "")
} else { } else {
print(node, terminator: "") print(node, terminator: "")
@ -41,10 +41,10 @@ private func printCycles(_ cycles: Vector<Vector<Node>>) {
} }
} }
let nodes: Vector<Node> = { let nodes: Array<Node> = {
let vector = Vector<Node>(10) var vector = Array<Node>()
for i in 0 ..< 10 { for i in 0 ..< 10 {
vector[i] = "Node \(i)" vector.append("Node \(i)")
} }
return vector return vector
}() }()

View File

@ -6,10 +6,10 @@ final class ElementaryCyclesSearchTests: XCTestCase {
private typealias Node = String private typealias Node = String
private var nodes: Vector<Node> { private var nodes: Array<Node> {
let nodes = Vector<Node>(10) var nodes = Array<Node>()
for i in 0 ..< 10 { for i in 0 ..< 10 {
nodes[i] = "Node \(i)" nodes.append("Node \(i)")
} }
return nodes return nodes
} }
@ -29,15 +29,15 @@ final class ElementaryCyclesSearchTests: XCTestCase {
matrix[6][1] = true matrix[6][1] = true
} }
private var sut: ((AdjacencyMatrix, Vector<Node>) -> Vector<Vector<Node>>)! private var sut: ((AdjacencyMatrix, Array<Node>) -> Array<Array<Node>>)!
private func prettify(cycles: Vector<Vector<Node>>) -> String { private func prettify(cycles: Array<Array<Node>>) -> String {
var description = "" var description = ""
for i in 0 ..< cycles.size { for i in 0 ..< cycles.count {
let cycle = cycles.get(i) let cycle = cycles[i]
for j in 0 ..< cycle.size { for j in 0 ..< cycle.count {
let node = cycle.get(j) let node = cycle[j]
if j < (cycle.size - 1) { if j < (cycle.count - 1) {
description.append(node + " -> ") description.append(node + " -> ")
} else { } else {
description.append(node) description.append(node)

View File

@ -7,10 +7,10 @@ final class ElementaryCyclesSearchShould: XCTestCase {
private typealias Node = String private typealias Node = String
private var nodes: Vector<Node> { private var nodes: Array<Node> {
let nodes = Vector<Node>(10) var nodes = Array<Node>()
for i in 0 ..< 10 { for i in 0 ..< 10 {
nodes[i] = "Node \(i)" nodes.append("Node \(i)")
} }
return nodes return nodes
} }