示例#1
0
void Sudoku::solve_colorability_style()
{
  if (!this->status_ok)
  {
    throw std::logic_error("Puzzle has not been initialized");
  }

  color_node(this->grid);
}
示例#2
0
bool Sudoku::color_node(Grid& cur_grid, std::size_t cur_x, std::size_t cur_y)
{
  std::size_t unknown_x, unknown_y;

  //check if we can keep coloring nodes, or if we need to stop and assess the generated board
  if (find_unknown(cur_grid, cur_x, cur_y, unknown_x, unknown_y))
  {
    std::uint_fast64_t colors = Validator::good_colors(cur_grid, unknown_x, unknown_y);

    //clone the existing game board
    Grid new_grid(cur_grid);

    for (int i = 1; i <= (int)cur_grid.n(); i++)
    {
      //can we use this color here?
      if ((colors & (1 << (i - 1))) != 0)
      {
        //color the node
        new_grid.set(unknown_x, unknown_y, i);

        //if the coloring was successful, then return the colored graph indicate success
        if (color_node(new_grid, unknown_x, unknown_y))
        {
          cur_grid = new_grid;
          return true;
        }
      }
    }

    //we couldn't find a coloring :(
    return false;
  }
  else
  {
    //the board is completely colored, so we can't color any more nodes, but is it a valid coloring?
    return Validator::is_good_board(cur_grid);
  }
}
void plassman_p_processors(int pid, int p, MPI_Comm * comm_workers) {
	int nodes;
	int * madjacency;
	int * all_weights, i, j;
	int my_nodes, nodes_per_block, max_nodes_per_block, n_locals;
	int * send_to, * n_wait, * n_send, * locals;
	int * receive_from, ended = 0;
	int * colors, my_colors[2], tmp = 0;

	MPI_Request req;
	MPI_Status status;
	PblSet * psetcolors = (PblSet *) pblSetNewHashSet();
	int good = 1;	

	MPI_Recv( &nodes, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status );

	nodes_per_block = get_nodes_per_process(nodes, p);
	max_nodes_per_block = nodes - (p - 1) * nodes_per_block;
	
	//printf("[rank %d] nodes: %d | nodes_per_block: %d | max_nodes_per_block: %d\n", pid, nodes, nodes_per_block, max_nodes_per_block);

	if (pid < p)
		my_nodes = nodes_per_block;
	else
		my_nodes = max_nodes_per_block;
		
	n_locals = 0;
	//printf("[rank %d] nodes: %d\n", pid, nodes);

	n_wait = (int*) malloc( my_nodes * sizeof(int) );
	n_send = (int*) malloc( my_nodes * sizeof(int) );
	send_to = (int*) malloc( my_nodes*(nodes-1) * sizeof(int) );
	receive_from = (int*) malloc( my_nodes*(nodes-1) * sizeof(int) );
	
	colors = (int*) malloc( (nodes) * sizeof(int) );
	all_weights = (int*) malloc( (nodes) * sizeof(int) );
	madjacency = (int*) malloc( nodes * my_nodes * sizeof(int) );
	locals = (int*) malloc( my_nodes * sizeof(int) );
	MPI_Recv( madjacency, nodes*my_nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status );

	//defenir peso random
	srand( time( NULL ) / pid );
	for (i = 0; i < my_nodes; i++){
		all_weights[(pid-1)*nodes_per_block +i] = rand();
		n_wait[i] = 0;
		n_send[i] = 0;
		//print-f("[rank %d] weight[%d]: %d\n", pid, (pid-1)*nodes_per_block + i, all_weights[(pid-1)*nodes_per_block +i]);
	}
		

	//printf("[rank %d] will exchange weights\n", pid);
	//exchange all weights
	for ( i = 0; i < p-1; i++)
		MPI_Bcast( &all_weights[i*nodes_per_block], nodes_per_block, MPI_INT, i, *comm_workers );
	MPI_Bcast( &all_weights[(p-1)*nodes_per_block], max_nodes_per_block, MPI_INT, p-1, *comm_workers );
	
	//printf("[rank %d] weights exchanged\n", pid);

	fflush(stdout);

	for ( i = 0; i < my_nodes; i++ ) {
		for (j = 0; j < nodes; j++) {

			if ((pid-1)*nodes_per_block + i == j || madjacency[i*nodes + j] <= 0 || pid == get_pid_of_node(j, nodes, p))
				continue;

			if ( all_weights[(pid-1)*nodes_per_block + i] < all_weights[j] ) {
				receive_from[i*(nodes-1) + n_wait[i]] = j;
				n_wait[i]++;
			} 
			else {
				send_to[i*(nodes-1) + n_send[i]] = j;
				n_send[i]++;
			}
		}

		locals[i] = is_local( (pid-1)*nodes_per_block+i, i, madjacency, nodes, p);
		if (locals[i]) {
			n_locals++;
			continue;
		}

		//printf("[rank %d] vertice[%d]: wait %d | send %d\n", pid, (pid-1)*nodes_per_block+i, n_wait[i], n_send[i]);
		if(n_wait[i] == 0 ){
			colors[(pid-1)*nodes_per_block+i] = color_node(i, pid,nodes_per_block, madjacency, colors, psetcolors, nodes);
			ended++;
			
			my_colors[0] = (pid-1)*nodes_per_block+i;
			my_colors[1] = colors[my_colors[0]];
			for (j = 0; j < n_send[i]; j++) {
				//printf("[rank %d] send color %d do vertice %d para o %d do rank %d\n", pid, my_colors[1], (pid-1)*nodes_per_block+i,
				//		send_to[i*(nodes-1) +j], get_pid_of_node(send_to[i*(nodes-1) +j],nodes,p));

				MPI_Isend(my_colors, 2, MPI_INT, get_pid_of_node(send_to[i*(nodes-1) + j], nodes, p), TAG, MPI_COMM_WORLD, &req);
			}
		}
	}
	
	//print_adjacency_matrix(pid, madjacency, my_nodes, nodes);
	//printf("[rank %d] locals");
	//for (i = 0; i < my_nodes; i++)
		//printf(" %d", locals[i]);
	//printf("\n");

	//printf("[rank %d] ended: %d | locals = %d\n", pid, ended, n_locals);

	while(ended != my_nodes-n_locals) {
		//printf("[rank %d] mais uma voltinha...\n", pid);

		MPI_Recv(my_colors, 2, MPI_INT, MPI_ANY_SOURCE, TAG, MPI_COMM_WORLD, &status);

		colors[my_colors[0]] = my_colors[1];
		//printf("[rank %d] Reiceived color %d from vertice %d\n", pid, my_colors[1], my_colors[0]);
		//printf("[rank %d]", pid);
		//for( i = 0; i < nodes; i++)
			//printf(" %d", colors[i]);
		//printf("\n");


		for ( i = 0; i < my_nodes; i++ ) {
			if (n_wait[i] == 0 || locals[i])
				continue;
			//printf("[rank %d] %d not done...\n", pid, i);
			for (j = 0; j < n_wait[i]; j++)
				if (receive_from[i*(nodes-1)+j] == my_colors[0] ) {
					receive_from[i*(nodes-1)+j] = receive_from[i*(nodes-1)+n_wait[i]-1];
					n_wait[i]--;
					break;
				}
				
			if (n_wait[i] > 0)
				continue;
			//printf("[rank %d] %d done...\n", pid, i);
			colors[(pid-1)*nodes_per_block+i] = color_node(i, pid,nodes_per_block, madjacency, colors, psetcolors, nodes);
			ended++;
			
			my_colors[0] = (pid-1)*nodes_per_block+i;
			my_colors[1] = colors[my_colors[0]];
			for (j = 0; j < n_send[i]; j++) {
				//printf("[rank %d] send color do vertice %d para o %d do rank %d\n", pid, (pid-1)*nodes_per_block+i,
				//		send_to[i*(nodes-1) +j], get_pid_of_node(send_to[i*(nodes-1) +j],nodes,p));

				MPI_Isend(my_colors, 2, MPI_INT, get_pid_of_node(send_to[i*(nodes-1) + j], nodes, p), TAG, MPI_COMM_WORLD, &req);
			}
		}

	}

	for(i = 0; i < my_nodes; i++)
		if (locals[i])
			colors[(pid-1)*nodes_per_block + i] = color_node(i, pid,nodes_per_block, madjacency, colors, psetcolors, nodes);
	//enviar cor final para o master
//	for(i = 0; i < my_nodes; i++)
		//printf("[rank %d] color[%d] = %d\n", pid, i, colors[(pid-1)*nodes_per_block + i]);
	//printf("[rank %d] Send colors to master\n", pid);
	MPI_Send( &colors[(pid-1)*nodes_per_block], my_nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD);
}