/** * Beispiel aus * * - Algorithmen und Datenstrukturen für Dummies * - von Andreas Gogol-Döring und Thomas Letschert * - Verlag Wiley-VCH; Oktober 2019 * - Kapitel 10, Verbindungen finden * * @author A. Gogol-Döring, Th. Letschert */ import Foundation struct AuD_10_05_SpanningTree { class DS { private let alst: [A] private var k: [A : A] = [:] private var s: [A : Int] = [:] init(_ alst: [A]) { self.alst = alst for a in alst { k[a] = a s[a] = 1 } } func find(_ a: A) -> A { var a_ = a while (a_ != k[a_]!) { a_ = k[a_]! } return a_ } func unite(_ x: A, _ y: A) { let a = find(x) let b = find(y) if (s[a]! >= s[b]!) { s[a] = s[a]! + s[b]! k[b] = a } else { s[b] = s[b]! + s[a]! k[a] = b } } } struct Edge: Hashable, CustomStringConvertible { let l: A let r: A init (_ l: A, _ r: A) { self.l = l self.r = r } var description: String { "(\(l), \(r))" } } struct Graph { let V: [A] let E: [Edge] let w: [Edge : Int] } static func kruskalDS(_ g:Graph) -> [Edge] { var a: [Edge] = [] let ds: DS = DS(g.V) var eSorted: [Edge] = g.E eSorted.sort( by: { (e1: Edge, e2: Edge) -> Bool in g.w[e1]! < g.w[e2]! }) for edge in eSorted { let u = edge.l let v = edge.r if (ds.find(u) != ds.find(v)) { a = a + [edge] ds.unite(u, v) } } return a } static let graph = Graph ( V : ["a", "b", "c", "d", "e", "f"], E : [Edge("a", "b"), Edge("a", "f"), Edge("a", "e"), Edge("b", "c"), Edge("b", "f"), Edge("c", "d"), Edge("c", "f"), Edge("d", "e"), Edge("d", "f"), Edge("e","f") ], w : [ Edge("a", "b") : 3, Edge("a", "f") : 5, Edge("a", "e") : 6, Edge("b", "c") : 1, Edge("b", "f") : 4, Edge("c", "d") : 6, Edge("c", "f") : 4, Edge("d", "e") : 8, Edge("d", "f") : 5, Edge("e", "f") : 2] ) static func run () { print(kruskalDS(graph)) } }