今天上午在网上看到了一篇介绍马踏棋盘的贪心算法的文章,就想照着把它实现。可是写到一半,发现原文好像是国际象棋的棋盘。对国际象棋的规则一窍不通,所以就硬着头皮按中国象棋的规则来写。还真的写出来了。

【问题描述】(国际象棋)
马的遍历问题。在8×8方格的棋盘上,从任意指定方格出发,为马寻找一条走遍棋盘每一格并且只经过一次的一条路径。

【问题描述】(中国象棋)
马的遍历问题。在9×10方格的棋盘上,从任意指定点出发,为马寻找一条走遍棋盘每一点并且每点只经过一次的一条路径。

下面是引用原文的关于贪心算法的介绍:

【贪心算法】
其实马踏棋盘的问题很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一个有名的算法。在每个结点对其子结点进行选取时,优先选择‘出口’最小的进行搜索,‘出口’的意思是在这些子结点中它们的可行子结点的个数,也就是‘孙子’结点越少的越优先跳,为什么要这样选取,这是一种局部调整最优的做法,如果优先选择出口多的子结点,那出口少的子结点就会越来越多,很可能出现‘死’结点(顾名思义就是没有出口又没有跳过的结点),这样对下面的搜索纯粹是徒劳,这样会浪费很多无用的时间,反过来如果每次都优先选择出口少的结点跳,那出口少的结点就会越来越少,这样跳成功的机会就更大一些。这种算法称为为贪心算法,也叫贪婪算法或启发示算法,它对整个求解过程的局部做最优调整,它只适用于求较优解或者部分解,而不能求最优解。这样的调整方法叫贪心策略,至于什么问题需要什么样的贪心策略是不确定的,具体问题具体分析。实验可以证明马遍历问题在运用到了上面的贪心策略之后求解速率有非常明显的提高,如果只要求出一个解甚至不用回溯就可以完成,因为在这个算法提出的时候世界上还没有计算机,这种方法完全可以用手工求出解来,其效率可想而知。
下面是我用C#实现的代码。

private int N = 9; private int M = 8; //方向指示 private int[] direct = { 0, 0, 0, 0, 0, 0, 0, 0 }; //棋盘每个点上的标识 public static int[,] board = new int[9, 10]; //马的规则,马走“日”字。 private int[] dx = { 2, 1, -1, -2, -2, -1, 1, 2 }; private int[] dy = { 1, 2, 2, 1, -1, -2, -2, -1 }; //取出所有的子结点的列表 private IList getChild() { IList list = new ArrayList(); for (int i = 0; i < 8; i++) { if (direct[i] == 1) { Hnode hnode = new Hnode(); hnode.x = x + dx[i]; hnode.y = y + dy[i]; list.Add(hnode); } } return list; } //找出出口数数目最小的结点,放在链表的第一位。 public IList sort() { IList list = this.getChild(); int min = 0; for (int i = 0; i < list.Count; i++) { Hnode hnode0 = (Hnode)list[min]; Hnode hnode = (Hnode)list[i]; if (hnode.ways_out() < hnode0.ways_out()) { min = i; } } if (list.Count == 0) { return null; } Hnode hnode1 = (Hnode)list[min]; list.Remove(hnode1); list.Insert(0, hnode1); return list; } //求出口数。 public int ways_out() { int tx, ty, childcount = 0; if (x < 0 || y < 0 || x > M || y > N || board[x, y] > 0) { return -1; } for (int i = 0; i < 8; i++) { tx = this.x + dx[i]; ty = this.y + dy[i]; if (tx < 0 || ty < 0 || tx > M || ty > N) { continue; } if (board[tx, ty] == 0) { childcount++; //在某个方向上有出口,该方向的指示变为1 direct[i] = 1; } } return childcount; } //递归搜索 public void serach(Hnode hn, int count) { if (count >= (M + 1) * (N + 1)) { Console.WriteLine("count={0}", count); Console.WriteLine("完了!"); Console.ReadKey(); } else { Console.WriteLine("x={0},y={1}", hn.x, hn.y); int childcount = hn.ways_out(); // Console.WriteLine("childcount={0}", childcount); board[hn.x, hn.y] = 1; IList list = hn.sort(); if (list == null || list.Count == 0) { Console.WriteLine("count={0}", count); Console.WriteLine("发生错误!"); return; } //for (int i = 0; i < list.Count; i++) //{ // Hnode hnode = (Hnode)list[i]; // Console.WriteLine("x={0},y={1},childcount={2}", hnode.x, hnode.y, hnode.ways_out()); //} serach((Hnode)list[0], count + 1); Console.ReadKey(); } }

以下是运行的效果:

x=0,y=0 x=2,y=1 x=0,y=2 x=1,y=0 x=3,y=1 x=5,y=0 x=7,y=1 x=8,y=3 x=7,y=5 x=8,y=7 x=7,y=9 x=5,y=8 x=3,y=9 x=1,y=8 x=0,y=6 x=1,y=4 x=2,y=6 x=0,y=7 x=1,y=9 x=3,y=8 x=5,y=9 x=7,y=8 x=8,y=6 x=6,y=7 x=8,y=8 x=6,y=9 x=4,y=8 x=2,y=9 x=0,y=8 x=2,y=7 x=1,y=5 x=0,y=3 x=1,y=1 x=3,y=0 x=2,y=2 x=0,y=1 x=2,y=0 x=1,y=2 x=0,y=4 x=2,y=3 x=4,y=2 x=3,y=4 x=4,y=6 x=2,y=5 x=1,y=3 x=0,y=5 x=1,y=7 x=0,y=9 x=2,y=8 x=4,y=9 x=3,y=7 x=1,y=6 x=2,y=4 x=3,y=6 x=5,y=7 x=4,y=5 x=3,y=3 x=4,y=1 x=6,y=0 x=8,y=1 x=6,y=2 x=7,y=0 x=8,y=2 x=7,y=4 x=6,y=6 x=5,y=4 x=3,y=5 x=4,y=7 x=6,y=8 x=8,y=9 x=7,y=7 x=5,y=6 x=4,y=4 x=6,y=5 x=5,y=3 x=3,y=2 x=4,y=0 x=6,y=1 x=8,y=0 x=7,y=2 x=8,y=4 x=7,y=6 x=5,y=5 x=6,y=3 x=5,y=1 x=4,y=3 x=6,y=4 x=8,y=5 x=7,y=3 count=90 完了!

算是做出来了。可是想想这个样子不太直观,所以我就又在winform上画了幅棋盘,然后把经过的路径都画出来。为了看清效果,就定了个时间,每隔一秒钟画一条线。因为我不会做flash,所以只能把最终的图发给大家看看。

画图的程序:

System.Collections.IList list0 = Hnode.list0; Graphics g = this.CreateGraphics(); for (int i = 0; i < list0.Count-1; i++) { int[] aa = (int[])list0[i]; int[] bb = (int[])list0[i+1]; g.DrawLine(new Pen(Color.Red), new Point(150 + aa[0] * 50, 50 + aa[1] * 50), new Point(150 + bb[0] * 50, 50 + bb[1] * 50)); Thread.Sleep(1000); }

最终的效果图如下:

马踏中国象棋棋盘的贪心算法相关推荐

  1. matlab识别中国象棋棋盘,一种基于图像处理的中国象棋识别系统及方法与流程

    本发明涉及计算机图像识别技术,具体涉及一种基于图像处理的中国象棋识别系统及方法. 背景技术: 数字图像处理技术在机器感知领域应用十分广泛,主要目标是通过一些图像处理技术从图像中提取信息,该信息类似于人 ...

  2. 用turtle画中国象棋棋盘

    刚刚学习了<Python入门教程(一)--Python语言基础视频课程>(http://edu.51cto.com/course/12194.html) 中间有道作业就是用turtle画中 ...

  3. JAVA中用程序绘制国际象棋与中国象棋棋盘

    JAVA API 中的绘制图形类的paint()方法,我们可以轻松绘制中国象棋与国际象棋的棋盘.详见代码: 一.中国象棋棋盘代码 import java.awt.Font; import java.a ...

  4. 中国象棋棋盘java_java绘制国际象棋与中国象棋棋盘

    JAVA API 中的绘制图形类的paint()方法,我们可以轻松绘制中国象棋与国际象棋的棋盘.详见代码: 一.中国象棋棋盘代码 import java.awt.Font; import java.a ...

  5. 如何用Python画一个中国象棋棋盘?

    今天试着画了一个中国象棋棋盘! #绘制象棋盘 import turtle      t=turtle.Pen() t.speed(100) def angle(x,y):     t.penup() ...

  6. C++实现双人中国象棋(一)——算法篇(附完整代码)

    一.简介 最近突发奇想,要使用C++做一个双人象棋的程序,昨天肝了一天,终于把算法部分完成了,下面把开发过程中的经验分享一下. 开发环境:Visual Studio 2019 语言标准:C++11及以 ...

  7. 中国象棋棋盘c语言编程,中国象棋 C语言编程.ppt

    中国象棋 C语言编程 双人对弈中国象棋 程序所负责内容介绍 计算机生成红黑双方以及棋盘. 各个棋子的移动. 当危险时显示被"将军". 分支思路 1.棋盘棋子的制作与输出 棋盘 走子 ...

  8. java中国象棋棋盘放置棋子,JAVA简易文字版中国象棋

    大二时制作的JAVA简易文字版中国象棋,现在放出,希望大家喜欢! // Java core packages import java.awt.*; import java.awt.event.*; / ...

  9. 中国象棋棋盘java_Java中国象棋博弈程序探秘[2]——棋盘的表示

    棋盘的表示 转载请保留作者信息: 作者:88250 MSN & Gmail & QQ:DL88250@gmail.com 在象棋博弈程序中,首先我们要确定下棋盘-棋子的数据结构描述. ...

最新文章

  1. 转 深入理解Midlet类
  2. 关于当前所用的MVP架构的所思所想
  3. mysql 定时同步数据_如何定时备份Mysql数据库数据?
  4. 休眠事实:集成测试策略
  5. 作者:陈威,电子科技大学互联网科学中心硕士生。
  6. 计算机考研雷区,考研的五大雷区是什么 如何避免
  7. jquery-animate()动画
  8. Atitit jfugue midi make tour attilx sumup 目录 1.1. Jyepu prob not support ,gazi nonge map trans支持简谱解决
  9. java毕业设计——基于java+jsp+Tomcat的电子书下载系统设计与实现(毕业论文+程序源码)——电子书下载系统
  10. Linux之top命令
  11. Android——一个简单的银行系统
  12. PPT图标库 iSlide 阿里iconfont
  13. 智慧路灯网关下的校园智慧路灯照明解决方案
  14. 公司网站应该外包SEO公司还是自己去做?
  15. 一个bug看一天,写代码像cxk
  16. 学计算机发朋友圈文案,2020开学发朋友圈文案句子精选100句
  17. Rocketmq广播消费模式怎么扩展消费者
  18. EasyUI TreeGrid各行调整上下位置
  19. 相册照片直播小程序开发
  20. 今天win10弹出了flash助手,禁用它

热门文章

  1. TensorFlow+Pytorch识别阿猫阿狗
  2. 一起学爬虫(Python) — 18 一生之敌查帕斯
  3. Linux Shell - 脚本中自动确认需要输入确认的命令
  4. 国产化7K325T板卡学习资料: 基于国产化Ch-7K325T 的 FMC接口PCIe卡 国产化板卡
  5. 【手把手教你】使用Python构建股票财务指标打分系统
  6. 360html格式转换word,将Word文档转化为HTML格式的文档
  7. Python数据可视化之散点图(进阶篇---图文并茂详细版!!!)
  8. Linux 执行命令不挂断
  9. 仿金山打字通游戏 Java代码
  10. 终于装好titan x显卡驱动