From 7db65e6e2c268fa5cfa17ecbf5d2765b116bda54 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Tue, 10 May 2022 14:23:24 +0800 Subject: [PATCH] Megrez // Weighten nodes with longer span (Megrez v1.0.7). --- .../LanguageParsers/Megrez/1_Walker.swift | 31 ++++++++++++++++--- .../LanguageParsers/Megrez/2_Grid.swift | 20 ++++++------ .../LanguageParsers/Megrez/3_NodeAnchor.swift | 6 ++++ .../LanguageParsers/Megrez/4_Node.swift | 4 ++- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/Source/Modules/LanguageParsers/Megrez/1_Walker.swift b/Source/Modules/LanguageParsers/Megrez/1_Walker.swift index 7c2a5051..429d78b5 100644 --- a/Source/Modules/LanguageParsers/Megrez/1_Walker.swift +++ b/Source/Modules/LanguageParsers/Megrez/1_Walker.swift @@ -31,21 +31,37 @@ extension Megrez { mutGrid = grid } - public func reverseWalk(at location: Int, score accumulatedScore: Double = 0.0) -> [NodeAnchor] { + public func reverseWalk(at location: Int, score accumulatedScore: Double = 0.0, nodesLimit: Int = 0) + -> [NodeAnchor] + { if location == 0 || location > mutGrid.width() { return [] as [NodeAnchor] } var paths: [[NodeAnchor]] = [] - let nodes: [NodeAnchor] = mutGrid.nodesEndingAt(location: location) + var nodes: [NodeAnchor] = mutGrid.nodesEndingAt(location: location) - for n in nodes { + nodes.sort { + $0.balancedScore > $1.balancedScore // 排序規則已經在 NodeAnchor 內定義了。 + } + + // 只檢查前 X 個 NodeAnchor 是否有 node。 + // 這裡有 abs 是為了防止有白癡填負數。 + var border: Int = nodes.count + if nodesLimit > 0 { + border = min(nodes.count, abs(nodesLimit)) + } + + for n in nodes[0..= 0 { + break + } } if !paths.isEmpty { diff --git a/Source/Modules/LanguageParsers/Megrez/2_Grid.swift b/Source/Modules/LanguageParsers/Megrez/2_Grid.swift index c391b425..355c6bf8 100644 --- a/Source/Modules/LanguageParsers/Megrez/2_Grid.swift +++ b/Source/Modules/LanguageParsers/Megrez/2_Grid.swift @@ -140,16 +140,15 @@ extension Megrez { public func fixNodeSelectedCandidate(location: Int, value: String) -> NodeAnchor { var node = NodeAnchor() - let nodes = nodesCrossingOrEndingAt(location: location) - for nodeAnchor in nodes { + for (index, nodeAnchor) in nodesCrossingOrEndingAt(location: location).enumerated() { // Reset the candidate-fixed state of every node at the location. let candidates = nodeAnchor.node?.candidates() ?? [] - nodeAnchor.node?.resetCandidate() + nodesCrossingOrEndingAt(location: location)[index].node?.resetCandidate() for (i, candidate) in candidates.enumerated() { if candidate.value == value { - nodeAnchor.node?.selectCandidateAt(index: i) - node = nodeAnchor + nodesCrossingOrEndingAt(location: location)[index].node?.selectCandidateAt(index: i) + node = nodesCrossingOrEndingAt(location: location)[index] break } } @@ -158,18 +157,17 @@ extension Megrez { } public func overrideNodeScoreForSelectedCandidate(location: Int, value: String, overridingScore: Double) { - for nodeAnchor in nodesCrossingOrEndingAt(location: location) { - var nodeAnchor = nodeAnchor + for (index, nodeAnchor) in nodesCrossingOrEndingAt(location: location).enumerated() { if let theNode = nodeAnchor.node { let candidates = theNode.candidates() // Reset the candidate-fixed state of every node at the location. - theNode.resetCandidate() - nodeAnchor.node = theNode + nodesCrossingOrEndingAt(location: location)[index].node?.resetCandidate() for (i, candidate) in candidates.enumerated() { if candidate.value == value { - theNode.selectFloatingCandidateAt(index: i, score: overridingScore) - nodeAnchor.node = theNode + nodesCrossingOrEndingAt(location: location)[index].node?.selectFloatingCandidateAt( + index: i, score: overridingScore + ) break } } diff --git a/Source/Modules/LanguageParsers/Megrez/3_NodeAnchor.swift b/Source/Modules/LanguageParsers/Megrez/3_NodeAnchor.swift index 0a130a58..938262f4 100644 --- a/Source/Modules/LanguageParsers/Megrez/3_NodeAnchor.swift +++ b/Source/Modules/LanguageParsers/Megrez/3_NodeAnchor.swift @@ -32,5 +32,11 @@ extension Megrez { public var keyLength: Int { node?.key().count ?? 0 } + + public var balancedScore: Double { + let weightedScore: Double = (Double(spanningLength) - 1) * 2 + let nodeScore: Double = node?.score() ?? 0 + return weightedScore + nodeScore + } } } diff --git a/Source/Modules/LanguageParsers/Megrez/4_Node.swift b/Source/Modules/LanguageParsers/Megrez/4_Node.swift index fdf0838d..be518b3e 100644 --- a/Source/Modules/LanguageParsers/Megrez/4_Node.swift +++ b/Source/Modules/LanguageParsers/Megrez/4_Node.swift @@ -36,6 +36,8 @@ extension Megrez { var mutCandidateFixed: Bool = false var mutSelectedUnigramIndex: Int = 0 + let kSelectedCandidateScore: Double = 99 + public init(key: String, unigrams: [Megrez.Unigram], bigrams: [Megrez.Bigram] = []) { mutLM = LanguageModel() @@ -112,7 +114,7 @@ extension Megrez { public func selectCandidateAt(index: Int = 0, fix: Bool = false) { mutSelectedUnigramIndex = index >= mutUnigrams.count ? 0 : index mutCandidateFixed = fix - mutScore = 99 + mutScore = kSelectedCandidateScore } public func resetCandidate() {