58 static void log_state(
const char * message,
66 static void log_state(
const char * message,
72 tprintf(
"%20s [%40s], priority %8.3f\n", message,
73 segstate.
string(), priority);
99 the_search =
new_search(chunks_record, num_joints, best_char_choices,
109 tprintf(
"\n\n\n =========== BestFirstSearch ==============\n");
117 log_state(
"BestFirstSearch", num_joints, best_state);
120 guided_state = *state;
133 tprintf(
"Breaking best_first_search on keep_going %s numstates %d\n",
134 ((keep_going) ?
"T" :
"F"), the_search->
num_states);
141 if (new_worst_priority < worst_priority) {
143 tprintf(
"Lowering WorstPriority %f --> %f\n",
144 worst_priority, new_worst_priority);
148 worst_priority = new_worst_priority;
150 expand_node(worst_priority, chunks_record, the_search);
154 log_state(
"Done with", the_search->
num_joints, &orig_state);
166 tprintf(
"\n\n\n =========== BestFirstSearch ==============\n");
184 reinterpret_cast<uinT32*>(the_search->
best_state), 2) /
207 BLOB_CHOICE_LIST *blob_choices;
208 BLOB_CHOICE_IT blob_choice_it;
214 for (i = 1; i <= search_state[0] + 1; i++) {
215 if (i > search_state[0])
218 y = x + search_state[i];
227 x, y, blamer_bundle);
229 if (blob_choices ==
NULL) {
235 blob_choice_it.set_to_list(blob_choices);
244 *char_choices += blob_choices;
247 return (char_choices);
263 bool keep_going =
true;
271 log_state(
"Evaluating state", the_search->
num_joints,
276 char_choices =
evaluate_chunks(chunks_record, chunk_groups, blamer_bundle);
278 bool updated_best_choice =
false;
279 if (char_choices !=
NULL && char_choices->
length() > 0) {
285 updated_best_choice =
289 bool replaced =
false;
290 if (updated_best_choice) {
300 #ifndef GRAPHICS_DISABLED
316 if (char_choices !=
NULL) fixpt->
clear();
319 if (char_choices !=
NULL)
delete char_choices;
339 #ifndef GRAPHICS_DISABLED
341 print_state(
"Rebuilding state", state, num_joints);
354 for (
int i = 1; i <= search_state[0]; i++) {
355 y = x + search_state[i];
364 STRING expanded_fragment_lengths_str =
"";
365 bool state_has_fragments =
false;
366 const char *fragment_lengths =
NULL;
371 if (fragment_lengths) {
373 *char_choices +=
NULL;
375 if (fragment_lengths[i] > 1) {
376 state_has_fragments =
true;
378 for (
int j = 0; j < fragment_lengths[i]; ++j) {
379 expanded_fragment_lengths_str += fragment_lengths[i];
383 for (
int i = 0; i <= search_state[0]; ++i) {
384 expanded_fragment_lengths_str += (char)1;
385 *char_choices +=
NULL;
391 const char *word_lengths_ptr =
NULL;
392 const char *word_ptr =
NULL;
393 if (state_has_fragments) {
397 word_lengths_ptr += (strlen(word_lengths_ptr)-1);
401 word_ptr += (strlen(word_ptr)-*word_lengths_ptr);
403 const char *expanded_fragment_lengths =
404 expanded_fragment_lengths_str.
string();
417 int ss_index = search_state[0];
429 for (
int char_choices_index = char_choices->
length() - 1;
430 char_choices_index >= 0;
431 --char_choices_index) {
438 int fragment_pieces = expanded_fragment_lengths[ss_index];
439 int old_choice_index = ss_index;
441 if (fragment_pieces > 1) {
442 strncpy(unichar, word_ptr, *word_lengths_ptr);
443 unichar[*word_lengths_ptr] =
'\0';
445 old_choice_index, old_choices);
446 old_choice_index = -1;
448 while (fragment_pieces > 0) {
452 x = y - search_state[ss_index--];
455 word->
best_state[char_choices_index] = true_y + 1 - true_x;
457 word, true_x, true_y, old_choice_index, ratings, old_choices);
458 if (merged_choice !=
NULL) {
462 BLOB_CHOICE_IT choice_it(current_choices);
463 for (choice_it.mark_cycle_pt(); !choice_it.cycled_list() &&
464 merged_choice->
rating() > choice_it.data()->rating();
465 choice_it.forward());
466 choice_it.add_before_stay_put(merged_choice);
469 BLOB_CHOICE_IT choice_it(current_choices);
470 for (choice_it.mark_cycle_pt(); !choice_it.cycled_list();
471 choice_it.forward()) {
473 choice_it.data()->unichar_id())) {
474 delete choice_it.extract();
477 char_choices->
set(current_choices, char_choices_index);
480 if (word_lengths_ptr !=
NULL && word_ptr !=
NULL) {
482 word_ptr -= (*word_lengths_ptr);
516 for (x = the_search->
num_joints; x > 32; x--) {
520 if (new_merit < worst_priority) {
522 log_state(
"Pushing segstate", the_search->
num_joints,
528 log_state(
"Ignore weak segstate", the_search->
num_joints,
547 if (new_merit < worst_priority) {
549 log_state(
"Pushing segstate", the_search->
num_joints,
555 log_state(
"Ignoring weak segstate", the_search->
num_joints,
584 cprintf (
"error: bad initial state in new_search\n");
598 return (this_search);
611 #ifndef GRAPHICS_DISABLED
630 FLOAT32 priority,
bool debug) {
633 if (priority < worst_priority) {
635 if (debug)
tprintf(
"Heap is Full\n");
640 entry.
Key = priority;
659 num_blobs = state[0] + 1;
663 for (i = 0; i < num_blobs; i++) {
667 if (i + 1 < num_blobs)
682 const char* expanded_fragment_lengths,
686 float certainty = 0.0f;
689 for (
int fragment_pieces = expanded_fragment_lengths[choice_index] - 1;
690 fragment_pieces >= 0; --fragment_pieces, --choice_index) {
692 BLOB_CHOICE_LIST *current_choices = old_choices->
get(choice_index);
697 fragment.
set_all(unichar, fragment_pieces,
698 expanded_fragment_lengths[choice_index],
false);
699 BLOB_CHOICE_IT choice_it(current_choices);
700 for (choice_it.mark_cycle_pt(); !choice_it.cycled_list();
701 choice_it.forward()) {
705 if (current_fragment && fragment.
equals(current_fragment)) {
706 rating += choice->
rating();
711 &min_xheight, &max_xheight);
715 if (choice_it.cycled_list()) {
717 tprintf(
"Failed to find fragment %s at index=%d\n",
723 rating, certainty, -1, -1, 0,
724 min_xheight, max_xheight,
false);
737 for (
int i = 0; i < x; i++) {
745 BLOB_CHOICE_LIST *choices =
NULL;
748 if (choice_index >= 0 && old_choices !=
NULL) {
749 choices = old_choices->
get(choice_index);
750 old_choices->
set(
NULL, choice_index);
755 if (choices ==
NULL && ratings !=
NULL) {
756 choices = ratings->
get(x, y);
762 if (choices ==
NULL) {
void delete_data_pointers()
SEARCH_RECORD * new_search(CHUNKS_RECORD *chunks_record, int num_joints, BLOB_CHOICE_LIST_VECTOR *best_char_choices, WERD_CHOICE *best_choice, WERD_CHOICE *raw_choice, STATE *state)
int hash_add(HASH_TABLE state_table, STATE *state)
const STRING & unichar_string() const
void SetWordsegRatingAdjustFactor(float f)
Set wordseg_rating_adjust_factor_ to the given value.
void set_rating(float new_val)
WIDTH_RECORD * char_widths
BLOB_CHOICE_LIST * join_blobs_and_classify(WERD_RES *word, int x, int y, int choice_index, MATRIX *ratings, BLOB_CHOICE_LIST_VECTOR *old_choices)
WERD_CHOICE * best_choice
void expand_node(FLOAT32 worst_priority, CHUNKS_RECORD *chunks_record, SEARCH_RECORD *the_search)
void IntersectRange(const T &lower1, const T &upper1, T *lower2, T *upper2)
void(* void_dest)(void *)
bool equals(const char *other_unichar, int other_pos, int other_total) const
void memfree(void *element)
void best_first_search(CHUNKS_RECORD *chunks_record, BLOB_CHOICE_LIST_VECTOR *best_char_choices, WERD_RES *word, STATE *state, DANGERR *fixpt, STATE *best_state)
BLOB_CHOICE_LIST * get_piece_rating(MATRIX *ratings, TBLOB *blobs, const DENORM &denorm, SEAMS seams, inT16 start, inT16 end, BlamerBundle *blamer_bundle)
void replace_char_widths(CHUNKS_RECORD *chunks_record, SEARCH_STATE state)
void break_pieces(TBLOB *blobs, SEAMS seams, inT16 start, inT16 end)
void set_all(const char *unichar, int pos, int total, bool natural)
STATE * new_state(STATE *oldstate)
HEAP * MakeHeap(int Size)
const UNICHARSET & getUnicharset() const
void CopyCharChoices(const BLOB_CHOICE_LIST_VECTOR &from, BLOB_CHOICE_LIST_VECTOR *to)
GenericVector< int > best_state
double wordrec_worst_state
T get(int column, int row) const
int wordrec_display_segmentations
void print_state(const char *label, STATE *state, int num_joints)
BLOB_CHOICE * rebuild_fragments(const char *unichar, const char *expanded_fragment_lengths, int choice_index, BLOB_CHOICE_LIST_VECTOR *old_choices)
UNICHAR_ID unichar_id() const
void FreeHeapData(HEAP *Heap, void_dest destructor)
GenericVector< BLOB_CHOICE_LIST * > BLOB_CHOICE_LIST_VECTOR
char window_wait(ScrollView *win)
void join_pieces(TBLOB *piece_blobs, SEAMS seams, inT16 start, inT16 end)
SEARCH_STATE bin_to_chunks(STATE *state, int num_joints)
const char * fragment_lengths() const
void display_segmentation(TBLOB *chunks, SEARCH_STATE segmentation)
void put(int column, int row, const T &thing)
static int GetChunksWidth(WIDTH_RECORD *width_record, int start_blob, int last_blob)
int wordrec_num_seg_states
int hamming_distance(uinT32 *array1, uinT32 *array2, int length)
void print_ratings_list(const char *msg, BLOB_CHOICE_LIST *ratings, const UNICHARSET ¤t_unicharset)
BLOB_CHOICE_LIST_VECTOR * best_char_choices
bool permute_characters(const BLOB_CHOICE_LIST_VECTOR &char_choices, WERD_CHOICE *best_choice, WERD_CHOICE *raw_choice)
int GetTopOfHeap(HEAP *Heap, HEAPENTRY *Entry)
const CHAR_FRAGMENT * get_fragment(UNICHAR_ID unichar_id) const
const char * string() const
inT16 evaluate_state(CHUNKS_RECORD *chunks_record, SEARCH_RECORD *the_search, DANGERR *fixpt, BlamerBundle *blamer_bundle)
FLOAT32 prioritize_state(CHUNKS_RECORD *chunks_record, SEARCH_RECORD *the_search)
static int GetChunksGap(WIDTH_RECORD *width_record, int last_chunk)
static const float kBadRating
DLLSYM void tprintf(const char *format,...)
int count_blobs(TBLOB *blobs)
void push_queue(HEAP *queue, STATE *state, FLOAT32 worst_priority, FLOAT32 priority, bool debug)
void HeapStore(HEAP *Heap, HEAPENTRY *Entry)
void delete_search(SEARCH_RECORD *the_search)
BLOB_CHOICE_LIST_VECTOR * rebuild_current_state(WERD_RES *word, STATE *state, BLOB_CHOICE_LIST_VECTOR *char_choices, MATRIX *ratings)
const STRING & unichar_lengths() const
WIDTH_RECORD * chunk_widths
inT16 max_xheight() const
EVALUATION_ARRAY last_segmentation
int hash_lookup(HASH_TABLE state_table, STATE *state)
void LogNewSegmentation(PIECES_STATE BlobWidth)
uinT8 PIECES_STATE[MAX_NUM_CHUNKS+2]
BLOB_CHOICE_LIST_VECTOR * evaluate_chunks(CHUNKS_RECORD *chunks_record, SEARCH_STATE search_state, BlamerBundle *blamer_bundle)
STATE * pop_queue(HEAP *queue)
void cprintf(const char *format,...)
HASH_TABLE new_hash_table()
void bin_to_pieces(STATE *state, int num_joints, PIECES_STATE pieces)
#define free_hash_table(table)
BlamerBundle * blamer_bundle
inT16 min_xheight() const
WERD_CHOICE * best_choice
BLOB_CHOICE_LIST * classify_blob(TBLOB *blob, const DENORM &denorm, const char *string, C_COL color, BlamerBundle *blamer_bundle)
static STRING to_string(const char *unichar, int pos, int total, bool natural)