### 问题描述,八皇后
算法描述:爬山法,是以当前最优,可能会导致结果陷入到局部最优,所以本代码为改进版本的随机重启的爬山法。让陷入无限循环的对象,直接重启,进入新的
环境进行爬山。形象的将棋盘的每一行,看成山~而所有位置是0-7为所有的点,最优函数,计算的是整个棋盘的皇后碰撞对数。所以,每一次爬山,就是算,哪个位置
可以使得函数最优
初始化:棋盘,以行为例够形象些,然后去想象爬山
public static int[] init_queen(int[] queen_array){
for (int i = 0; i < queen_array.length; i++) {
queen_array[i] = (int)(Math.random()*8);
}
return queen_array;
}
爬山函数,准备开始爬山操作
//开始爬山
public static void begin_climbing(int[] queen_array){
//将当前爬到最优的地方,是不是每个地方都尝试,然后选择最优解的地方,然后开始随机重启
//开始爬山之前,对该位置,进行评测,然后,计算换位置后的最优解,然后保存,开始随机下一波爬山
//位置随机
int function_key = 0;
int start_index = 0;
int climbing_count = 0;
while(true){
if (climbing_count==40){
queen_array=reset_arry(queen_array);
climbing_count = 0;
}
climbing_count++;
function_key = function(queen_array);
System.out.println("------------------function = "+function_key);
//出口已经写好
if(function_key==0){
System.out.println("------------------find out array--------------------------");
for (int i = 0; i < 8; i++) {
System.out.print("-"+queen_array[i]+"-");
}
System.out.println();
break;
}
int min_Value = queen_array[start_index];//存储的当前下标位置
int temp = function_key;
for (int i = 0; i < 8; i++) {
queen_array[start_index] = i;
if (temp>function(queen_array)){
min_Value = i;
}
}
queen_array[start_index] = min_Value;
//开始随机重启
System.out.println("------------------爬山开始--------------------------");
start_index = (int)(Math.random()*8);
System.out.println("------------------爬山位置"+start_index+"-----------");
}
}
重置函数:就是将当前棋盘打乱,找到打破僵局
public static int[] reset_arry(int[] queen_array){
queen_array = init_queen(queen_array);
return queen_array;
}
最后,这是适应度函数
public static int function(int[] queen_array){
int count = 0;
for (int i = 0; i < queen_array.length-1; i++) {
for (int j = i+1; j < queen_array.length; j++) {
if (queen_array[i]==queen_array[j]|(j-i)==Math.abs(queen_array[i]-queen_array[j])){
count++;
}
}
}
return count;
}
所有代码如下:
package Mountain_climbing_slove_eight_queen;
/**
* @Author CRH
* @Date 2020/11/17 16:41
*/
/**
* 传统的爬山法,非常容易走进局部最优,最后走不出来,因为这和其本身的关系相关,针对于爬山法,是讲究当前最优解,没有考虑
* 全局概念,所以,如果想要最优解,就需要随机重启,意思是,当走到不行了的时候,需要将整个棋盘进行重置,然后接着进行爬山法,最后
* 会得到最优解。
*/
/**
* 1.爬山法,将当前每行看成第一个,开始爬山,爬到适当的地方为止,标明其为最OK的点,然后选择随机重启,将下一行进行继续随机重启
* 2、适应度函数为冲突的对数
* 3、结束条件是冲突函数为0
*/
public class mountain_climbing_slove_eight_queen {
//爬山法,以当前最优,并寻找最优解
public static void main(String[] arg){
int[] queen_array = new int[8];
queen_array = init_queen(queen_array);
begin_climbing(queen_array);
}
//初始化棋盘
public static int[] init_queen(int[] queen_array){
for (int i = 0; i < queen_array.length; i++) {
queen_array[i] = (int)(Math.random()*8);
}
return queen_array;
}
//开始爬山
public static void begin_climbing(int[] queen_array){
//将当前爬到最优的地方,是不是每个地方都尝试,然后选择最优解的地方,然后开始随机重启
//开始爬山之前,对该位置,进行评测,然后,计算换位置后的最优解,然后保存,开始随机下一波爬山
//位置随机
int function_key = 0;
int start_index = 0;
int climbing_count = 0;
while(true){
if (climbing_count==40){
queen_array=reset_arry(queen_array);
climbing_count = 0;
}
climbing_count++;
function_key = function(queen_array);
System.out.println("------------------function = "+function_key);
//出口已经写好
if(function_key==0){
System.out.println("------------------find out array--------------------------");
for (int i = 0; i < 8; i++) {
System.out.print("-"+queen_array[i]+"-");
}
System.out.println();
break;
}
int min_Value = queen_array[start_index];//存储的当前下标位置
int temp = function_key;
for (int i = 0; i < 8; i++) {
queen_array[start_index] = i;
if (temp>function(queen_array)){
min_Value = i;
}
}
queen_array[start_index] = min_Value;
//开始随机重启
System.out.println("------------------爬山开始--------------------------");
start_index = (int)(Math.random()*8);
System.out.println("------------------爬山位置"+start_index+"-----------");
}
}
//重置函数
public static int[] reset_arry(int[] queen_array){
queen_array = init_queen(queen_array);
return queen_array;
}
//适应度函数
public static int function(int[] queen_array){
int count = 0;
for (int i = 0; i < queen_array.length-1; i++) {
for (int j = i+1; j < queen_array.length; j++) {
if (queen_array[i]==queen_array[j]|(j-i)==Math.abs(queen_array[i]-queen_array[j])){
count++;
}
}
}
return count;
}
}
结语:共勉