以下使用爬山法求解n皇后问题的代码存在bug,请找出
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <algorithm>
#include <random>
using namespace std;
// 显示棋盘
void print_board(int *queens, int n)
{
printf("\n解决方案:\n");
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (queens[i] == j)
{
printf("Q ");
}
else
{
printf(". ");
}
}
printf("\n");
}
}
int *diag1_conflicts;
int *diag2_conflicts;
int pos_diag1(int row, int col)
{
return row + col;
}
int pos_diag2(int row, int col, int n)
{
return row - col + n - 1;
}
bool hill_climbing_n_queens(int n, int max_iterations)
{
int *queens = (int *)malloc(n * sizeof(int));
diag1_conflicts = (int *)calloc(2 * n, sizeof(int));
diag2_conflicts = (int *)calloc(2 * n, sizeof(int));
// int *col_conflicts = (int *)calloc(n, sizeof(int));
if (queens == NULL || /*col_conflicts == NULL || */
diag1_conflicts == NULL || diag2_conflicts == NULL)
{
printf("内存分配失败\n");
return false;
}
// 随机初始化并计算初始冲突
vector<int> queens_position;
for (int i = 0; i < n; i++)
{
queens_position.push_back(i);
}
std::mt19937 gen(std::random_device{}());
shuffle(queens_position.begin(), queens_position.end(), gen);
for (int i = 0; i < n; i++)
{
queens[i] = queens_position[i];
// col_conflicts[queens[i]]++;
diag1_conflicts[i + queens[i]]++;
diag2_conflicts[i - queens[i] + n - 1]++;
}
printf("使用优化爬山法求解 %d 皇后问题\n", n);
for (int iter = 0; iter < max_iterations; iter++)
{
// 检查是否找到解
bool found_solution = true;
for (int i = 0; i < n; i++)
{
if (/*col_conflicts[queens[i]] > 1 || */
diag1_conflicts[i + queens[i]] > 1 ||
diag2_conflicts[i - queens[i] + n - 1] > 1)
{
found_solution = false;
break;
}
}
if (found_solution)
{
printf("\n在第 %d 次迭代中找到解决方案!\n", iter);
print_board(queens, n);
free(queens);
// free(col_conflicts);
free(diag1_conflicts);
free(diag2_conflicts);
return true;
}
int row1_to_change = -1;
int row2_to_change = -1;
// 对每对相邻行的皇后,尝试互相交换
for (int row1 = 0; row1 < n; row1++)
{
int col1 = queens[row1];
bool isFound = false;
for (int row2 = 0; row2 < n; row2++)
{
if (row1 == row2)
{
continue;
}
int col2 = queens[row2];
// 计算当前冲突数
int current_conflicts = diag1_conflicts[pos_diag1(row1, col1)] - 1 +
diag2_conflicts[pos_diag2(row1, col1, n)] - 1 +
diag1_conflicts[pos_diag1(row2, col2)] - 1 +
diag2_conflicts[pos_diag2(row2, col2, n)] - 1;
int new_conflicts = diag1_conflicts[pos_diag1(row2, col1)] - 1 +
diag2_conflicts[pos_diag2(row2, col1, n)] - 1 +
diag1_conflicts[pos_diag1(row1, col2)] - 1 +
diag2_conflicts[pos_diag2(row1, col2, n)] - 1;
if(new_conflicts < current_conflicts){
isFound = true;
row1_to_change = row1;
row2_to_change = row2;
break;
}
}
if(isFound){
break;
}
}
// for (int row = 0; row < n - 1; row++)
//{
/*int row1 = row;
int row2 = row + 1;
int col1 = queens[row];
int col2 = queens[row2];*/
// 计算当前冲突数
/*int current_conflicts = diag1_conflicts[pos_diag1(row1, col1)] - 1 +
diag2_conflicts[pos_diag2(row1, col1, n)] - 1 +
diag1_conflicts[pos_diag1(row2, col2)] - 1 +
diag2_conflicts[pos_diag2(row2, col2, n)];*/
/*int current_conflicts = (diag1_conflicts[row1 + col1] - 1) +
(diag2_conflicts[row1 - row + n - 1] - 1) +
(diag1_conflicts[row1 + 1 +])*/
/*int current_conflicts = (diag1_conflicts[row1 + col1] - 1) +
(diag2_conflicts[row2 - col2 + n - 1]) +
(diag1_conflicts[row1 + col1 + 1] - 1) +
(diag2_conflicts[row2 - col2 + n - 2]);*/
/*// 计算修改后的冲突数
int new_conflicts = diag1_conflicts[pos_diag1(row1 + 1, col1)] - 1 +
diag2_conflicts[pos_diag2(row1 + 1, col1, n)] - 1 +
diag1_conflicts[pos_diag1(row2 - 1, col2)] - 1 +
diag2_conflicts[pos_diag2(row2 - 1, col2, n)];
// 计算是否保留该答案
int improvement = current_conflicts - new_conflicts;
if (improvement > best_improvement)
{
best_improvement = improvement;
best_row = row;
}*/
//}
/*for (int row = 0; row < n; row++) {
int current_col = queens[row];
// 计算当前位置的冲突数
int current_conflicts = (col_conflicts[current_col] - 1) +
(diag1_conflicts[row + current_col] - 1) +
(diag2_conflicts[row - current_col + n - 1] - 1);
for (int new_col = 0; new_col < n; new_col++) {
if (new_col == current_col) continue;
// 计算新位置的冲突数
int new_conflicts = col_conflicts[new_col] +
diag1_conflicts[row + new_col] +
diag2_conflicts[row - new_col + n - 1];
int improvement = current_conflicts - new_conflicts;
if (improvement > best_improvement) {
best_improvement = improvement;
best_row = row;
best_col = new_col;
}
}
}*/
if (row1_to_change == -1)
{
// 随机重启
/*for (int i = 0; i < n; i++) {
//col_conflicts[queens[i]]--;
diag1_conflicts[i + queens[i]]--;
diag2_conflicts[i - queens[i] + n - 1]--;
queens[i] = rand() % n;
//col_conflicts[queens[i]]++;
diag1_conflicts[i + queens[i]]++;
diag2_conflicts[i - queens[i] + n - 1]++;
}*/
vector<int> queens_position;
for (int i = 0; i < n; i++)
{
queens_position.push_back(i);
}
std::mt19937 gen(std::random_device{}());
shuffle(queens_position.begin(), queens_position.end(), gen);
for (int i = 0; i < n; i++)
{
queens[i] = queens_position[i];
// col_conflicts[queens[i]]++;
diag1_conflicts[i + queens[i]]++;
diag2_conflicts[i - queens[i] + n - 1]++;
}
printf("迭代 %d: 随机重启\n", iter + 1);
}
else
{
// todo
// 更新冲突数组并移动皇后
diag1_conflicts[pos_diag1(row1_to_change, queens[row1_to_change])]--;
diag2_conflicts[pos_diag2(row1_to_change, queens[row1_to_change], n)]--;
diag1_conflicts[pos_diag1(row2_to_change, queens[row2_to_change])]--;
diag2_conflicts[pos_diag2(row2_to_change, queens[row2_to_change], n)]--;
swap(queens[row1_to_change], queens[row2_to_change]);
diag1_conflicts[pos_diag1(row1_to_change, queens[row1_to_change])]++;
diag2_conflicts[pos_diag2(row1_to_change, queens[row1_to_change], n)]++;
diag1_conflicts[pos_diag1(row2_to_change, queens[row2_to_change])]++;
diag2_conflicts[pos_diag2(row2_to_change, queens[row2_to_change], n)]++;
/*diag1_conflicts[pos_diag1(best_row, queens[best_row])]--;
diag2_conflicts[pos_diag2(best_row, queens[best_row], n)]--;
diag1_conflicts[pos_diag1(best_row + 1, queens[best_row + 1])]--;
diag2_conflicts[pos_diag2(best_row + 1, queens[best_row + 1], n)]--;
swap(queens[best_row], queens[best_row + 1]);
diag1_conflicts[pos_diag1(best_row, queens[best_row])]++;
diag2_conflicts[pos_diag2(best_row, queens[best_row], n)]++;
diag1_conflicts[pos_diag1(best_row + 1, queens[best_row + 1])]++;
diag2_conflicts[pos_diag2(best_row + 1, queens[best_row + 1], n)]++;*/
/*int old_col = queens[best_row];
//col_conflicts[old_col]--;
diag1_conflicts[best_row + old_col]--;
diag2_conflicts[best_row - old_col + n - 1]--;
queens[best_row] = best_col;*/
// col_conflicts[best_col]++;
// diag1_conflicts[best_row + best_col]++;
// diag2_conflicts[best_row - best_col + n - 1]++;
printf("迭代 %d: %d 与 %d行交换",
iter + 1, row1_to_change, row2_to_change);
}
}
printf("在 %d 次迭代内未找到解决方案\n", max_iterations);
free(queens);
// free(col_conflicts);
free(diag1_conflicts);
free(diag2_conflicts);
return false;
}
int main()
{
int n;
int max_iterations;
printf("请输入皇后数量 n: ");
scanf("%d", &n);
printf("请输入最大迭代次数: ");
scanf("%d", &max_iterations);
bool result2 = hill_climbing_n_queens(n, max_iterations);
return 0;
}