예제 #1
1
INLINE_IF_HEADER_ONLY void MorseDecomposition::
assign ( Digraph const& digraph, 
         Components const& components ) {
  data_ . reset ( new MorseDecomposition_ );
  data_ -> components_ = components;

  uint64_t C = components . size ();
  uint64_t R = components . recurrentComponents () . size ();
  std::vector<std::vector<uint64_t>> reachability ( R );
  std::vector<uint64_t> recurrent_indices;
  for ( uint64_t i = 0; i < C; ++ i ) {
    if ( components . isRecurrent ( i ) ) {
      recurrent_indices . push_back ( i );
    }
  }
  // Proceed in cohorts of 64 recurrent components. There are ceil(R/64) cohorts
  uint64_t num_cohorts = R / 64;
  if ( R % 64 != 0 ) ++ num_cohorts; // Round up for ceiling
  std::vector<uint64_t> reach_info ( C, 0 );
  for ( uint64_t cohort = 0; cohort < num_cohorts; ++ cohort ) {
    if ( cohort > 0 ) std::fill ( reach_info.begin(), reach_info.end(), 0);
    uint64_t source = 64LL*cohort;
    // Give each recurrent component in the cohort a unique bit signature
    // e.g. the 5th component gets 000...00010000
    for ( uint64_t i = 0; i < 64; ++ i, ++ source ) {
      if ( source == R ) break;
      reach_info [ recurrent_indices [ source ] ] = (1LL << i);
    }
    // Propagate reachability information by bitwise-oring bit signatures
    uint64_t parent_comp = 0;
    for ( auto const& component : components ) { 
      for ( uint64_t u : component ) {
        std::vector<uint64_t> const& children = digraph . adjacencies ( u );
        for ( uint64_t v : children ) {
          uint64_t child_comp = components . whichComponent ( v );
          reach_info [ child_comp ] |= reach_info [ parent_comp ];
        }
      }
      ++ parent_comp;
    }
    for ( uint64_t i = 0; i < R; ++ i ) {
      uint64_t code = reach_info [ recurrent_indices [ i ] ];
      uint64_t ancestor = 64*cohort;
      while ( code != 0 ) {
        if ( code & 1 ) reachability[ancestor].push_back(i);
        code >>= 1;
        ++ ancestor;
      }
    }
  } 
  data_ -> poset_ = Poset(reachability);
  _canonicalize ();
}
예제 #2
0
파일: flow.c 프로젝트: ChiahungTai/Trilinos
void 
wbpcover (
    int n_left,		/* number of vertices on left side */
    int n_right,		/* number of vertices on right side */
    int *pointers,		/* start/stop of adjacency lists */
    int *indices,		/* adjacency list for each vertex */
    int *vweight,		/* vertex weights */
    int *psep_size,		/* returned size of separator */
    int *psep_weight,		/* returned weight of separator */
    int **psep_nodes		/* list of separator nodes */
)
{
    extern int DEBUG_COVER;	/* debug flag for this routine */
    int      *touched;		/* flags for each vertex */
    int      *resid;		/* remaining, unmatched vertex weight */
    int      *flow;		/* flow on each right->left edge */
    int      *sep_nodes;	/* list of separator nodes */
    int       sep_size;		/* returned size of separator */
    int       sep_weight;	/* returned weight of separator */
    int       nedges;		/* number of edges in bipartite graph */
    int       i, j;		/* loop counter */
    int       wleft, wright, wedges;

    void      confirm_cover();

if (DEBUG_COVER) {
    printf("-> Entering wbpcover, nleft = %d, nright = %d, 2*nedges = %d\n",
	n_left, n_right, pointers[n_left+n_right]-pointers[0]);

    wleft = wright = 0;
    wedges = 0;
    for (i = 0; i < n_left; i++) {
	wleft += vweight[i];
	for (j = pointers[i]; j < pointers[i + 1]; j++)  {
	    wedges += vweight[i] * vweight[indices[j]];
	}
    }
    for (i = n_left; i < n_left + n_right; i++) {
	wright += vweight[i];
	for (j = pointers[i]; j < pointers[i + 1]; j++)  {
	    wedges += vweight[i] * vweight[indices[j]];
	}
    }
    printf("    Corresponds to unweighted, nleft = %d, nright = %d, 2*nedges = %d\n",
	wleft, wright, wedges);
}

    nedges = pointers[n_left + n_right] - pointers[0];

    resid = smalloc((n_left + n_right) * sizeof(int));
    touched = smalloc((n_left + n_right) * sizeof(int));
    flow = smalloc((nedges + 1) * sizeof(int));


    /* Not a matching.  I can be connected to multiple nodes. */
    bpflow(n_left, n_right, pointers, indices, vweight, resid, flow, touched);

    reachability(n_left, n_right, pointers, indices, resid, flow, touched);


    /* Separator includes untouched nodes on left, touched on right. */
    /* Left separator nodes if unconnected to unmatched right node via */
    /* augmenting path, right separator nodes otherwise. */

    /* First count the separator size for malloc. */
    sep_size = 0;
    for (i = 0; i < n_left; i++) {
	if (!touched[i]) {
	    sep_size++;
	}
    }
    for (i = n_left; i < n_left + n_right; i++) {
	if (touched[i]) {
	    sep_size++;
	}
    }

    sep_nodes = smalloc((sep_size + 1) * sizeof(int));

    sep_size = sep_weight = 0;
    for (i = 0; i < n_left; i++) {
	if (!touched[i]) {
	    sep_nodes[sep_size++] = i;
	    sep_weight += vweight[i];
	}
    }
    for (i = n_left; i < n_left + n_right; i++) {
	if (touched[i]) {
	    sep_nodes[sep_size++] = i;
	    sep_weight += vweight[i];
	}
    }

    sep_nodes[sep_size] = 0;

    *psep_size = sep_size;
    *psep_weight = sep_weight;
    *psep_nodes = sep_nodes;

/* Check the answer. */
if (DEBUG_COVER) {
confirm_cover(n_left, n_right, pointers, indices, flow, vweight, resid,
		             sep_size, sep_nodes);
}

    sfree(flow);
    sfree(touched);
    sfree(resid);
}
예제 #3
0
// What are the specified player's next possible moves
LocationID *whereCanTheyGo(DracView currentView, int *numLocations,
                           PlayerID player, int road, int rail, int sea)
{

  assert(currentView != NULL);
  assert(player >= PLAYER_LORD_GODALMING && player <= PLAYER_DRACULA);
  assert(numLocations != NULL);
  
  LocationID from = currentView->playerstate[player]->current;
  assert(from >= ALICANTE && from < NUM_MAP_LOCATIONS);
  
  Round round = currentView->gameturn;
  assert(round >= 0 && round <= 366);
 
  Map europe = newMap();
  LocationID locations[NUM_MAP_LOCATIONS];
  int i,j=0;
  //USE AN ARRAY TO INDICATE PATHING TO EVERY DESTINATION
  //0 -> cannot reach, 1 -> reachable
  for ( i=0; i<NUM_MAP_LOCATIONS; i++ ) {
    locations[i] = 0;
  }
  
  
  //The reachability will mark on the array 
  if ( road ) {
    reachability(europe, from, ROAD, ONEPATH, locations);
  }
  
  if ( rail && player != PLAYER_DRACULA) {
    //Dracula can't travel by rail
    int roundmod = (round+player) % 4;
    reachability(europe, from, RAIL, roundmod, locations);
  }

  if (sea) {
    reachability(europe, from, BOAT, ONEPATH, locations);
  }

  
  //PATH FIXING FOR DRACULA
  if ( player == PLAYER_DRACULA ) {
  
    //Dracula can't move to hospital, this is a incorrect path.
    locations[ST_JOSEPH_AND_ST_MARYS] = 0;
  
    //checks if Dracula is allowed to hide
    
    //check for hide in trail
    while( i<TRAIL_SIZE ){
      if( currentView->playerstate[PLAYER_DRACULA]->trail[i] == HIDE ){
        locations[from] = 0;
      }
    }
    
    //check if at sea
    if( idToType(from) == SEA ); locations[from] = 0;
    
  }
  
  //place reachable locations into our return array
  j = 0;
  
  LocationID *reachable = malloc(sizeof (int)*NUM_MAP_LOCATIONS);
  
  //place corresponding cities (e.g. ALICANTE, ROME, MARSEILLES) into 'result'
  for (i=0; i<NUM_MAP_LOCATIONS; i++) {
    
    if ( locations[i] ) {
      reachable[j] = i;
      j++;
    }
  }
  
  *numLocations = j;

  
  destroyMap(europe);
  return reachable;
}