Exemplo n.º 1
0
void
read_basis (const char *filename, wfa_t *wfa)
/*
 *  Read WFA initial basis 'filename' and fill 'wfa' struct.
 *
 *  No return value.
 *
 *  Side effects:
 *	wfa->into, wfa->weights, wfa->final_distribution, wfa->basis_states
 *	wfa->domain_type wfa->wfainfo->basis_name, are filled with the
 *	values of the WFA basis.
 */
{
   FILE	*input;				/* ASCII WFA initial basis file */

   assert (filename && wfa);

   if (!wfa->wfainfo->basis_name ||
       !streq (wfa->wfainfo->basis_name, filename))
   {
      if (wfa->wfainfo->basis_name)
	 Free (wfa->wfainfo->basis_name);
      wfa->wfainfo->basis_name = strdup (filename);
   }
   
   if (get_linked_basis (filename, wfa))
      return;				/* basis is linked with excecutable */
   
   /*
    *  Check whether 'wfa_name' is a regular ASCII WFA initial basis file
    */
   {
      char magic [MAXSTRLEN];		/* WFA magic number */

      if (!(input = open_file (filename, "FIASCO_DATA", READ_ACCESS)))
	 file_error(filename);
      
      if (fscanf (input, MAXSTRLEN_SCANF, magic) != 1)
	 error ("Format error: ASCII FIASCO initial basis file %s", filename);
      else if (strneq (FIASCO_BASIS_MAGIC, magic))
	 error ("Input file %s is not an ASCII FIASCO initial basis!",
		filename);
   }
   
   /*
    *  WFA ASCII format:
    *
    *  Note: State 0 is assumed to be the constant function f(x, y) = 128.
    *        Don't define any transitions of state 0 in an initial basis. 
    *
    *  Header:
    *   type		|description
    *	----------------+-----------
    *   string		|MAGIC Number "Wfa"
    *	int		|Number of basis states 'N'
    *	bool_t-array[N]	|use vector in linear combinations,
    *			|0: don't use vector (auxilliary state)
    *			|1: use vector in linear combinations
    *	float-array[N]	|final distribution of every state
    *
    *  Transitions:
    *
    *      <state 1>			current state
    *      <label> <into> <weight>	transition 1 of current state
    *      <label> <into> <weight>	transition 2 of current state
    *      ...
    *      <-1>				last transition marker
    *      <state 2>
    *      ...
    *      <-1>				last transition marker
    *      <state N>
    *      ...
    *
    *      <-1>				last transition marker
    *      <-1>				last state marker
    */
   {
      unsigned state;

      if (fscanf (input ,"%u", &wfa->basis_states) != 1)
	 error ("Format error: ASCII FIASCO initial basis file %s", filename);

      /*
       *  State 0 is assumed to be the constant function f(x, y) = 128.
       */
      wfa->domain_type [0]        = USE_DOMAIN_MASK; 
      wfa->final_distribution [0] = 128;
      wfa->states 		  = wfa->basis_states;
      wfa->basis_states++;

      append_edge (0, 0, 1.0, 0, wfa);
      append_edge (0, 0, 1.0, 1, wfa);
   
      for (state = 1; state < wfa->basis_states; state++)
	 wfa->domain_type [state]
	    = read_int (input) ? USE_DOMAIN_MASK : AUXILIARY_MASK;

      for (state = 1; state < wfa->basis_states; state++)
	 wfa->final_distribution[state] = read_real (input);

      /*
       *  Read transitions
       */
      for (state = 1; state < wfa->basis_states; state++)
      {
	 unsigned domain;
	 int      label;
	 real_t   weight;

	 if (read_int (input) != (int) state)
	    error ("Format error: ASCII FIASCO initial basis file %s",
		   filename);

	 while((label = read_int (input)) != -1)
	 {
	    domain = read_int (input);
	    weight = read_real (input);
	    append_edge (state, domain, weight, label, wfa);
	 }
      }
   }
   
   fclose (input);
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
	AllPoints all_points;
	EdgesPath path;
	all_points.number_of_points = 0;
	path.size = 0;
	
#ifdef DRAW_RESULT
	{
		const int xBound = 800;
		const int yBound = 600;

		initializeWindow(argc, argv, xBound, yBound);
	}
#endif // #ifdef DRAW_RESULT

	if (argc >= 2) {
		read_points_from_file(argv[1], &all_points);
	} else {
#ifdef DRAW_RESULT
		read_from_screen(&all_points);
#endif // #ifdef DRAW_RESULT
	}

	qsort(all_points.points, all_points.number_of_points, sizeof(Point), compare_points);
	
	{
		const int hk_subtasks_count = (all_points.number_of_points / MAX_HELD_KARP_POINTS) + (all_points.number_of_points % MAX_HELD_KARP_POINTS ? 1 : 0);
		Path *pathes = calloc(hk_subtasks_count, sizeof(Path));
		int start_point = 0;
		int current_hk_part_index = 0;
		for (current_hk_part_index = 0; current_hk_part_index < hk_subtasks_count; ++current_hk_part_index) {
			int size = MAX_HELD_KARP_POINTS;
			int i = 0;
			Path partial_path;
			if (current_hk_part_index + 2 == hk_subtasks_count) {
				size = (all_points.number_of_points - start_point) / 2;
			}
			if (current_hk_part_index + 1 == hk_subtasks_count) {
				size = all_points.number_of_points - start_point;
			}
			partial_path = build_held_karp_path(all_points.points + start_point, size);
			for (i = 0; i < size; ++i) {
				partial_path.points[i] += start_point;
			}

			pathes[current_hk_part_index] = partial_path;
			start_point += size;
		}

		// sub optimally join partial pathes
		{
			// in first path we do not have any edges that are forbidden for removal to join HK-loops. 
			int forbidden_endge_start = -1;
			for (current_hk_part_index = 1; current_hk_part_index < hk_subtasks_count; ++current_hk_part_index) {
				float best_cost = FLT_MAX;
				int prev = 0;
				
				int prev_loop_edge_start = -1;
				int curr_loop_edge_start = -1;
				Edge connecting_edge_1;
				Edge connecting_edge_2;
				// for each allowed edge from previous loop
				for (prev = 0; prev < pathes[current_hk_part_index - 1].size; ++prev) {
					int curr = 0;
					const int prev_start_index = pathes[current_hk_part_index - 1].points[prev];
					const int prev_end_index = pathes[current_hk_part_index - 1].points[(prev + 1) % pathes[current_hk_part_index - 1].size];
					const Point prev_start = all_points.points[prev_start_index];
					const Point prev_end = all_points.points[prev_end_index];

					if (forbidden_endge_start == prev) {
						continue;
					}
					 // for each edge from current loop
					for (curr = 0; curr < pathes[current_hk_part_index].size; ++curr) {
						// check if removing both edges and connecting loops in this points will get optimal result

						const int curr_start_index = pathes[current_hk_part_index].points[curr];
						const int curr_end_index = pathes[current_hk_part_index].points[(curr + 1) % pathes[current_hk_part_index].size];
						const Point curr_start = all_points.points[curr_start_index];
						const Point curr_end = all_points.points[curr_end_index];
						const float removal_cost = distance(prev_start, prev_end) + distance(curr_start, curr_end);
						const float start_start_connect_cost = distance(prev_start, curr_start) + distance(prev_end, curr_end);
						const float start_end_connect_cost = distance(prev_start, curr_end) + distance(prev_end, curr_start);
						if (best_cost > start_start_connect_cost - removal_cost) {
							best_cost = start_start_connect_cost - removal_cost;
							
							prev_loop_edge_start = prev;
							curr_loop_edge_start = curr;

							connecting_edge_1.start = prev_start_index;
							connecting_edge_1.end = curr_start_index;

							connecting_edge_2.start = prev_end_index;
							connecting_edge_2.end = curr_end_index;
						}
						if (best_cost > start_end_connect_cost - removal_cost) {
							best_cost = start_end_connect_cost - removal_cost;

							prev_loop_edge_start = prev;
							curr_loop_edge_start = curr;

							connecting_edge_1.start = prev_start_index;
							connecting_edge_1.end = curr_end_index;

							connecting_edge_2.start = prev_end_index;
							connecting_edge_2.end = curr_start_index;
						}
					}
				}
				
				for (prev = 0; prev < pathes[current_hk_part_index - 1].size; ++prev) {
					// append all edges from previous loop except forbidden and selected for removal
					const int prev_start_index = pathes[current_hk_part_index - 1].points[prev];
					const int prev_end_index = pathes[current_hk_part_index - 1].points[(prev + 1) % pathes[current_hk_part_index - 1].size];
					if (forbidden_endge_start == prev || prev_loop_edge_start == prev) {
						continue;
					}
					append_edge(&path, prev_start_index, prev_end_index);
				}
				
				{
					// append two extra edges added instead of removed ones
					append_edge(&path, connecting_edge_1.start, connecting_edge_1.end);
					append_edge(&path, connecting_edge_2.start, connecting_edge_2.end);
				}
				forbidden_endge_start = curr_loop_edge_start;
			}

			{
				int prev = 0;
				for (prev = 0; prev < pathes[hk_subtasks_count - 1].size; ++prev) {
					// append all edges from last loop except forbidden one
					const int prev_start_index = pathes[hk_subtasks_count - 1].points[prev];
					const int prev_end_index = pathes[hk_subtasks_count - 1].points[(prev + 1) % pathes[hk_subtasks_count - 1].size];
					if (forbidden_endge_start == prev) {
						continue;
					}
					append_edge(&path, prev_start_index, prev_end_index);
				}
			}
		}

		free(pathes);
	}

#ifdef DRAW_RESULT
	// run message loop with displaying points and found path
	display_results(&all_points, &path);
#endif // #ifdef DRAW_RESULT
}
Exemplo n.º 3
0
Arquivo: nd.c Projeto: ai8rahim/Fiasco
static unsigned
decode_nd_tree (wfa_t *wfa, bitfile_t *input)
/*
 *  Read 'wfa' prediction tree of given 'input' stream.
 *
 *  No return value.
 *
 *  Side effects:
 *	'wfa->into' is filled with the decoded values
 */
{
   lqueue_t *queue;			/* queue of states */
   int       next, state;		/* state and its current child */
   unsigned  total = 0;			/* total number of predicted states */
   u_word_t  sum0, sum1;		/* Probability model */
   u_word_t  code;			/* The present input code value */
   u_word_t  low;			/* Start of the current code range */
   u_word_t  high;			/* End of the current code range */

   /*
    *  Initialize arithmetic decoder
    */
   code = get_bits (input, 16);
   low  = 0;
   high = 0xffff;
   sum0 = 1;
   sum1 = 11;

   queue = alloc_queue (sizeof (int));
   state = wfa->root_state;
   queue_append (queue, &state);

   /*
    *  Traverse the WFA tree in breadth first order (using a queue).
    */
   while (queue_remove (queue, &next))
   {
      unsigned label;

      if (wfa->level_of_state [next] > wfa->wfainfo->p_max_level + 1) 
      {
	 /*
	  *  Nondetermismn is not allowed at levels larger than
	  *  'wfa->wfainfo->p_max_level'.
	  */
	 for (label = 0; label < MAXLABELS; label++)
	    if (ischild (state = wfa->tree [next][label]))
	       queue_append (queue, &state); /* continue with childs */
      }
      else if (wfa->level_of_state [next] > wfa->wfainfo->p_min_level)
      {
	 for (label = 0; label < MAXLABELS; label++)
	    if (ischild (state = wfa->tree [next][label]))
	    {
	       unsigned count;		/* Current interval count */
	       unsigned range;		/* Current interval range */
	       
	       count = (((code - low) + 1) * sum1 - 1) / ((high - low) + 1);
	       if (count < sum0)
	       {
		  /*
		   *  Decode a '0' symbol
		   *  First, the range is expanded to account for the
		   *  symbol removal.
		   */
		  range = (high - low) + 1;
		  high = low + (u_word_t) ((range * sum0) / sum1 - 1 );
		  RESCALE_INPUT_INTERVAL;
		  /*
		   *  Update the frequency counts
		   */
		  sum0++;
		  sum1++;
		  if (sum1 > 50) /* scale the symbol frequencies */
		  {
		     sum0 >>= 1;
		     sum1 >>= 1;
		     if (!sum0)
			sum0 = 1;
		     if (sum0 >= sum1)
			sum1 = sum0 + 1;
		  }
		  if (wfa->level_of_state [state] > wfa->wfainfo->p_min_level)
		     queue_append (queue, &state);
	       }
	       else
	       {
		  /*
		   *  Decode a '1' symbol
		   *  First, the range is expanded to account for the
		   *  symbol removal.
		   */
		  range = (high - low) + 1;
		  high = low + (u_word_t) ((range * sum1) / sum1 - 1);
		  low  = low + (u_word_t) ((range * sum0) / sum1);
		  RESCALE_INPUT_INTERVAL;
		  /*
		   *  Update the frequency counts
		   */
		  sum1++;
		  if (sum1 > 50) /* scale the symbol frequencies */
		  {
		     sum0 >>= 1;
		     sum1 >>= 1;
		     if (!sum0)
			sum0 = 1;
		     if (sum0 >= sum1)
			sum1 = sum0 + 1;
		  }
		  append_edge (next, 0, -1, label, wfa);
		  total++;
	       }