1 #include

2 #include

3 #include

4 #include

5 //

6 //编程题7 //爬山法(八皇后问题)8 //

9

10

11 //棋子结构体12 //typedef struct Chess * Chess;

13

14 int a[64];//a数组中记录了爬山过程中,每次棋盘碰撞次数的最小值

15 int array_count = 0; //array_count是a数组中的计数器

16 int number = 0;//number为爬山次数

17

18 structGlobal_Collidecount_min19 {20 int mincollidecount[64]; //存放每次搜索后,棋盘上最小碰撞对数。

21 int globalmin = -1;22 }global_collidecount_min;23

24

25

26 typedef struct

27 {28 intposx;29 intposy;30 intcollidecount;31 }Coordinate;32

33

34 typedef struct

35 {36 int value;//存储需要比较的数值

37 Coordinate position[8];//存储棋盘上的坐标。

38 }Chess;39

40 Chess chess;41

42

43 //地图结构体

44 typedef struct

45 {46

47 int map[8][8];48 int collidecount[8][8];49 int collidecount2[8][8];50 int collidecount3[8][8];51 }Map;52

53

54 //C实现键值对(Map功能)

55 typedef struct

56 {57 intkey_x;58 intkey_y;59 intvalue;60 boolkaiguan;61 }Pair;62

63

64

65

66 Pair pair[64];67 Map ditu;68

69

70

71 //初始化地图

72 voidinitmap()73 {74 for (int x = 0; x < 8; x++)75 for (int y = 0; y < 8; y++)76 {77 ditu.map[x][y] = 0;78 ditu.collidecount[x][y] = 0;79 ditu.collidecount2[x][y] = 0;80 ditu.collidecount3[x][y] = 0;81 }82 }83

84

85 //初始化八皇后,按列赋初值

86 voidinitchess()87 {88 inty;89 for (y = 0; y < 8; y++)90 {91 int x = rand() % 8;92 chess.value = 1;93 chess.position[y].posx =x;94 chess.position[y].posy =y;95 chess.position[y].collidecount = 0;96 ditu.map[x][y] = chess.value;//用1表示棋子

97 }98

99

100 }101

102

103 //初始化键值对

104 voidinitpair()105 {106

107 for (int i = 0; i < 63; i++)108 {109 pair[i].key_x = 0;110 pair[i].key_y = 0;111 pair[i].kaiguan = false;112 pair[i].value = 0;113 }114

115 }116

117

118

119

120 //输出地图

121 voidoutmap()122 {123

124 for (int x = 0; x < 8; x++)125 {126 for (int y = 0; y < 8; y++)127 printf("%3.1d", ditu.map[x][y]);128 printf("\n");129 }130 }131

132

133 //输出棋子位置

134 voidoutchess()135 {136

137 for (int x = 0; x < 8; x++)138 {139

140 printf("x=%3.1d,y=%3.1d", chess.position[x].posx, chess.position[x].posy);141 printf("\n");142 }143

144 }145

146

147

148 voidoutmap1()149 {150

151 for (int x = 0; x < 8; x++)152 {153 for (int y = 0; y < 8; y++)154 printf("%3.1d", ditu.collidecount[x][y]);155 printf("\n");156 }157 }158

159

160 voidoutmap2()161 {162

163 for (int x = 0; x < 8; x++)164 {165 for (int y = 0; y < 8; y++)166 printf("%3.1d", ditu.collidecount2[x][y]);167 printf("\n");168 }169 }170

171

172 voidoutmap3()173 {174

175 for (int x = 0; x < 8; x++)176 {177 for (int y = 0; y < 8; y++)178 printf("%3.1d", ditu.collidecount3[x][y]);179 printf("\n");180 }181 }182

183

184

185 //将地图中的碰撞数ditu.collidecount,ditu.collidecount2,ditu.collidecount3置0;

186 voidresetcollidecount()187 {188 for (int x = 0; x < 8; x++)189 for (int y = 0; y < 8; y++)190 {191 ditu.collidecount[x][y] = 0;192 ditu.collidecount2[x][y] = 0;193 ditu.collidecount3[x][y] = 0;194 }195 }196

197

198 //将存储棋盘中最小碰撞数的pair还原

199 voidresetpair()200 {201

202 for (int i = 0; i < 63; i++)203 {204 pair[i].key_x = 0;205 pair[i].key_y = 0;206 pair[i].kaiguan = false;207 pair[i].value = 0;208 }209

210 }211

212

213 ///

214 ///将地图中的碰撞数ditu.collidecount,ditu.collidecount2,ditu.collidecount3置0;215 ///将存储棋盘中最小碰撞数的pair还原216 ///

217 voidreset()218 {219 resetcollidecount();220 resetpair();221 }222

223

224

225 //查看是否与棋盘中皇后位置重复

226 int find(int row, intcolumn)227 {228 intm;229 for (m = 0; m < 8; m++)230 {231 int posx =chess.position[m].posx;232 int posy =chess.position[m].posy;233 if ((posx == row) && (posy ==column))234 return 0;235 }236 return 1;237 }238

239

240

241 //随机选取一个最小碰撞数所在的位置,将地图中同列的皇后置0,

242 void randomselect(intposition)243 {244

245 srand((int)time(NULL));246 int x = rand() %position;247 /*printf("%d\t%d\n", x, position);248 printf("%d\n", pair[x].key_y);*/

249 int posx = chess.position[pair[x].key_y].posx;//取得同列皇后的横坐标

250 int posy = chess.position[pair[x].key_y].posy;//取得同列皇后的纵坐标251 //printf("%d\t%d\n", posx, posy);

252 chess.position[pair[x].key_y].posx = pair[x].key_x;//将皇后的横坐标该为最小碰撞数所在的位置的横坐标253 //printf("%d\n", pair[x].key_x);

254 ditu.map[posx][posy] = 0;//将地图中皇后原位置置0

255 ditu.map[pair[x].key_x][pair[x].key_y] = 1;//将地图中皇后新位置置1

256 }257

258

259 //统计棋盘中最小碰撞数的个数,并将最小碰撞数所在位置和值存到pair键值对中

260 void countmin(intmin)261 {262 int position = 0;263 for (int n = 0; n < 8; n++)264 for (int m = 0; m < 8; m++)265 if (ditu.collidecount3[n][m] ==min)266 {267 pair[position].key_x =n;268 pair[position].key_y =m;269 pair[position].kaiguan = true;270 pair[position].value =min;271 position++;272 }273

274 randomselect(position);275 }276

277

278

279

280 //遍历 pair[]数组,找出最小碰撞数

281 intvisit()282 {283

284 intmin, min_x, min_y;285

286 for (min_x = 0; min_x < 8; min_x++)287 {288 for (min_y = 0; min_y < 8; min_y++)289 {290 if(find(min_x, min_y))291 {292 min =ditu.collidecount3[min_x][min_y];293 //printf("%d\n", min);294 //printf("%d\t%d\n", min_x, min_y);

295 break;296 }297 }298 break;299 }300 /*printf("%d\t%d\n", min_x, min_y);301 printf("%d\n", min);*/

302

303

304 for (int i = 0; i < 8; i++)305 for (int j = 0; j < 8; j++)306 if(find(i, j))307 {308 if (min >ditu.collidecount3[i][j])309 min =ditu.collidecount3[i][j];310 }311 //printf("%d\n", min);

312

313 returnmin;314 }315

316

317

318

319

320 intcountcollidecount()321 {322 int row, column, count = 0;323 for (row = 0; row < 8; row++)324 for (column = 0; column < 8; column++)325 if (ditu.collidecount2[row][column] != 0)326 count +=ditu.collidecount2[row][column];327 returncount;328 }329

330

331

332 ///

333 ///对m列的n位置上的棋子进行检测334 ///

335 ///

336 ///

337 void function3(int hang, intlie)338 {339 int collidecount = 0;340 int collidecount2 = 0;341 //行检测

342 for (int count = 0; count < 8; count++)343 {344 intm, n;345 int posx =chess.position[count].posx;346 int posy =chess.position[count].posy;347 //printf("x=%d,y=%d\n", posx, posy);

348 for (m = 0; m < 8; m++)349 {350 if ((ditu.map[posx][m] != 0) && (m !=posy))351 {352 collidecount++;353

354 }355 else

356 continue;357 }358

359

360

361

362 //lie列

363 for (n = 0; n < 8; n++)364 {365 if ((ditu.map[n][posy] != 0) && (n !=posx))366 {367 collidecount++;368 }369 else

370 continue;371 }372

373 //dui'jiao'xian对角线

374

375 n = posx - 1; m = posy + 1;376 { for (; (n != -1) && (m != 8); n--, m++)377 if (ditu.map[n][m] != 0)378 collidecount++;379 }380

381 n = posx + 1; m = posy - 1;382 { for (; (n != 8) && (m != -1); n++, m--)383 if (ditu.map[n][m] != 0)384 collidecount++;385 }386 n = posx - 1; m = posy - 1;387

388 { for (; (n != -1) && (m != -1); n--, m--)389 if (ditu.map[n][m] != 0)390 collidecount++;391 }392

393 n = posx + 1; m = posy + 1;394 { for (; (n != 8) && (m != 8); n++, m++)395 if (ditu.map[n][m] != 0)396 collidecount++;397 ditu.collidecount2[posx][posy] +=collidecount;398 } collidecount = 0;399

400

401

402 }403

404 ditu.collidecount3[hang][lie] =countcollidecount();405

406

407 //置零

408 for (int n = 0; n < 8; n++)409 {410 for (int m = 0; m < 8; m++)411 {412 ditu.collidecount2[n][m] = 0;413 }414 }415

416 }417

418

419

420 ///

421 ///检查同列中其他位置上的碰撞数422 ///

423 voidfunction2()424 {425 for (int n = 0; n < 8; n++)426 for (int m = 0; m < 8; m++)427 {428

429 if (!find(n, m))430 continue;431 else

432 {433 int posx =chess.position[m].posx;434 int posy =chess.position[m].posy;435 ditu.map[posx][posy] = 0;//将第m列的皇后置0

436 ditu.map[n][m] = 1;//将m列的第n个位置变为1

437 chess.position[m].posx =n;438 chess.position[m].posy =m;439 outmap();440 outmap3();441 function3(n, m);//对m列n位置碰撞检测

442 printf("\n");443 ditu.map[posx][posy] = 1; //恢复皇后

444 ditu.map[n][m] = 0;445 chess.position[m].posx =posx;446 chess.position[m].posy =posy;447 }448 }449

450 }451

452

453

454 //碰撞对数检测

455 voidfunction1()456 {457 int collidecount = 0;458

459 //行检测

460 for (int count = 0; count < 8; count++)461 {462 intm, n;463 int posx =chess.position[count].posx;464 int posy =chess.position[count].posy;465 //printf("x=%d,y=%d\n", posx, posy);

466 for (m = 0; m < 8; m++)467 {468 if ((ditu.map[posx][m] != 0) && (m !=posy))469 {470 collidecount++;471

472 }473 else

474 continue;475 }476

477

478

479 //lie列

480 for (n = 0; n < 8; n++)481 {482 if ((ditu.map[n][posy] != 0) && (n !=posx))483 {484 collidecount++;485 }486 else

487 continue;488 }489

490 //对角线检测

491 n = posx - 1; m = posy + 1;492 { for (; (n != -1) && (m != 8); n--, m++)493 if (ditu.map[n][m] != 0)494 collidecount++;495 }496

497 n = posx + 1; m = posy - 1;498 { for (; (n != 8) && (m != -1); n++, m--)499 if (ditu.map[n][m] != 0)500 collidecount++;501 }502 n = posx - 1; m = posy - 1;503

504 { for (; (n != -1) && (m != -1); n--, m--)505 if (ditu.map[n][m] != 0)506 collidecount++;507 }508

509 n = posx + 1; m = posy + 1;510 { for (; (n != 8) && (m != 8); n++, m++)511 if (ditu.map[n][m] != 0)512 collidecount++;513 chess.position[count].collidecount +=collidecount;514 } collidecount = 0;515

516 }517 for (int count = 0; count < 8; count++)518 {519 int posx =chess.position[count].posx;520 int posy =chess.position[count].posy;521 ditu.map[posx][posy] =chess.position[count].collidecount;522 }523

524 }525

526

527

528

529

530 //输出数组

531 void output(int*array)532 {533 for (int i = 0; i <= 63; i++)534 {535 printf("%4.1d", array[i]);536 }537 }538

539

540 voidoutput_globalcollidecount()541 {542 for (int i = 0; i <= 63; i++)543 { //if(global_collidecount_min.mincollidecount[i]!=-1)

544 printf("%4.1d", global_collidecount_min.mincollidecount[i]);545 }546

547 }548

549

550

551 //初始化碰撞数

552 voidinit_globalcollidecount()553 {554 for (int i = 0; i <= 63; i++)555 {556 global_collidecount_min.mincollidecount[i] = -1;557 }558 }559

560

561

562

563

564 //存储棋盘中除皇后位置之外,最小的碰撞数

565 void save_mincollidecount(intglobal_min)566 {567 if (global_collidecount_min.globalmin == -1)568 {569 global_collidecount_min.globalmin =global_min;570 global_collidecount_min.mincollidecount[0] =global_min;571 }572 else

573 {574

575 global_collidecount_min.mincollidecount[number] ==global_min;576

577

578

579 if (global_min

581 }582 }583

584

585

586 //如果碰撞数不小于之前所有棋盘检测的最小碰撞数,返回0,爬山法终止

587 int find_global_collidecount(int global)588 {589

590

591 //global是第一次存入,或者global比global_collidecount_min.globalmin还小

592 if ((global_collidecount_min.globalmin == -1) || (global

599 return 0;600 }601

602

603

604

605 voidHillClimbing()606 {607 intmin;608 initmap(); //初始化地图

609 initpair(); //初始化键值对

610 srand((int)time(NULL)); //随机种子

611 initchess(); //初始化棋盘

612 function1(); //碰撞对数检测

613 function2(); //对除皇后外的其他位置进行碰撞检测,将检测值存于ditu.collidecount3

614 min = visit(); //找出ditu.collidecount3中,皇后之外区域内的最小碰撞数

615

616

617 while (find_global_collidecount(min))//如果碰撞数不小于之前所有棋盘检测的最小碰撞数,返回0,爬山法终止

618 {619 number++;620 countmin(min); //统计棋盘中最小碰撞数的个数,并将最小碰撞数所在位置和值存到pair键值对中

621 reset(); //将地图中的碰撞数ditu.collidecount,ditu.collidecount2,ditu.collidecount3置0;将存储棋盘中最小碰撞数的pair[]还原(置0)

622 function1(); //碰撞对数检测

623 function2(); //检查同列中其他位置上的碰撞数

624 min = visit(); //遍历 pair[]数组,找出最小碰撞数

625 }626 }627

628

629

630 intmain()631 {632 init_globalcollidecount();//初始化碰撞数

633 HillClimbing();//爬山法

634 printf("\n");635 printf("globalmin=%3.1d\n", global_collidecount_min.globalmin);//输出最终的最小碰撞次数

636 output(a);//a数组中记录了爬山过程中,每次棋盘碰撞次数的最小值

637 printf("\n");638 printf("%d", number);//number为爬山次数

639 return 0;640 }

JAVA用爬山法解决八皇后问题_八皇后问题爬山法实现(C语言)相关推荐

  1. hive解决数据倾斜问题_八种解决 Spark 数据倾斜的方法

    有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能. 数 ...

  2. Python:爬山法/随机重启爬山法/允许侧移的爬山法解决八皇后问题

    文章目录 1 八皇后问题 2 程序代码 2.1 程序1 2.2 程序2 2.3 程序3 2.3.1 爬山法 2.3.2 随机重启爬山法 2.3.3 允许皇后侧移的爬山法 3 评价 1 八皇后问题 有一 ...

  3. 爬山法、随机重启爬山法、模拟退火算法对八皇后问题和八数码问题的性能测试...

    代码地址:https://github.com/laiy/AI/tree/master/awesome-search 一些前提: 1. 首先要明确这些算法并不是用于解决传统的搜索问题的(环境是可观察的 ...

  4. 八皇后问题和八数码问题的最陡上升爬山法、首选爬山法、随机重启爬山法、模拟退火算法的分析和实现

    对经典算法的问题的回顾与感想 对八皇后问题和八数码问题分别用最陡上升爬山法.首选爬山法.随机重启爬山法.模拟退火算法来实现,并且分析他们的性能. 分析 要求实现的各个算法是有共同点的,比如,八皇后问题 ...

  5. java 八皇后问题以及N皇后问题

    想了解更多数据结构以及算法题,可以关注微信公众号"数据结构和算法",每天一题为你精彩解答.也可以扫描下面的二维码关注 八皇后的来源 八皇后问题是一个以国际象棋为背景的问题:如何能够 ...

  6. JAVA物联所需技术_基于JAVA多线程技术解决物联云端服务雪崩效应的方法与流程...

    本发明涉及互联网技术领域,特别涉及一种基于JAVA多线程技术解决物联云端服务雪崩效应的方法. 背景技术: 目前,物联云系统已经作为普遍的智能电视平台出现在我们面前,而细致分析物联云系统我们可以发现,当 ...

  7. java 黑白皇后算法_不思议迷宫黑白皇后怎么样 值得培养吗

    不思议迷宫黑白皇后冈布奥怎么样?厉害吗?在游戏中,黑白皇后是来自深渊的咆哮阵营的冒险系冈布奥,玩家可以在主教的阴谋活动副本中获取黑白皇后.那么,黑白皇后有什么技能呢?是否值得培养?下面就和973手游小 ...

  8. 20172311『Java程序设计』课程 结对编程练习_四则运算第一周阶段总结

    20172311『Java程序设计』课程 结对编程练习_四则运算第一周阶段总结 结对伙伴 学号 :20172307 姓名 :黄宇瑭 伙伴第一周博客地址: http://www.cnblogs.com/ ...

  9. java编写桌球游戏素材小球图片_你学不好Java还是有原因的!拿走这套Java系统教程,自学必备...

    很多同学都遇到过一种情况:就是无论自己怎么学Java,到头来发现学的都是皮毛,当真正去用python去做一个项目的时候,脑袋里面一片空白.完全不知道从何做起! 那是你没有系统的学过一次Java,现在的 ...

最新文章

  1. 【视频】云信CTO阙杭宁:IM云开发经验分享
  2. springboot配置servlet容器的两种途径:配置文件及编码方式
  3. C#session共享+redis_Shiro权限管理框架(二):Shiro结合Redis实现分布式环境下的Session共享...
  4. OpenGL GLFW
  5. Find a girl friend
  6. linux系统的安全机制有哪些内容,系统安全机制
  7. 聚类算法教程(3):层次聚类算法Hierarchical Clustering Algorithms
  8. UCOSII学习笔记[开篇]
  9. PMP考试备考指南基础知识
  10. 大盘点!关于无线AP的实用技术,看这篇就够了
  11. php使用逻辑运算符提交程序运行效率
  12. leetcode 89
  13. 明日之后各个服务器的信息,明日之后三个字的和四个字的区什么不同 服务器区别详解...
  14. latex 公式换行、对齐
  15. CentOS 安装软件提示”没有可用软件包XXX
  16. 区块链的前世今生:走向高可靠企业应用
  17. 微信seo搜索精准引流怎么做呢?(案例效果图)
  18. 航模电机绕线LRKDLRK命名来历
  19. Postman测试导入/解析excel接口的方法
  20. MySQL中常用的SQL优化方法

热门文章

  1. 使用RecyclerView实现列表展开动画
  2. Keychron K7 Pro 轻薄矮轴机械键盘开箱体验
  3. 乔布斯那些经典的激励我们的语录
  4. 英语四级XYZ字母开头单词+托福高频单词
  5. 尚硅谷-ShardingSphere
  6. layui数据表格导入Excel,后端打印乱码
  7. 中国苹果之都苹果快成熟了
  8. C/C++新手入门教程:傻瓜都会的VS2013使用教程,成为程序员的第一步
  9. Libre密聊——致力于私密聊天的用心APP
  10. Tree03-TreeAndTreeMethod