00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef SEARCH_NODE_H
00028 #define SEARCH_NODE_H
00029
00030 #include "lang_mod_edge.h"
00031 #include "cube_reco_context.h"
00032
00033 namespace tesseract {
00034
00035 class SearchNode {
00036 public:
00037 SearchNode(CubeRecoContext *cntxt, SearchNode *parent_node,
00038 int char_reco_cost, LangModEdge *edge, int col_idx);
00039
00040 ~SearchNode();
00041
00042
00043
00044 bool UpdateParent(SearchNode *new_parent, int new_reco_cost,
00045 LangModEdge *new_edge);
00046
00047 char_32 *PathString();
00048
00049 static bool IdenticalPath(SearchNode *node1, SearchNode *node2);
00050
00051 inline const char_32 *NodeString() { return str_; }
00052 inline void SetString(char_32 *str) { str_ = str; }
00053
00054
00055 inline int CharRecoCost() { return char_reco_cost_; }
00056
00057
00058 inline int BestPathRecoCost() { return best_path_reco_cost_; }
00059
00060 inline int BestPathLength() { return best_path_len_; }
00061
00062
00063 inline int BestCost() { return best_cost_; }
00064
00065
00066 inline int BestRecoCost() { return mean_char_reco_cost_ ; }
00067
00068 inline int ColIdx() { return col_idx_; }
00069 inline SearchNode *ParentNode() { return parent_node_; }
00070 inline LangModEdge *LangModelEdge() { return lang_mod_edge_;}
00071 inline int LangModCost() { return LangModCost(lang_mod_edge_, parent_node_); }
00072
00073
00074
00075 inline static int SearchNodeComparer(const void *node1, const void *node2) {
00076 return (*(reinterpret_cast<SearchNode * const *>(node1)))->best_cost_ -
00077 (*(reinterpret_cast<SearchNode * const *>(node2)))->best_cost_;
00078 }
00079
00080 private:
00081 CubeRecoContext *cntxt_;
00082
00083 const char_32 *str_;
00084
00085 int char_reco_cost_;
00086
00087
00088 int best_cost_;
00089
00090
00091 int mean_char_reco_cost_ ;
00092
00093
00094 int best_path_reco_cost_;
00095
00096 int best_path_len_;
00097
00098 int col_idx_;
00099
00100 SearchNode *parent_node_;
00101
00102 LangModEdge *lang_mod_edge_;
00103 static int LangModCost(LangModEdge *lang_mod_edge, SearchNode *parent_node);
00104 };
00105
00106
00107
00108
00109 class SearchNodeHashTable {
00110 public:
00111 SearchNodeHashTable() {
00112 memset(bin_size_array_, 0, sizeof(bin_size_array_));
00113 }
00114
00115 ~SearchNodeHashTable() {
00116 }
00117
00118
00119 inline bool Insert(LangModEdge *lang_mod_edge, SearchNode *srch_node) {
00120
00121 unsigned int edge_hash = lang_mod_edge->Hash();
00122 unsigned int parent_hash = (srch_node->ParentNode() == NULL ?
00123 0 : srch_node->ParentNode()->LangModelEdge()->Hash());
00124 unsigned int hash_bin = (edge_hash + parent_hash) % kSearchNodeHashBins;
00125
00126
00127 if (bin_size_array_[hash_bin] >= kMaxSearchNodePerBin) {
00128 return false;
00129 }
00130
00131 bin_array_[hash_bin][bin_size_array_[hash_bin]++] = srch_node;
00132
00133 return true;
00134 }
00135
00136
00137 inline SearchNode *Lookup(LangModEdge *lang_mod_edge,
00138 SearchNode *parent_node) {
00139
00140 unsigned int edge_hash = lang_mod_edge->Hash();
00141 unsigned int parent_hash = (parent_node == NULL ?
00142 0 : parent_node->LangModelEdge()->Hash());
00143 unsigned int hash_bin = (edge_hash + parent_hash) % kSearchNodeHashBins;
00144
00145
00146 for (int node_idx = 0; node_idx < bin_size_array_[hash_bin]; node_idx++) {
00147 if (lang_mod_edge->IsIdentical(
00148 bin_array_[hash_bin][node_idx]->LangModelEdge()) == true &&
00149 SearchNode::IdenticalPath(
00150 bin_array_[hash_bin][node_idx]->ParentNode(), parent_node) == true) {
00151 return bin_array_[hash_bin][node_idx];
00152 }
00153 }
00154
00155 return NULL;
00156 }
00157
00158 private:
00159
00160
00161 static const int kSearchNodeHashBins = 4096;
00162 static const int kMaxSearchNodePerBin = 512;
00163 int bin_size_array_[kSearchNodeHashBins];
00164 SearchNode *bin_array_[kSearchNodeHashBins][kMaxSearchNodePerBin];
00165 };
00166 }
00167
00168 #endif // SEARCH_NODE_H