0047算法笔记——【随机化算法】拉斯维加斯(Las Vegas)算法和n后问题
来源:互联网 发布:pid算法原理视频教程 编辑:程序博客网 时间:2024/05/24 02:42
1、拉斯维加斯(Las Vegas)算法
拉斯维加斯算法不会得到不正确的解。一旦用拉斯维加斯算法找到一个解,这个解就一定是正确解。但有时用拉斯维加斯算法找不到解。与蒙特卡罗算法类似,拉斯维加斯算法找到正确解的概率随着它所用的计算时间的增加而提高。对于所求解问题的任一实例,用同一拉斯维加斯算法反复对该实例求解足够多次,可使求解失败的概率任意小。拉斯维加斯算法的一个显著特征是它所作的随机性决策有可能导致算法找不到所需的解。
- void obstinate(Object x, Object y)
- {// 反复调用拉斯维加斯算法LV(x,y),直到找到问题的一个解y
- bool success= false;
- while (!success) success=lv(x,y);
- }
void obstinate(Object x, Object y){// 反复调用拉斯维加斯算法LV(x,y),直到找到问题的一个解y bool success= false; while (!success) success=lv(x,y);}
设p(x)是对输入x调用拉斯维加斯算法获得问题的一个解的概率。一个正确的拉斯维加斯算法应该对所有输入x均有p(x)>0。设t(x)是算法obstinate找到具体实例x的一个解所需的平均时间 ,s(x)和e(x)分别是算法对于具体实例x求解成功或求解失败所需的平均时间,则有。解此方程得:
2、n后问题
问题描速:在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
1)纯拉斯维加斯随机算法求解思路
对于n后问题的任何一个解而言,每一个皇后在棋盘上的位置无任何规律,不具有系统性,而更象是随机放置的。在棋盘上相继的各行中随机地放置皇后,并注意使新放置的皇后与已放置的皇后互不攻击,直至n个皇后均已相容地放置好,或已没有下一个皇后的可放置位置时为止。
具体实现代码如下:
1、RandomNumber.h
- #include"time.h"
- //随机数类
- const unsigned long maxshort = 65536L;
- const unsigned long multiplier = 1194211693L;
- const unsigned long adder = 12345L;
- class RandomNumber
- {
- private:
- //当前种子
- unsigned long randSeed;
- public:
- RandomNumber(unsigned long s = 0);//构造函数,默认值0表示由系统自动产生种子
- unsigned short Random(unsigned long n);//产生0:n-1之间的随机整数
- double fRandom(void);//产生[0,1)之间的随机实数
- };
- RandomNumber::RandomNumber(unsigned long s)//产生种子
- {
- if(s == 0)
- {
- randSeed = time(0);//用系统时间产生种子
- }
- else
- {
- randSeed = s;//由用户提供种子
- }
- }
- unsigned short RandomNumber::Random(unsigned long n)//产生0:n-1之间的随机整数
- {
- randSeed = multiplier * randSeed + adder;//线性同余式
- return (unsigned short)((randSeed>>16)%n);
- }
- double RandomNumber::fRandom(void)//产生[0,1)之间的随机实数
- {
- return Random(maxshort)/double(maxshort);
- }
#include"time.h"//随机数类const unsigned long maxshort = 65536L;const unsigned long multiplier = 1194211693L;const unsigned long adder = 12345L;class RandomNumber{private://当前种子unsigned long randSeed;public:RandomNumber(unsigned long s = 0);//构造函数,默认值0表示由系统自动产生种子unsigned short Random(unsigned long n);//产生0:n-1之间的随机整数double fRandom(void);//产生[0,1)之间的随机实数};RandomNumber::RandomNumber(unsigned long s)//产生种子{if(s == 0){randSeed = time(0);//用系统时间产生种子}else{randSeed = s;//由用户提供种子}}unsigned short RandomNumber::Random(unsigned long n)//产生0:n-1之间的随机整数{randSeed = multiplier * randSeed + adder;//线性同余式return (unsigned short)((randSeed>>16)%n);}double RandomNumber::fRandom(void)//产生[0,1)之间的随机实数{return Random(maxshort)/double(maxshort);}2、7d4d1.cpp
- //随机化算法 拉斯维加斯算法 n后问题
- #include "stdafx.h"
- #include "RandomNumber.h"
- #include <cmath>
- #include <iostream>
- using namespace std;
- class Queen
- {
- friend void nQueen(int);
- private:
- bool Place(int k); //测试皇后k置于第x[k]列的合法性
- bool QueensLv(void); //随机放置n个皇后拉斯维加斯算法
- int n; //皇后个数
- int *x,*y; //解向量
- };
- //测试皇后k置于第x[k]列的合法性
- bool Queen::Place(int k)
- {
- for(int j=1; j<k; j++)
- {
- if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))
- {
- return false;
- }
- }
- return true;
- }
- //随机放置n个皇后的拉斯维加斯算法
- bool Queen::QueensLv(void)
- {
- RandomNumber rnd; //随机数产生器
- int k = 1; //下一个皇后的编号
- int count = 1; //在一列中,可以放置皇后的个数
- while((k<=n)&&(count>0))
- {
- count = 0;
- for(int i=1; i<=n; i++)
- {
- x[k] = i;//位置
- if(Place(k))
- {
- y[count++] = i;
- }
- }
- if(count>0)
- {
- x[k++] = y[rnd.Random(count)]; //随机位置
- }
- }
- return (count>0); //count>0 表示放置成功
- }
- //解n后问题的拉斯维加斯算法
- void nQueen(int n)
- {
- Queen X;
- X.n = n;
- int *p = new int[n+1];
- for(int i=0; i<=n; i++)
- {
- p[i] = 0;
- }
- X.x = p;
- X.y = new int[n+1];
- //反复调用随机放置n个皇后的拉斯维加斯算法,直到放置成功
- while(!X.QueensLv());
- for(int i=1; i<=n; i++)
- {
- cout<<p[i]<<" ";
- }
- cout<<endl;
- delete []p;
- }
- int main()
- {
- int n=8;
- cout<<n<<"皇后问题的解为:"<<endl;
- nQueen(n);
- return 0;
- }
//随机化算法 拉斯维加斯算法 n后问题#include "stdafx.h"#include "RandomNumber.h"#include <cmath>#include <iostream>using namespace std;class Queen{friend void nQueen(int);private:bool Place(int k);//测试皇后k置于第x[k]列的合法性bool QueensLv(void);//随机放置n个皇后拉斯维加斯算法int n;//皇后个数int *x,*y;//解向量};//测试皇后k置于第x[k]列的合法性bool Queen::Place(int k){for(int j=1; j<k; j++){if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])){return false;}}return true;}//随机放置n个皇后的拉斯维加斯算法bool Queen::QueensLv(void){RandomNumber rnd;//随机数产生器int k = 1;//下一个皇后的编号int count = 1;//在一列中,可以放置皇后的个数while((k<=n)&&(count>0)){count = 0;for(int i=1; i<=n; i++){x[k] = i;//位置if(Place(k)){y[count++] = i;}}if(count>0){x[k++] = y[rnd.Random(count)];//随机位置}}return (count>0);//count>0 表示放置成功}//解n后问题的拉斯维加斯算法void nQueen(int n){Queen X;X.n = n;int *p = new int[n+1];for(int i=0; i<=n; i++){p[i] = 0;}X.x = p;X.y = new int[n+1];//反复调用随机放置n个皇后的拉斯维加斯算法,直到放置成功while(!X.QueensLv());for(int i=1; i<=n; i++){cout<<p[i]<<" ";}cout<<endl;delete []p;}int main(){int n=8; cout<<n<<"皇后问题的解为:"<<endl; nQueen(n); return 0; }程序运行结果如下:
2)与回溯法结合的拉斯维加斯随机算法求解思路
如果将上述随机放置策略与回溯法相结合,可能会获得更好的效果。可以先在棋盘的若干行中随机地放置皇后,然后在后继行中用回溯法继续放置,直至找到一个解或宣告失败。随机放置的皇后越多,后继回溯搜索所需的时间就越少,但失败的概率也就越大。
算法具体代码如下:
1、RandomNumber.h如上
2、7d4d1-2.cpp
- //随机化算法 拉斯维加斯算法 n后问题
- #include "stdafx.h"
- #include "RandomNumber.h"
- #include <cmath>
- #include <iostream>
- using namespace std;
- class Queen
- {
- friend bool nQueen(int);
- private:
- bool Place(int k); //测试皇后k置于第x[k]的合法性
- bool Backtrack(int t); //解n后问题的回溯法
- bool QueensLV(int stopVegas); //随机放置n个皇后拉斯维加斯算法
- int n,*x,*y;
- };
- //测试皇后k置于第x[k]列的合法性
- bool Queen::Place(int k)
- {
- for(int j=1; j<k; j++)
- {
- if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))
- {
- return false;
- }
- }
- return true;
- }
- //解n后问题的回溯法
- bool Queen::Backtrack(int t)
- {
- if(t>n)
- {
- for(int i=1; i<=n; i++)
- {
- y[i] = x[i];//问题的解
- }
- return true;
- }
- else
- {
- for(int i=1; i<=n; i++)
- {
- x[t] = i;
- if(Place(t)&&Backtrack(t+1))
- {
- return true;
- }
- }
- }
- return false;
- }
- //随机放置n个皇后拉斯维加斯算法
- bool Queen::QueensLV(int stopVegas)
- {
- RandomNumber rnd; //随机数产生器
- int k = 1;
- int count = 1;
- //1<=stopVegas<=n
- while((k<=stopVegas)&&(count>0))
- {
- count = 0;
- for(int i=1; i<=n; i++)
- {
- x[k] = i;
- if(Place(k))
- {
- y[count++] = i;
- }
- }
- if(count>0)
- {
- x[k++] = y[rnd.Random(count)];//随机位置
- }
- }
- return (count>0); //count>0表示放置成功
- }
- //与回溯法相结合的解n后问题的拉斯维加斯算法
- bool nQueen(int n)
- {
- Queen X;
- //初始化X
- X.n = n;
- int *p = new int[n+1];
- int *q = new int[n+1];
- for(int i=0; i<=n; i++)
- {
- p[i] = 0;
- q[i] = 0;
- }
- X.y = p;
- X.x = q;
- int stop = 3;
- if(n>15)
- {
- stop = n-15;
- }
- bool found = false;
- while(!X.QueensLV(stop));
- //算法的回溯搜索部分
- if(X.Backtrack(stop+1))
- {
- for(int i=1; i<=n; i++)
- {
- cout<<p[i]<<" ";
- }
- found = true;
- cout<<endl;
- }
- delete []p;
- delete []q;
- return found;
- }
- int main()
- {
- int n=8;
- cout<<n<<"皇后问题的解为:"<<endl;
- while(!nQueen(n));
- return 0;
- }
//随机化算法 拉斯维加斯算法 n后问题#include "stdafx.h"#include "RandomNumber.h"#include <cmath>#include <iostream>using namespace std;class Queen{friend bool nQueen(int);private:bool Place(int k);//测试皇后k置于第x[k]的合法性bool Backtrack(int t);//解n后问题的回溯法bool QueensLV(int stopVegas);//随机放置n个皇后拉斯维加斯算法int n,*x,*y;};//测试皇后k置于第x[k]列的合法性bool Queen::Place(int k){for(int j=1; j<k; j++){if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k])){return false;}}return true;}//解n后问题的回溯法bool Queen::Backtrack(int t){if(t>n){for(int i=1; i<=n; i++){y[i] = x[i];//问题的解}return true;}else{for(int i=1; i<=n; i++){x[t] = i;if(Place(t)&&Backtrack(t+1)){return true;}}}return false;}//随机放置n个皇后拉斯维加斯算法bool Queen::QueensLV(int stopVegas){RandomNumber rnd;//随机数产生器int k = 1;int count = 1;//1<=stopVegas<=nwhile((k<=stopVegas)&&(count>0)){count = 0;for(int i=1; i<=n; i++){x[k] = i;if(Place(k)){y[count++] = i;}}if(count>0){x[k++] = y[rnd.Random(count)];//随机位置}}return (count>0);//count>0表示放置成功}//与回溯法相结合的解n后问题的拉斯维加斯算法bool nQueen(int n){Queen X;//初始化XX.n = n;int *p = new int[n+1];int *q = new int[n+1];for(int i=0; i<=n; i++){p[i] = 0;q[i] = 0;}X.y = p;X.x = q;int stop = 3;if(n>15){stop = n-15;}bool found = false;while(!X.QueensLV(stop));//算法的回溯搜索部分if(X.Backtrack(stop+1)){for(int i=1; i<=n; i++){cout<<p[i]<<" ";}found = true;cout<<endl;}delete []p;delete []q;return found;}int main(){int n=8; cout<<n<<"皇后问题的解为:"<<endl; while(!nQueen(n)); return 0; }程序运行结果如图:
- 0047算法笔记——【随机化算法】拉斯维加斯(Las Vegas)算法和n后问题
- 0047算法笔记——【随机化算法】拉斯维加斯(Las Vegas)算法和n后问题
- 随机化算法(4) — 拉斯维加斯(Las Vegas)算法
- 随机化算法(4) — 拉斯维加斯(Las Vegas)算法
- 0048算法笔记——【随机化算法】拉斯维加斯随机化算法求解整数因子分解中的因子分割问题
- 0048算法笔记——【随机化算法】拉斯维加斯随机化算法求解整数因子分解中的因子分割问题
- N后问题(拉斯维加斯算法)
- n后问题2.0(拉斯维加斯随机算法)
- 拉斯维加斯算法和N皇后问题
- java实现的n后问题体现拉斯维加斯算法
- 0044算法笔记——【随机化算法】舍伍德(Sherwood)算法和线性时间选择问题
- 0044算法笔记——【随机化算法】舍伍德(Sherwood)算法和线性时间选择问题
- 0041算法笔记——【随机化算法】随机化算法与随机数问题
- 0041算法笔记——【随机化算法】随机化算法与随机数问题
- 拉斯维加斯算法求n皇后问题
- 0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题
- 0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题
- 蒙特卡罗算法和拉斯维加斯算法
- Android系统广播Broadcast机制分析
- 图像处理与计算机视觉:基础,经典以及最近发展(4)图像处理与分析
- 0045算法笔记——【随机化算法】舍伍德随机化思想搜索有序表
- 图像处理与计算机视觉:基础,经典以及最近发展(5)计算机视觉
- 利用队列输出杨辉三角
- 0047算法笔记——【随机化算法】拉斯维加斯(Las Vegas)算法和n后问题
- 0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题
- java网络编程1
- 0048算法笔记——【随机化算法】拉斯维加斯随机化算法求解整数因子分解中的因子分割问题
- 0049算法笔记——【随机化算法】蒙特卡罗算法,主元素问题,素数测试问题
- 0050算法笔记——【线性规划】单纯形算法(未完全实现)
- java 配置文件 web.xml基础
- Unity 事件2
- Swing之JTextField中添加图片