ParsingContext ParseAndReturnBest(ParsingContext org_context) { ParsingContexts contexts = new ParsingContexts(org_context); int n_pass = 0; while (true) { n_pass++; for (int ictx = 0; ictx < contexts.Count(); ++ictx) { ParsingContext cur_context = contexts[ictx]; int ntoken = cur_context.tokens.Count; for (int iword = 0; iword < cur_context.tokens.Count; ++iword) { // ищем правила, применимые для сборки контекста вокруг слова в iword. ParsingToken headword = cur_context.tokens[iword]; for (int rule_layer = 0; rule_layer < 2; ++rule_layer) { ParsingContext new_ctx = null; /* * if( rule_layer == 0 ) * { * if( cur_context.tokens.Count > 2 ) * { * // проверяем 3-граммы * NGrams4Headword ngrams = null; * if( headword_ngrams.TryGetValue( headword.GetToken(), out ngrams ) ) * { * if( iword + 2 <= cur_context.tokens.Count - 1 ) * { * // ROOT + NODE + SUBNODE * ParsingToken node_token = cur_context.tokens[iword + 1]; * ParsingToken subnode_token = cur_context.tokens[iword + 2]; * * int score = ngrams.FindRule_Root_Node_Subnode( node_token.GetToken(), subnode_token.GetToken() ); * if( score > 0 ) * { * // создаем новый контекст * * List<ParsingToken> new_tokens = new List<ParsingToken>(); * for( int j = 0; j < cur_context.tokens.Count; ++j ) * if( j != iword + 1 && j != iword + 2 ) * new_tokens.Add( cur_context.tokens[j] ); * * Edge4Stat_Words e1 = new Edge4Stat_Words(); * e1.l_token = headword; * e1.r_token = node_token; * e1.root_index = 0; * * Edge4Stat_Words e2 = new Edge4Stat_Words(); * e2.l_token = node_token; * e2.r_token = subnode_token; * e2.root_index = 0; * * List<Edge4Stat_Words> new_edges = new List<Edge4Stat_Words>(); * new_edges.AddRange( cur_context.edges ); * new_edges.Add( e1 ); * new_edges.Add( e2 ); * * new_ctx = new ParsingContext( new_tokens, cur_context.GetScore() + score, new_edges ); * * * } * } * } * } * } * else * { */ Rules4Headword rules = null; bool head_found; if (rule_layer == 0) { head_found = headword_rules.TryGetValue(headword.GetToken(), out rules); } else { head_found = headword_sx_rules.TryGetValue(headword.GetTag(), out rules); } if (head_found) { for (int offset = -2; offset <= 2; ++offset) { if (offset == 0) { continue; } int remove_index = iword + offset; if (remove_index < 0 || remove_index >= ntoken) { continue; // слово за пределами цепочки } ParsingToken child_word = cur_context.tokens[remove_index]; int child_position = offset < 0 ? -1 : 1; int score = rules.FindRule(rule_layer == 0 ? child_word.GetToken() : child_word.GetTag(), child_position); if (score > 0) { // для непроективных дальных ребер штрафуем через уменьшение частотности int freq = score / Math.Abs(offset); // также штраф за лист, если зависимый токен не имеет веток int leaf_fine = 0; if (!cur_context.HasChildren(cur_context.tokens[remove_index].GetPosition())) { leaf_score.TryGetValue(cur_context.tokens[remove_index].GetToken(), out leaf_fine); } // зависимое слово убираем из контекста List <ParsingToken> new_tokens = new List <ParsingToken>(); for (int j = 0; j < cur_context.tokens.Count; ++j) { if (j != remove_index) { new_tokens.Add(cur_context.tokens[j]); } } Edge4Stat_Words e = new Edge4Stat_Words(); if (child_position == -1) { e.l_token = child_word; e.r_token = headword; e.root_index = 1; } else { e.r_token = child_word; e.l_token = headword; e.root_index = 0; } List <Edge4Stat_Words> new_edges = new List <Edge4Stat_Words>(); new_edges.AddRange(cur_context.edges); new_edges.Add(e); new_ctx = new ParsingContext(new_tokens, cur_context.GetScore() + freq - leaf_fine, new_edges); } } } if (new_ctx != null) { // проверим уникальность bool do_add = true; for (int i = 0; i < contexts.Count(); ++i) { if (contexts[i].GetHashCode() == new_ctx.GetHashCode()) { if (contexts[i].Equals(new_ctx)) { if (contexts[i].GetScore() < new_ctx.GetScore()) { contexts[i] = new_ctx; } do_add = false; break; } } } if (do_add) { for (int i = 0; i < contexts.new_contexts.Count(); ++i) { if (contexts.new_contexts[i].GetHashCode() == new_ctx.GetHashCode()) { if (contexts.new_contexts[i].Equals(new_ctx)) { if (contexts.new_contexts[i].GetScore() < new_ctx.GetScore()) { contexts.new_contexts[i] = new_ctx; } do_add = false; break; } } } if (do_add) { contexts.Add(new_ctx); } } } } } } if (contexts.Commit() == 0) { break; } } // теперь берем самый лучший результат ParsingContext best = contexts.GetBest(); return(best); }
public override bool Equals(object obj) { Edge4Stat_Words x = (Edge4Stat_Words)obj; return(x.l_token == l_token && x.r_token == r_token && root_index == x.root_index); }