广度优先搜索并打印出Kevin Bacon Path,重新访问受访节点?

时间:2012-11-26 21:15:07

标签: java shortest-path breadth-first-search

我在尝试查找Kevin Bacon号码的程序中实现广度优先搜索时遇到了一些麻烦。我创建了一个存储访问节点的临时哈希集,但程序仍在重新访问节点,尽管我从列表中删除了我反馈到队列中的节点。

演员和电影的信息存储在HashMap(字符串,HashSet(字符串))中 - 所以如果你把一个演员作为一个键,你可以获得他们演出的电影,如果你把电影放入关键,你得到了行动的演员。下面是我的代码和System.out.prints打印的内容。谢谢您的帮助!

public List<String> findBaconPath (String actor) throws IllegalArgumentException {
    ArrayList<String> list = new ArrayList<String>();
    HashSet<String> visited = new HashSet<String>();
    visited.add(actor);
    LinkedList<String> bfs = new LinkedList<String>();
    bfs.add(actor);
    while (!bfs.isEmpty()){
        String curr = bfs.remove(); //The current actor we are looking at.
        visited.add(curr);
        HashSet<String> mov = myMovies.get(curr);
        Iterator<String> it = mov.iterator();
        while (it.hasNext()){
            String next = it.next(); //The next movie in the iterator.
            visited.add(next);
            HashSet<String> coStars = myMovies.get(next);
            coStars.removeAll(visited);
            if (coStars.contains("Bacon, Kevin")){
                list.add(curr);
                list.add(next);
                list.add("Bacon, Kevin");
                System.out.println(list.toString());
                return list;
            }
            else {
                list.add(curr);
                list.add(next);
                System.out.println("This is what is in visited: "+visited.toString());
                System.out.println("This is what is in coStars pre removal. "+ coStars.toString());
                coStars.removeAll(visited);
                System.out.println("This is what is in coStars post removal. "+ coStars.toString());
                Iterator<String> cos = coStars.iterator();
                while (cos.hasNext()){
                    bfs.add(cos.next());
                }
            }
        }

    }
    return list;
}
  • 这就是所访问的内容:[D,电影7]
  • 这是coStars预删除中的内容。 [D,A,B,C]
  • 这是删除coStars后的内容。 [A,B,C]
  • 这就是所访问的内容:[D,电影7,电影2]
  • 这是coStars预删除中的内容。 [D,E,A,B]
  • 这是删除coStars后的内容。 [E,A,B]
  • 这就是所访问的内容:[D,A,电影7,电影2]
  • 这是coStars预删除中的内容。 [A,B,C]
  • 这是删除coStars后的内容。 [B,C]
  • 这就是所访问的内容:[D,A,电影7,电影2]
  • 这是coStars预删除中的内容。 [E,A,B]
  • 这是删除coStars后的内容。 [E,B]
  • 这就是所访问的内容:[D,A,电影7,电影2,电影1]
  • 这是coStars预删除中的内容。 [A,B,C]
  • 这是删除coStars后的内容。 [B,C]
  • [D,电影7,D,电影2,A,电影7,A,电影2,A,电影1,A,电影0,培根,凯文]

1 个答案:

答案 0 :(得分:0)

如果您更好地区分访问列表中的电影和演员而不是混合它们,这可能会有所帮助。类似的东西:

[(Movie1, Actor1, Actor2), (Movie2, Actor1, Actor2, Actor3)]

然后,当您删除所有内容时,您始终可以通过电影标题识别“已访问”中的条目。

此外,每个循环都会调用removeAll两次。一次就在'if(coStars.contains(“培根,凯文”)){'之前,再次在你打印'去除后'之前。

不,这是答案吗?电影7,电影2,电影1,电影0