示例#1
0
/*
 * See Figure 10-3, "The bipartite matching algorithm", page 224.
 *
 * Corresponds to "procedure augment(v)",
 * but is iterative instead of recursive.
 */
static void
hm_augment( hm_data *hm, int v )
{
  while ( LABEL( v ) != blank )
    {
      EXPOSED( LABEL( v ) ) = MATE( v );
      MATE( v ) = EXPOSED( v );
      MATE( EXPOSED( v ) ) = v;
      v = LABEL( v );
    }
  MATE( v ) = EXPOSED( v );
  MATE( EXPOSED( v ) ) = v;
}
示例#2
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 ) );
                }
            }
        }
    }
}
示例#3
0
/*
 * See Figure 11-2, "The Hungarian method", page 251.
 *
 * Corresponds to lines 29--41.
 */
static bool
hm_search( hm_data *hm )
{
  int i, j, z;
  while ( Q.size != 0 )
    {
      i = stack_pop( &Q );
      for ( z = 0; z < A.size; ++z )
        {
          if ( A.data[ z ].x == i )
            {
              j = A.data[ z ].y;
              if ( LABEL( j ) == blank )
                {
                  LABEL( j ) = i;
                  if ( EXPOSED( j ) != blank )
                    {
                      hm_augment( hm, j );
                      return false; /* goto endstage */
                    }
                  /*
                   * The following instruction is listed just before the prior
                   * conditional in Figure 11-2. Here, it is relocated simply
                   * because its execution would serve no purpose if the prior
                   * conditional executes.
                   */
                  stack_push( &Q, j );
                  hm_update_slack( hm, j );
                }
            }
        }
    }
  return true;
}
示例#4
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" );
}
示例#5
0
/*
 * See Figure 11-2, "The Hungarian method", page 251.
 *
 * Corresponds to lines 19--28.
 */
static bool
hm_pre_search( hm_data *hm )
{
  int i;
  Q.size = 0;
  for EACH_V( i )
    {
      if ( MATE( i ) == blank )
        {
          if ( EXPOSED( i ) != blank )
            {
              hm_augment( hm, i );
              return false; /* goto endstage */
            }
          stack_push( &Q, i );
          LABEL( i ) = blank;
          hm_update_slack( hm, i );
        }
    }
  return true;
}
示例#6
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;
}
示例#7
0
bool Board::isCovered(int row, int column) { return ! EXPOSED(row, column); }