深度优先搜索父级,距离,完成Java问题

时间:2018-12-13 06:24:10

标签: java depth-first-search

我的DFS出现问题。因此,我相信我实际的深度优先搜索是可行的,但是我的父节点(pi),距离(d)和结束(f)会返回一些奇怪的数字。

我一直非常仔细地跟踪伪代码,将变量与书中DFS示例中的变量完全一样。

enter image description here

我的策略是在DFS函数中传递4个ArrayList:顶点(当前顶点),pi(父),d(距离),f(完成)的总顶点数的大小并添加值在递归中。

DFS

    enum VertexState {
White, Gray, Black}

// The function to do DFS traversal. It uses recursive DFSVisit()
//passes in 4 array lists (vertex, pi, d, f) that keep track of current vertex, parent node, distance, and finish times respectively
public void DFS(List<Integer> vertex, List<Integer> pi, List<Integer> d, List<Integer> f)
{
    VertexState state[] = new VertexState[numberOfVertices()];

    // Mark all the vertices as white (not visited)
    for (int i = 0; i < numberOfVertices(); i++) {
        state[i] = VertexState.White;
    }

    int time = 0; //initialize time

    // Call the recursive helper function to print DFS traversal
    // starting from all vertices one by one
    for (int i = 0; i < numberOfVertices(); i++) {
        if( state[i]== VertexState.White)
        DFSVisit(i, state, vertex, pi, d, f, time);
    }
}


// A function used by DFS
//passes in u (current node) and it's state (color)
//passes in 4 array lists (vertex, pi, d, f) that keep track of current vertex, parent node, distance, and finish times respectively
public void DFSVisit(int u, VertexState[] state, List<Integer> vertex, List<Integer>pi, List<Integer>d, List<Integer>f, int time)
{
    time=time+1; //increment time (white vertex u has been discovered)
    d.add(time); //add current time int to distance array list

    // Mark the current node as gray (visited)
    state[u] = VertexState.Gray;

    vertex.add(u); //add current node to vertex array list

    // Recur for all the vertices adjacent to this vertex
    Iterator<Integer> i = adjacencies[u].listIterator();
    while (i.hasNext())
    {
        int n = i.next();
        if (state[n]==VertexState.White)
        {
            pi.add(n); //add current node to parent array list
            DFSVisit(n, state, vertex, pi, d, f, time);
        }
    }
    state[u] = VertexState.Black; //mark current node as black (it is finished)
    time=time+1; //increment time
    f.add(time); //add current time int to f (finished) array list
}
}

驱动程序

package com.company;
import java.util.ArrayList;
import java.util.List;

public class Main {

public static void main(String[] args)
{
    //GENERATED GRAPHS
    Graph g = new Graph(10, 0.3);
    System.out.println("The graph is");
    System.out.println( g.toString());
    System.out.println("It had " + g.numberOfVertices() + " vertices and " + g.numberOfEdges() + " edges.");

    //initialize array lists to print
    List<Integer> vertex = new ArrayList<Integer>(g.numberOfVertices());
    List<Integer> pi = new ArrayList<Integer>(g.numberOfVertices());
    List<Integer> d = new ArrayList<Integer>(g.numberOfVertices());
    List<Integer> f = new ArrayList<Integer>(g.numberOfVertices());

    //depth first search
    g.DFS(vertex,pi,d,f);

    //print array lists
    System.out.println("Vertex:   "+vertex);
    System.out.println("Parent:   "+pi);
    System.out.println("Distance: "+d);
    System.out.println("Finish:   "+f);

}
}

输出如下:

图形是

0:[1、5、7]

1:[2、6、8、9]

2:[1、3、4]

3:[0,1,2,8]

4:[1,4]

5:[0,4,6]

6:[2,6,8]

7:[0,8]

8:[5]

9:[3,8]

它有10个顶点和27条边。

顶点:[0、1、2、3、8、5、4、6、9、7]

父母:[1、2、3、8、5、4、6、9、7]

距离:[1、2、3、4、5、6、7、7、3、2]

完成:[8、8、7、6、5、4、4、3、3、2]

1 个答案:

答案 0 :(得分:0)

首先,您应该打印期望的值。

我没有检查整个代码,但是f肯定包含错误的值。

  1. 列表d和f的顺序相反。
  2. 该值将始终为d +1,因为该值不会从递归调用中“增加”。

因此,以下建议可克服这些错误。请勿混合使用列表和数组,因为您的访问权限已“中断”。坚持使用数组。或者更好的方法是,使每个顶点“拥有”一个真实的属性对象,例如(伪代码)

public class VertexAttribute {
  VertexState state;
  Object parent;
  int distance;
  int finished
}

并且将这些属性的列表传递给您的“ helper”方法,并且您永远不会混合使用不同顶点的属性。