/** * [Angelo::bfs Setup shooting strategy from the forest adjacency.] * @return [Whether the planning was successful or the algorithm failed.] */ bool Angelo::bfs() { // Local variables int exploration_set, complement_adjacency; // Allocate storage std::bitset<MAXSIZE> explored; std::vector<int> target_tree( MAXSIZE ), parent_set( MAXSIZE ); // Reset shot sequence shot_sequence.clear(); // Begin from the first node (explore all others) const int all_nodes_but_first = (1 << n_nodes) - 1; // Initialize unexplored queue std::list<int> unexplored; unexplored.push_back(all_nodes_but_first); // Explore nodes while( !unexplored.empty() ) { // Pull new exploration set from queue if( (exploration_set = unexplored.front()) == 0 ) break; unexplored.pop_front(); // Explore each node of the set for ( int i = 0, current_node = 1; i < n_nodes; ++i, current_node = current_node << 1 ) if( exploration_set & current_node ) { // All nodes of the set, except the current one const int node_complement = exploration_set ^ current_node; // Create a new set with the adjacency of the complement complement_adjacency = 0; // Iterate on each node of the complement, adding its adjacency for ( int j = 0, other_node = 1; j < n_nodes; ++j, other_node = other_node << 1 ) if( node_complement & other_node) complement_adjacency |= adjacency[j]; // Remember the current node, the current complement adjacency, and // the link between this new set and the current exploration set. if( !explored[complement_adjacency] ) { explored[complement_adjacency] = true; parent_set[complement_adjacency] = exploration_set; target_tree[complement_adjacency] = i; unexplored.push_back(complement_adjacency); } } } // Impossible if( exploration_set != 0 ) return false; // Rollback through the parent sets, and stack the corresponding target trees while( exploration_set != all_nodes_but_first ) { shot_sequence.push_back(target_tree[exploration_set]); exploration_set = parent_set[exploration_set]; } // Report success return true; }
inline ttree_permute_iterator<Iterator> target_tree_permute(Iterator it, const target_body_iterator& tbi) const { return target_tree().body_permute(it, tbi); }