栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

骑士巡回赛-导致无限循环,我不知道为什么

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

骑士巡回赛-导致无限循环,我不知道为什么

您的算法似乎运行良好,可以为较小的问题实例(例如5x5或7x7电路板)提供正确的结果。对于强力
/回溯方法来说,似乎8x8板太大了。

尽管如此,您仍然可以简化

findTour
方法,使其更易于理解和调试:

public boolean findTour(int x, int y, int c) {    solutionBoard[x][y] = c;    if (c == size*size) {        return true;    }    for (Point p : MOVES) {        Point dst =  new Point(x + p.x, y + p.y);        if (canMove(dst) && findTour(dst.x, dst.y, c + 1)) { return true;        }}    solutionBoard[x][y] = -1;    return false;}

findTour(0, 0, 1)
with的示例输出
size = 7
(需要使所有代码适应可变大小!)

 1 14  3 38  5 34  7 12 39 10 33  8 37 26 15  2 13  4 25  6 35 40 11 32  9 36 27 44 19 16 21 24 45 48 29 22 41 18 31 28 43 46 17 20 23 42 47 30 49

更好的方法是:使用Wikipedia文章中提到的其他算法之一,例如相当简单的Warnsdorff启发式算法:
“我们移动骑士,以便我们始终前进到骑士前进最少的位置。”

我们可以通过排序动作来实现这一目标…

public Point[] sortedPoints(final int x, final int y) {    Point[] sorted = Arrays.copyOf(MOVES, MOVES.length);    Arrays.sort(sorted, new Comparator<Point>() {        public int compare(Point p1, Point p2) { return Integer.signum(nextMoves(p1) - nextMoves(p2));        };        private int nextMoves(Point p) { Point dst = new Point(x + p.x, y + p.y); if (canMove(dst)) {     int s = 0;     for (Point m : MOVES) {         Point dst2 = new Point(dst.x + m.x, dst.y + m.y);         if (canMove(dst2)) {  s++;         }     }     return s; } else {     return 999; }        }    });    return sorted;}

…,并将后继者循环更改为

for (Point p : sortedPoints(x, y))
。结果:

size     findTour calls without and with heuristic5x5          76497       25 7x7          8947880     498x8          ???         6420x20        ???         400

确实,对于我尝试过的所有尺寸,该

findTour
方法都称为 精确
size^2
时间,即它在第一次尝试时就找到了游览路线,而根本没有回溯。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/394806.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号