");
+ sb.append("| ");
+ sb.append(getNodeLabel(node));
+ sb.append(" |
");
+ sb.append("| ");
+ sb.append("");
+ sb.append(node.getWordCost());
+ sb.append("");
+ sb.append(" |
");
+// sb.append("| ");
+// sb.append(this.dictionary.get(node.getWordId()).getPosInfo());
+// sb.append(" |
");
+ sb.append("
>");
+ return sb.toString();
+ }
+
+ private String getNodeId(ViterbiNode node) {
+ return String.valueOf(node.hashCode());
+ }
+
+ private String getNodeLabel(ViterbiNode node) {
+ if (node.getType() == Type.KNOWN && node.getWordId() == 0) {
+ if (this.foundBOS) {
+ return EOS_LABEL;
+ } else {
+ this.foundBOS = true;
+ return BOS_LABEL;
+ }
+ } else {
+ return node.getSurfaceForm();
+ }
+ }
+
+ private int getCost(ViterbiNode from, ViterbiNode to) {
+ return this.costs.get(from.getLeftId(), to.getRightId());
+ }
+}
\ No newline at end of file
diff --git a/modules/analysis/kuromoji/src/java/org/apache/lucene/analysis/kuromoji/viterbi/Viterbi.java b/modules/analysis/kuromoji/src/java/org/apache/lucene/analysis/kuromoji/viterbi/Viterbi.java
new file mode 100644
index 0000000..6c01f47
--- /dev/null
+++ b/modules/analysis/kuromoji/src/java/org/apache/lucene/analysis/kuromoji/viterbi/Viterbi.java
@@ -0,0 +1,353 @@
+package org.apache.lucene.analysis.kuromoji.viterbi;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.lucene.analysis.kuromoji.Tokenizer.Mode;
+import org.apache.lucene.analysis.kuromoji.dict.CharacterDefinition;
+import org.apache.lucene.analysis.kuromoji.dict.ConnectionCosts;
+import org.apache.lucene.analysis.kuromoji.dict.TokenInfoDictionary;
+import org.apache.lucene.analysis.kuromoji.dict.UnknownDictionary;
+import org.apache.lucene.analysis.kuromoji.dict.UserDictionary;
+import org.apache.lucene.analysis.kuromoji.dict.CharacterDefinition.CharacterClass;
+import org.apache.lucene.analysis.kuromoji.trie.DoubleArrayTrie;
+import org.apache.lucene.analysis.kuromoji.viterbi.ViterbiNode.Type;
+
+public class Viterbi {
+
+ private final DoubleArrayTrie trie;
+
+ private final TokenInfoDictionary dictionary;
+
+ private final UnknownDictionary unkDictionary;
+
+ private final ConnectionCosts costs;
+
+ private final UserDictionary userDictionary;
+
+ private final CharacterDefinition characterDefinition;
+
+ private final boolean useUserDictionary;
+
+ private final boolean searchMode;
+
+ private final boolean extendedMode;
+
+ private static final int DEFAULT_COST = 10000000;
+
+ private static final int SEARCH_MODE_LENGTH_KANJI = 3;
+
+ private static final int SEARCH_MODE_LENGTH = 7;
+
+ private static final int SEARCH_MODE_PENALTY = 10000;
+
+ private static final String BOS = "BOS";
+
+ private static final String EOS = "EOS";
+
+ /**
+ * Constructor
+ * @param trie
+ * @param targetMap
+ * @param dictionary
+ * @param unkDictionary
+ * @param costs
+ * @param userDictionary
+ */
+ public Viterbi(DoubleArrayTrie trie,
+ TokenInfoDictionary dictionary,
+ UnknownDictionary unkDictionary,
+ ConnectionCosts costs,
+ UserDictionary userDictionary,
+ Mode mode) {
+ this.trie = trie;
+ this.dictionary = dictionary;
+ this.unkDictionary = unkDictionary;
+ this.costs = costs;
+ this.userDictionary = userDictionary;
+ if(userDictionary == null) {
+ this.useUserDictionary = false;
+ } else {
+ this.useUserDictionary = true;
+ }
+
+ switch(mode){
+ case SEARCH:
+ searchMode = true;
+ extendedMode = false;
+ break;
+ case EXTENDED:
+ searchMode = true;
+ extendedMode = true;
+ break;
+ default:
+ searchMode = false;
+ extendedMode = false;
+ break;
+ }
+
+ this.characterDefinition = unkDictionary.getCharacterDefinition();
+ }
+
+ /**
+ * Find best path from input lattice.
+ * @param lattice the result of build method
+ * @return List of ViterbiNode which consist best path
+ */
+ public List