Пример #1
0
void M2MFstAligner::_conditional_max( bool y_given_x ){
  /*
    Compute the conditional distribution, P(Y|X) using the WFST paradigm.
    This is bassed on the approach from Shu and Hetherington 2002.
    It is assumed that all WFSTs and operations use the Log semiring.

    Given: 
           FST1 = P(X,Y)
    Compute:
           FST2 = P(X) 
             := Map_inv(Det(RmEps(Proj_i(FST1))))
           FST3 = P(Y|X)
             := Compose(FST2,FST1)

    Proj_i:  project on input labels
    RmEps:   epsilon removal
    Det:     determinize
    Map_inv: invert weights

    Notes: An analogous process may be used to compute P(X|Y).  In this
      case one would project on OUTPUT labels - Proj_o, and reverse the
      composition order to Compose(FST1,FST2).

    Future work:
      What we are doing here in terms of *generating* the JOINT fst each
      time is really just a dumb hack.  We *should* encode the model in an
      FST and encode the individual lattices, rather than doing the hacky
      manual label encoding that we currently rely on.
  */

  //Joint distribution that we start with
  VectorFst<LogArc>* joint  = new VectorFst<LogArc>();
  SymbolTable* misyms = new SymbolTable("misyms");
  SymbolTable* mosyms = new SymbolTable("mosyms");
  joint->AddState();
  joint->AddState();
  joint->SetStart(0);
  joint->SetFinal(1,LogArc::Weight::One());
  map<LogArc::Label,LogWeight>::iterator it;
  for( it=prev_alignment_model.begin(); it != prev_alignment_model.end(); it++ ){
    string isym = isyms->Find((*it).first); 
    vector<string> io = tokenize_utf8_string( &isym, &s1s2_sep );
    LogArc arc( misyms->AddSymbol(io[0]), mosyms->AddSymbol(io[1]), (*it).second, 1 );
    joint->AddArc( 0, arc );
  }
  //VectorFst<LogArc>* joint  = new VectorFst<LogArc>();
  //Push<LogArc,REWEIGHT_TO_FINAL>(*_joint, joint, kPushWeights);
  //joint->SetFinal(1,LogWeight::One());
  joint->Write("m2mjoint.fst");
  //BEGIN COMPUTE MARGINAL P(X)  
  VectorFst<LogArc>* dmarg;
  if( y_given_x )
    dmarg = new VectorFst<LogArc>(ProjectFst<LogArc>(*joint, PROJECT_INPUT));
  else
    dmarg = new VectorFst<LogArc>(ProjectFst<LogArc>(*joint, PROJECT_OUTPUT));

  RmEpsilon(dmarg);
  VectorFst<LogArc>* marg = new VectorFst<LogArc>();
  Determinize(*dmarg, marg);
  ArcMap(marg, InvertWeightMapper<LogArc>());

  if( y_given_x )
    ArcSort(marg, OLabelCompare<LogArc>());
  else
    ArcSort(marg, ILabelCompare<LogArc>());
  //END COMPUTE MARGINAL P(X)
  marg->Write("marg.fst");

  //CONDITIONAL P(Y|X)
  VectorFst<LogArc>* cond = new VectorFst<LogArc>();
  if( y_given_x )
    Compose(*marg, *joint, cond);
  else
    Compose(*joint, *marg, cond);
  //cond now contains the conditional distribution P(Y|X)
  cond->Write("cond.fst");
  //Now update the model with the new values
  for( MutableArcIterator<VectorFst<LogArc> > aiter(cond, 0); !aiter.Done(); aiter.Next() ){
    LogArc arc = aiter.Value();
    string lab = misyms->Find(arc.ilabel)+"}"+mosyms->Find(arc.olabel);
    int   labi = isyms->Find(lab);
    alignment_model[labi]      = arc.weight;
    prev_alignment_model[labi] = LogWeight::Zero();
  }
  delete joint, marg, cond, dmarg;
  delete misyms, mosyms;
  return;
}
Пример #2
0
	Move ChooseMove(const GameState& game, unsigned iterations)
	{
		std::mt19937 r(GlobalRandomDevice());
		MCTSNode root;

		MCTSNode* store = (MCTSNode*)malloc(sizeof(MCTSNode) * iterations);
		MCTSNode* store_head = store;

		for (unsigned iter = 0; iter < iterations; ++iter)
		{
			GameState sim_state = Determinize(game, r);

			// Selection
			MCTSNode* node = &root;
			while (!node->HasUntriedMoves(sim_state) && node->HasChildren())
			{
				MCTSNode* next_node = node->UCTSelectChild(sim_state);

				// Update availability
				for (MCTSNode* avail_node = node->m_child; avail_node; avail_node = avail_node->m_siblings)
				{
					if (sim_state.m_possible_moves.Contains(avail_node->m_move))
					{
						avail_node->m_availability++;
					}
				}

				sim_state.ProcessMove(next_node->m_move);
				node = next_node;
			}
		
			// Expansion
			if (node->HasUntriedMoves(sim_state))
			{
				Move m = node->ChooseRandomUntriedMove(sim_state, r);
				for (MCTSNode* avail_node = node->m_child; avail_node; avail_node = avail_node->m_siblings)
				{
					if (sim_state.m_possible_moves.Contains(avail_node->m_move))
					{
						avail_node->m_availability++;
					}
				}

				sim_state.ProcessMove(m);
				node = node->AddChild(m, store_head);
				store_head += 1;
				node->m_availability++;
			}

			// Simulation
			sim_state.PlayOutRandomly(r);
		
			// Backpropagation
			bool won = sim_state.m_winner == (Winner)game.m_active_player_index;
			while (node)
			{
				node->m_visits++;
				if (won) node->m_wins++;

				node = node->m_parent;
			}
		}

		MCTSNode* best_node = nullptr;
		uint32_t best_visits = 0;

		for (MCTSNode* node = root.m_child; node; node = node->m_siblings)
		{
			if (node->m_visits > best_visits)
			{
				best_visits = node->m_visits;
				best_node = node;
			}
		}

		Move m = best_node->m_move;
		free(store);
		return m;
	}