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

97 lines
3.5 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 by (c) 2022 and onwards The vChewing Project (MIT License).
// 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
public init(node: Node) {
self.node = node
}
}
///
///
/// (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 {
v.distance = u.distance + w
v.prev = u
}
}
typealias VertexSpan = [Vertex]
/// 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: Vertex) -> [Vertex] {
class State {
var iterIndex: Int
var 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
}
}