void Sudoku::solve_colorability_style() { if (!this->status_ok) { throw std::logic_error("Puzzle has not been initialized"); } color_node(this->grid); }
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); }