- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用回溯法解决骑士的巡回问题。我认为我的算法应该有效。我试过了,但我不明白为什么它不起作用。它会导致无限循环。
但是,如果我注释掉回溯 solutionBoard[dst.x][dst.y]=-1;
行,它会起作用!我只是不明白为什么!任何帮助,将不胜感激。
private int solutionBoard[][] = new int [8][8];
// The eight possible moves a knight can make from any given position
private static final Point[] MOVES = new Point[] { new Point(-2, -1),
new Point(-2, 1), new Point(2, -1), new Point(2, 1),
new Point(-1, -2), new Point(-1, 2), new Point(1, -2),
new Point(1, 2) };
private int count = 0;
public KnightsTour_DFS(){
// board is 0- 7
//initialize visited
for(int i =0; i<8;i++){
for(int j = 0; j< 8; j++){
solutionBoard[i][j] = -1;
}
}
solutionBoard[0][0]=count++;
if(findTour(0, 0)){
System.out.println("Tour found!!");
printSolution();
}
}
public boolean findTour(int x, int y){
if(x <0 || y <0 || x>7 || y > 7 ){
return false;
}
if(count == 64){
//we've covered all node
return true;
}
for(int i = 0; i < this.MOVES.length; i++){
Point dst = new Point(x + MOVES[i].x, y + MOVES[i].y);
if(canMove(dst)){
solutionBoard[dst.x][dst.y]=count++;
if(findTour(dst.x, dst.y)){
System.out.println("Solution shown on board\n");
return true;
}
else{
count --;
solutionBoard[dst.x][dst.y]=-1;
}
}
}
return false;
}
private void printSolution() {
System.out.println("Solution shown on board\n");
for (int[] rows : solutionBoard) {
for (int r : rows) {
System.out.printf("%2d ", r);
}
System.out.println();
}
}
public boolean canMove(Point destination){
if(destination.x<0 || destination.y<0 || destination.x>7|| destination.y>7){
return false;
}
if(solutionBoard[destination.x][destination.y] != -1){
//already visited
return false;
}
return true;
}
最佳答案
您的算法似乎工作得很好,对于较小的问题实例(例如 5x5 或 7x7 板)会产生正确的结果。好像是 8x8 board is just too big for the brute force/回溯法。
不过,您可以简化您的 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)
的示例输出,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
更好:使用维基百科文章中提到的其他算法之一,例如相当简单的 Warnsdorff 启发式算法:"We move the knight so that we always proceed to the square from which the knight will have the fewest onward moves."我们可以通过对移动进行排序来实现这一点...
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 heuristic
5x5 76497 25
7x7 8947880 49
8x8 ??? 64
20x20 ??? 400
事实上,对于我尝试过的所有尺寸,findTour
方法被调用了 exactly size^2
次,即它在第一次尝试,完全不回溯。
关于java - 骑士之旅 - 导致无限循环,我不明白为什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24558120/
我尝试运行稍微修改过的 horsemanjs 的示例代码: var Horseman = require('node-horseman'); var horseman = new Horseman()
我在 Isometric camera with THREE.js 中找到了有关如何创建(轴测)等距相机的示例,但如何创建轴测斜线? 最佳答案 您可以渲染带有倾斜的场景 cabinet perspec
我正在尝试在 horseman 的 evalute 函数中使用 promises。一个简单的例子: var Horseman = require('node-horseman'); var horse
我试图在调试期间查看 List<> 的内容。不幸的是我看不到它们,因为我在变量窗口中收到以下消息: corvalue.GetExactTypeSafe(out type). The object is
Rider IDE 通知我以下内容效率低下 transform.Translate(moveDirection * speed * Time.smoothDeltaTime); 并想将
是否有一种简单的方法可以在 Visual Studio 之外使用旧的 EF 来搭建脚手架迁移?如果可能的话,我想通过 Rider IDE 来完成。 最佳答案 对于 EF Core,您可以使用 http
在 Rider 中,当在断点处暂停时,有没有办法在调试器堆栈帧中实际显示“外部代码”? 在 Visual Studio 中,这可以轻松完成,但在 Rider 中似乎不可能。而且,是的,我启用了“exa
我试图通过更改其环境变量来修改 Linux 上 JetBrains Rider 中 .NET 项目的设置配置文件。但是,当我点击文件夹图标时,我无法点击添加、删除或修改任何环境变量。 我注意到在 Ri
只是试用 Rider 并遇到了这个问题,如果我只是构建 Xamarin Android 项目 - 它构建得非常好,但是如果我尝试运行它,它会在部署步骤失败并出现以下错误: ▼ Project Not
当我在 Jetbrains Rider EAP 21 中创建解决方案时,我在解决方案资源管理器窗口中收到“(缺少包)”错误。 然后,我尝试构建项目并获得 [MSB4057] 错误。 尽管如此,我可以通
我是一名优秀的程序员,十分优秀!