实验内容 :
本实验要求基于算法设计与分析的一般过程(即待求解问题的描述、算法设计、算法 描述、算法正确性证明、算法分析、算法实现与测试),通过随机化方法(包括拉斯维加斯 法)在实际问题求解实践中,加深理解其基本原理和思想以及求解步骤。求解的问题为 N 后问题。作为挑战:可以考虑其他随机化算法(如随机快排、蒙特卡洛法估计问题的平均 情况下的复杂性/搜索树的规模等)。
实验目的:
◆ 理解随机化算法的核心思想以及求解过程;
◆ 掌握几种随机化算法(即数值随机化算法、蒙特卡洛算法、拉斯维加斯算法以及 舍伍德算法);
◆ 从算法分析与设计的角度,对 N 后问题等的随机化算法有更进一步的理解。
实验步骤:
步骤 1:理解问题,给出问题的描述。
在 n×n 格的棋盘上放置彼此不受攻击的 n 个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
步骤 2:算法设计,包括策略与数据结构的选择
对于n后问题的任何一个解而言,每一个皇后在棋盘上的位置无任何规律,不具有系统 性,而更象是随机放置的。由此容易想到下面的拉斯维加斯算法。在棋盘上相继的各行中随 机地放置皇后,并注意使新放置的皇后与已放置的皇后互不攻击,直至 n 个皇后已相容地放置好,或已没有下一个皇后的可放置位置时为止。
步骤 3:描述算法。希望采用源代码以外的形式,如伪代码或流程图等;
void Obstinate(InputType x, OutputType &y){
// 反复调用拉斯维加斯算法 LV(x, y),直到找到问题的一个解
bool success= false;
while (!success) success = LV(x,y);
}
步骤 5:算法复杂性分析,包括时间复杂性和空间复杂性。
可以基于蒙特卡洛算法来估 计平均情况下的算法复杂性; 时间复杂度 o(n²) 空间复杂度 o(n)
步骤 6:算法实现与测试。附上代码或以附件的形式提交,同时贴上算法运行结果截图
#include <iostream> #include <vector> using namespace std; // 判断在(row, col)位置放置皇后是否与之前的皇后冲突 bool isConflict(const vector<int> &pos, int row, int col) { for (int i = 0; i < row; ++i) { // 检查是否在同一列上 if (pos[i] == col) { return true; } // 检查是否在同一斜线上 if (abs(i - row) == abs(pos[i] - col)) { return true; } } return false; } // 验证当前解的合法性 bool validateSolution(const vector<int> &pos) { int n = pos.size(); for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { // 检查两个皇后是否在同一列上 if (pos[i] == pos[j]) { return false; } // 检查两个皇后是否在同一斜线上 if (abs(i - j) == abs(pos[i] - pos[j])) { return false; } } } return true; } // 打印棋盘上的皇后位置 void printBoard(const vector<int> &pos) { int n = pos.size(); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (pos[i] == j) { cout << "Q "; // 打印皇后位置 } else { cout << ". "; // 打印空位置 } } cout << endl; // 换行 } } int main() { vector<int> solution(8); // 初始化一个大小为8的向量,用于存储皇后的位置 cout << "请输入 8 个数字(范围:0 到 7),表示每个皇后的位置:" << endl; for (int i = 0; i < 8; ++i) { cin >> solution[i]; // 输入皇后的位置 } cout << "输入的解:" << endl; printBoard(solution); // 打印输入的解 cout << "验证解的正确性:" << endl; if (validateSolution(solution)) { cout << "解是正确的" << endl; } else { cout << "解是错误的" << endl; } system("pause"); // 暂停程序,等待用户操作 return 0; }
实验总结 :
拉斯维加斯算法的一个显著特征是它所做的随机性策略可能找不到所需的解。典型的调 用形式为 bool success=LV(x,y),其中 x 是输入参数,当 success 值为 true 时,y 返回问题 的解。当 success 值为 false 时,算法未能找到问题的解,此时可对同一实例再次独立地调 用相同的算法。