我正在尝试实施这个问题的解决方案,但我遇到了一些问题。
问题是:
“在r行和c列的网格的左上角有一个机器人。机器人只能向右或向下移动,某些单元格是“禁止”的,这意味着机器人不能踩它们。设计一个算法来为机器人找到从左上角到右下的路径。”
解决方案如下所示:
public static ArrayList<Point> getPath(boolean[][] maze){
if(maze == null || maze.length==0) return null;
ArrayList<Point> path = new ArrayList<Point>();
HashSet<Point> failedPoints = new HashSet<Point>();
if(getPath(maze, maze.length-1,maze[0].length-1,path,failedPoints)){
return path;
}
return null;
}
public static boolean getPath(boolean[][] maze, int row, int col,
ArrayList<Point> path, HashSet<Point> failedPoints){
/*if out of bounds or not available, return*/
if(col<0 || row<0 || !maze[row][col]){
return false;
}
Point p = new Point(row,col);
/*If we've already visited this cell return*/
if(failedPoints.contains(p)){
System.out.println("Worked");
return false;
}
boolean isAtOrigin = (row == 0) && (col == 0);
/*If there's a path from start to my current location, add my location.*/
if(isAtOrigin || getPath(maze,row,col -1, path, failedPoints) || getPath(maze,row-1, col, path,failedPoints)){
path.add(p);
return true;
}
failedPoints.add(p); //Cache result
return false;
}
让我困惑的是动态编程的尝试。
if(failedPoints.contains(p))
从不计算为true
。
我已经覆盖了Point类中的equals
和hashCode
方法,所以失败了。只要所比较的对象具有相同的行和列值,contains(对象)就会计算为true。
也许这与我使用的迷宫输入有关:
boolean[][] maze = new boolean[4][4];
java.util.Arrays.fill(maze[0],true);
java.util.Arrays.fill(maze[1],true);
java.util.Arrays.fill(maze[2],true);
java.util.Arrays.fill(maze[3],true);
maze[0][1] = false;
maze[3][2] = false;
ArrayList<Point> path = getPath(maze);
但我不确定。最后,我看不出是如何失败的。包含(p)
正在保存我的计算机的任何执行步骤
这是点类:
public class Point {
int row;
int col;
Point(int row1,int col1) {
row = row1;
col = col1;
}
public boolean equals(Object o) {
if (!(o instanceof Point)) return false;
Point comp = (Point) o;
return comp.row == row && comp.col == col;
}
public int hashCode() {
return row;
}
}
这是你迷宫的设计。
这是你的迷宫,根据你在问题中的输入:
E O O O
O O O O
O O X X
O O X S
你从S
开始,试图到达E
,而X
是超限位置。
所以,你可以看到,随着S
被完全覆盖了超限点,你不可能到达E
。因此,第一个点S
是一个失败点,它永远不会被重复使用,因为算法在计算S
后停止。
如果您将0th行和1st列中的点设置为off-limit,您将有多个探索到达该点,并利用缓存来确定该点不能进一步用于探索迷宫。
更新:
在你更新了迷宫之后,我意识到你的实现有两个问题,而不是一个。
换线,
if(isAtOrigin | | getPath(迷宫,行,列-1,路径,失败点)| | getPath(迷宫,行-1,列,路径,失败点))
到
if(isAtOrigin||getPath(迷宫, row-1, coll, path,失败点)||getPath(迷宫, row, col-1, path,失败点))
这段代码将实际用于新的迷宫。
问题是您一找到路径就从getPath()
返回。因为您首先向左然后向上,所以点[0,2](这是一个失败的点)根本没有命中,因此没有缓存,因此也没有使用。
更改if条件会导致算法先向上搜索,然后向左搜索。这会导致您多次点击[0,2],导致它被缓存,并在进一步的路径搜索中重复使用。
计算机科学中的许多程序是为了优化一些值而编写的; 例如,找到两个点之间的最短路径,找到最适合一组点的线,或找到满足某些标准的最小对象集。计算机科学家使用许多策略来解决这些问题。本书的目标之一是向你展示几种不同的解决问题的策略。动态规划 是这些类型的优化问题的一个策略。 优化问题的典型例子包括使用最少的硬币找零。假设你是一个自动售货机制造商的程序员。你的公司希望通过给每个交易最少硬币来简化工作。假设
*正则匹配问题[H] 三角形问题[M] 计算二进制数中1的个数[M] *括号匹配问题[M] 最短路径和[M]
主要内容:动态规划算法的实际应用动态规划算法解决问题的过程和分治算法类似,也是先将问题拆分成多个简单的小问题,通过逐一解决这些小问题找到整个问题的答案。不同之处在于,分治算法拆分出的小问题之间是相互独立的,而动态规划算法拆分出的小问题之间相互关联,例如要想解决问题 A,必须先解决问题 B 和 C。 《贪心算法》一节中,给大家举过一个例子,假设有 1、7、10 这 3 种面值的纸币,每种纸币使用的数量不限,要求用尽可能少的纸币拼凑
斐波那契数列 1. 爬楼梯 2. 强盗抢劫 3. 强盗在环形街区抢劫 4. 信件错排 5. 母牛生产 矩阵路径 1. 矩阵的最小路径和 2. 矩阵的总路径数 数组区间 1. 数组区间和 2. 数组中等差递增子区间的个数 分割整数 1. 分割整数的最大乘积 2. 按平方数来分割整数 3. 分割整数构成字母字符串 最长递增子序列 1. 最长递增子序列 2. 一组整数对能够构成的最长链 3. 最长摆动子
我有一个子集问题的工作代码,如果它发现一个子集等于所需的目标,它可以打印数字。 > 我想打印给定目标的所有可能的子集,我不知道要为此更改什么。 我如何让它对负数起作用?
我试图将所有的值和容量除以1.000.000,但这会产生浮点,我认为这不是正确的方法。我也试图使数组和矩阵的类型长,但这没有帮助。也许是另一种数据结构?欢迎任何建议... 代码: