Example #1
0
/*
 * See Figure 11-2, "The Hungarian method", page 251.
 *
 * Corresponds to lines 26--27, 38--39.
 * Called by hm_pre_search() and hm_search().
 */
static void
hm_update_slack( hm_data *hm, int z )
{
  int k, tmp;
  for EACH_U( k )
    {
      tmp = C( z, k ) - ALPHA( z ) - BETA( k );
      if ( 0 <= tmp && tmp < SLACK( k ) )
        {
          SLACK( k ) = tmp;
          /*
           * The following decrement and increment are necessary to maintain
           * the count[] array, which is not included in the original Figure
           * 11-2 implementation, and whose addition and purpose are described
           * above in hm_construct_auxiliary_graph().
           */
          if ( NHBOR( k ) != blank )
            {
              --COUNT( NHBOR( k ) );
            }
          ++COUNT( z );
          NHBOR( k ) = z;
        }
    }
}
Example #2
0
File: TERM.CPP Project: ems/TMS
void MatchGraph::SET_MATCH_BOUNDS ()
{
    long del;

    for (v=1; v <= U; ++v) {
	if (LINK[(int)v] < 0 || BASE[(int)v] != v) {
	    NEXT_D[(int)v] = LAST_D;
	    continue;
	}
	LINK[(int)v] = -LINK[(int)v];
	i = v;
	while (i != DUMMYVERTEX) {
	    Y[(int)i] -= DELTA;
	    i = NEXTVTX[(int)i];
	}
	f = MATE[(int)v];
	if (f != DUMMYEDGE) {
	    i = BEND(f);
	    del = SLACK(f);
	    while (i != DUMMYVERTEX) {
		Y[(int)i] -= del;
		i = NEXTVTX[(int)i];
	    }
	}
	NEXT_D[(int)v] = LAST_D;
    }
}
Example #3
0
/*
 * This function is for debugging purposes. It prints the algorithm's internal
 * state in a format similar to that of Example 11.1 (The matrix form of the
 * Hungarian method) beginning on page 252.
 *
 * The formatted output coded here is intended for small numbers.
 */
static void
hm_print( hm_data *hm )
{
  int i, j, k;
  printf( "\n a\\b |" );
  for EACH_U( j )
    {
      printf( "%3d ", BETA( j ) );
    }
  printf( "mate exposed label\n" );
  printf( "-----+" );
  for EACH_U( j )
    {
      printf( "----" );
    }
  printf( "------------------\n" );
  for EACH_V( i )
    {
      printf( "     |\n %3d |", ALPHA( i ) );
      for EACH_U( j )
        {
          printf( "%3d ", C( i, j ) );
        }
      printf( "%4d %7d %5d\n", MATE( i ), EXPOSED( i ), LABEL( i ) );
    }
  printf( "\nslack" );
  for EACH_U( j )
    {
      printf( " %3d", SLACK( j ) == INT_MAX ? -1 : SLACK( j ) );
    }
  printf( "\nnhbor" );
  for EACH_U( j )
    {
      printf( " %3d", NHBOR( j ) );
    }
  printf( "\n\nA = { " );
  for ( k = 0; k < A.size; ++k )
    {
      printf( "(%d,%d) ", A.data[ k ].x, A.data[ k ].y );
    }
  printf( "}\nQ = { " );
  for ( k = 0; k < Q.size; ++k )
    {
      printf( "%d ", Q.data[ k ] );
    }
  printf( "}\n\n" );
}
Example #4
0
/*
 * See Figure 11-2, "The Hungarian method", page 251.
 *
 * Corresponds to lines 12--17.
 */
static void
hm_construct_auxiliary_graph( hm_data *hm )
{
  int i, j;
  A.size = 0;
  for EACH_V( i )
    {
      EXPOSED( i ) = blank;
      LABEL( i ) = blank;
      /*
       * The following data structure is not included in the Figure 11-2
       * pseudo-code implementation. It has been added to account for
       * "labeling" on certain vertices described within Example 11.1 that
       * would otherwise be missing from the Figure 11-2 implementation.
       *
       * count[v] for any v \in V is equal to the size of the set
       * { u \in U : nhbor[u] = v }. When this set is non-empty, v is
       * considered to be "labeled". The use of this new data structure is
       * only to complete the conditional check on "labeled" statuses when
       * updating alpha within "procedure modify".
       */
      COUNT( i ) = 0;
    }
  for EACH_U( j )
    {
      SLACK( j ) = INT_MAX;
      /*
       * The following initialization of nhbor[] is necessary for proper usage
       * of the count[] array, whose addition and purpose is described above.
       */
      NHBOR( j ) = blank;
    }
  for EACH_V( i )
    {
      for EACH_U( j )
        {
          if ( ALPHA( i ) + BETA( j ) == C( i, j ) )
            {
              if ( MATE( j ) == blank )
                {
                  EXPOSED( i ) = j;
                }
              else if ( i != MATE( j ) )
                {
                  add_arc( &A, i, MATE( j ) );
                }
            }
        }
    }
}
Example #5
0
/*
 * See Figure 11-2, "The Hungarian method", page 252.
 *
 * Corresponds to "procedure modify".
 */
static bool
hm_modify( hm_data *hm )
{
  int i, j, theta_one;
  /*
   * Determine theta_one.
   */
  theta_one = INT_MAX;
  for EACH_U( j )
    {
      if ( 0 < SLACK( j ) && SLACK( j ) < theta_one )
        {
          theta_one = SLACK( j );
        }
    }
  theta_one /= 2;
  /*
   * Update the dual variable alpha.
   */
  for EACH_V( i )
    {
      /*
       * The following conditional expression has been changed from its form
       * in Figure 11-2. Here, an additional check on the count[] array is
       * performed to account for a certain type of "labeling" that is
       * mentioned in the Example 11.1 walk-through but is omitted from the
       * Figure 11-2 implementation.
       *
       * See the comments provided near the initialization of count[] in the
       * function hm_construct_auxiliary_graph().
       */
      if ( LABEL( i ) != blank || COUNT( i ) > 0 )
        {
          ALPHA( i ) += theta_one;
        }
      else
        {
          ALPHA( i ) -= theta_one;
        }
    }
  /*
   * Update the dual variable beta.
   */
  for EACH_U( j )
    {
      if ( SLACK( j ) == 0 )
        {
          BETA( j ) -= theta_one;
        }
      else
        {
          BETA( j ) += theta_one;
        }
    }
  /*
   * Update slack and check for new admissible edges.
   */
  for EACH_U( j )
    {
      if ( SLACK( j ) > 0 )
        {
          SLACK( j ) -= 2 * theta_one;
          if ( SLACK( j ) == 0 )
            {
              if ( MATE( j ) == blank )
                {
                  EXPOSED( NHBOR( j ) ) = j;
                  hm_augment( hm, NHBOR( j ) );
                  return false; /* goto endstage */
                }
              else
                {
                  /*
                   * The following statement corresponds to a pseudo-code
                   * command that should be removed from the else-clause of
                   * the modify procedure in Figure 11-2.
                   *
                   * LABEL( MATE( j ) ) = NHBOR( j );
                   *
                   * The inclusion of the above statement causes the arc
                   * added in one of the next statements to never be considered
                   * in following "search" sub-stages during this stage, and it
                   * partially duplicates what would happen in these sub-stages
                   * if the arc were to be considered there. The result of
                   * inclusion is (often) non-optimality of the algorithm's
                   * output.
                   */
                  /*
                   * The next statement corresponds to a pseudo-code command
                   * (in the same else-clause) that should be modified
                   * slightly. In Figure 11-2, this command "pushes" mate[ u ]
                   * into Q when it should be "pushing" nhbor[ u ] instead.
                   * This is because the purpose of this command is to ensure
                   * that the soon-to-be-added arc will be considered in the
                   * next "search" sub-stage, and consideration is dependent
                   * upon the arc-tail, not the arc-head.
                   */
                  stack_push( &Q, NHBOR( j ) ); /* Note modification */
                  add_arc( &A, NHBOR( j ), MATE( j ) );
                }
            }
        }
    }
  return true;
}