vChewing-macOS/Packages/vChewing_Megrez/Sources/Megrez/5_Vertex.swift

110 lines
4.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Swiftified and further development by (c) 2022 and onwards The vChewing Project (MIT License).
// Was initially rebranded from (c) Lukhnos Liu's C++ library "Gramambular 2" (MIT License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
extension Megrez.Compositor {
///
///
///
class Vertex {
///
public var prev: Vertex?
///
public var edges = [Vertex]()
///
///
///
/// /
public var distance = -(Double.infinity)
///
public var topologicallySorted = false
///
public var node: Node
///
///
///
/// - Parameter node:
public init(node: Node) {
self.node = node
}
/// Vertex Vertex
/// Vertex 使
public func destroy() {
while prev?.prev != nil { prev?.destroy() }
prev = nil
edges.forEach { $0.destroy() }
edges.removeAll()
node = .init()
}
}
///
///
/// (relax) Cormen 2001 Introduction to Algorithms 585
/// - Parameters:
/// - u: v
/// - v:
func relax(u: Vertex, v: inout Vertex) {
// u w v
let w: Double = v.node.score
//
// v u ww u w v
// v
if v.distance >= u.distance + w { return }
v.distance = u.distance + w
v.prev = u
}
/// topological
/// sort
///
/// 使
///
/// ```
/// func topologicalSort(vertex: Vertex) {
/// for vertexNode in vertex.edges {
/// if !vertexNode.topologicallySorted {
/// dfs(vertexNode, result)
/// vertexNode.topologicallySorted = true
/// }
/// result.append(vertexNode)
/// }
/// }
/// ```
/// Cormen 2001 Introduction to Algorithms
/// - Parameter root:
/// - Returns:
func topologicalSort(root: inout Vertex) -> [Vertex] {
class State {
var iterIndex: Int
let vertex: Vertex
init(vertex: Vertex, iterIndex: Int = 0) {
self.vertex = vertex
self.iterIndex = iterIndex
}
}
var result = [Vertex]()
var stack = [State]()
stack.append(.init(vertex: root))
while !stack.isEmpty {
let state = stack[stack.count - 1]
let theVertex = state.vertex
if state.iterIndex < state.vertex.edges.count {
let newVertex = state.vertex.edges[state.iterIndex]
state.iterIndex += 1
if !newVertex.topologicallySorted {
stack.append(.init(vertex: newVertex))
continue
}
}
theVertex.topologicallySorted = true
result.append(theVertex)
stack.removeLast()
}
return result
}
}