Use Array instead of Vector where possible
This commit is contained in:
parent
634afeca6a
commit
347691d331
|
@ -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]()
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue