我在Java中使用递归函数(图论)来获取4x4表中的所有路径,从随机起点开始。可能的方向是水平,垂直和对角线,但我要求相同的位置不能访问两次。
到目前为止,脚本运行正常,我得到了很多组合。问题是在函数的for循环中,当有多种可能的方法时,我在第二个和后面的循环中得到错误的结果,因为boolean [] tempvisited没有回到他的旧值。
我希望有人能够理解我的英语和我的问题。到目前为止,这是我的代码:
// here I define a constant input of values:
String letters = "1548987425461854"
// This matrix shows all possible directions from every startpoint in the matrix:
// from the second value, you may get to the following locations: 1,3,5,6 and 7
private int[][] matrix = {
{1,4,5},
{0,2,4,5,6},
{1,3,5,6,7},
{2,6,7},
{0,1,5,8,9},
{0,1,2,4,6,8,9,10},
{1,2,3,5,7,9,10,11},
{2,3,6,10,11},
{4,5,9,12,13},
{4,5,6,8,10,12,13,14},
{5,6,7,9,11,13,14,15},
{6,7,10,14,15},
{8,9,13},
{8,9,10,12,14},
{9,10,11,13,15},
{10,11,14}
};
// Here begins the recursive function
public List<Combination> depthFirst(int vertex, boolean[] visited, Combination zeichen, List<Combination> combis){
// A temporary list of booleans to mark every value position visited or not
boolean[] tempvisited = new boolean[16];
// combis is the whole list of ways, zeichen is just the actual combination
zeichen.name = zeichen.name + this.letters.charAt(vertex);
combis.add(zeichen.name);
//marks actual value as visited
visited[vertex] = true;
for(int i = 0; i < 16; i++){
tempvisited[i] = visited[i];
}//end for
// going to next possible locations
for (int i = 0; i < this.matrix[vertex].length; i++) {
if (!visited[this.matrix[vertex][i]]) {
combis = depthFirst(this.matrix[vertex][i], tempvisited, zeichen, combis);
}//end if
}//end for
return combis;
}
答案 0 :(得分:0)
您对tempvisited
有正确的想法,并制作副本。但是你在错误的地方这样做了。
您正在设置visited[vertex] = true
,这意味着您传入的visited
正在发生变化。你想要的是visited
永远不会改变。复制一份,然后对该副本进行更改。
另外,我注意到你每次都使用相同的zeichen
。因此,如果您有一个3步长的路径,则您的combis
列表将包含相同zeichen
的3个副本。这似乎不正确。
答案 1 :(得分:0)
在第一个for循环之前,将visited [vertex]设置为true;您可以在返回之前将其重置为false。如果每次调用都撤消它所做的更改(直接),那么每次调用都将返回,并在调用时返回到其状态。没有必要的温度。
答案 2 :(得分:0)
深入了解深度优先搜索(DFS)的其他递归解决方案(伪代码)。
void search(Node root) {
if (root == null) return;
visit(root);
root.visited = true;
foreach (Node n in root.adjacent) {
if (n.visited == false)
search(n);
}
}
答案 3 :(得分:0)
实际上,您不需要访问数组的副本。在深度查询的reccurrent调用之前将节点标记为已访问,然后在调用之后立即“取消标记”它。类似的东西:
for (int i = 0; i < this.matrix[vertex].length; i++) {
if (!visited[this.matrix[vertex][i]]) {
visited[this.matrix[vertex][i]] = true;
combis = depthFirst(this.matrix[vertex][i], tempvisited, zeichen, combis);
visited[this.matrix[vertex][i]] = false;
}//end if
}//end for