Megrez // Weighten nodes with longer span (Megrez v1.0.7).
This commit is contained in:
parent
afa2dd2feb
commit
7db65e6e2c
|
@ -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..<border] {
|
||||
var n = n
|
||||
if n.node == nil {
|
||||
guard let nNode = n.node else {
|
||||
continue
|
||||
}
|
||||
|
||||
n.accumulatedScore = accumulatedScore + n.node!.score()
|
||||
// 利用 Spanning Length 來決定權重。
|
||||
// 這樣一來,例:「再見」比「在」與「見」的權重更高。
|
||||
let weightedScore: Double = (Double(n.spanningLength) - 1) * 2
|
||||
n.accumulatedScore = accumulatedScore + nNode.score() + weightedScore
|
||||
|
||||
var path: [NodeAnchor] = reverseWalk(
|
||||
at: location - n.spanningLength,
|
||||
|
@ -54,6 +70,11 @@ extension Megrez {
|
|||
path.insert(n, at: 0)
|
||||
|
||||
paths.append(path)
|
||||
|
||||
// 始終使用固定的候選字
|
||||
if nNode.score() >= 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !paths.isEmpty {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue