【问题标题】:Find shortest path between two webpages查找两个网页之间的最短路径
【发布时间】:2009-12-14 17:02:35
【问题描述】:

我需要找到两个维基百科页面之间的最短距离(以“跳数”计)

我有一种方法可以提取页面上的所有内部 wiki 链接

我知道起点和终点,但我对如何从数据中提取跃点一无所知

到目前为止,我一直在使用链接提取方法来填充字典,其中键是页面上的链接,值是它被删除的页面。

如果有人对保存信息以及如何查看信息有什么好的数据结构有任何想法,我将不胜感激

【问题讨论】:

    标签: c# loops recursive-datastructures


    【解决方案1】:

    你知道graph theory吗?您拥有构建图表所需的数据,但您需要使用 Dijkstra's algorithm 遍历它以找到两点之间的最短路径。

    【讨论】:

    • 是的。或者在这种情况下进行简单的广度优先搜索,因为所有边的权重都是 1 次点击。
    • @CaptnCraig - 是的,我认为你是对的。我试图记住我所有的图形算法,但我发现了 Dijkstra 的,所以我停止寻找 ;)
    【解决方案2】:

    也许这有点愚蠢,因为我不是真正的 C# 程序员,但包含内部所有链接的多维数组会根据维度的深度让您知道哪种方式包含更少的箍。

    这只是一个想法,虽然这在理论上肯定是可行的,因为对数组可以具有的维度数量没有语言限制,我很确定它会非常消耗内存!

    类似这样的:

    [source] -> [source link] -> ['source link' link] -> etc
             -> [source link] -> ['source link' link] -> etc
             -> [source link] -> ['source link' link] -> etc
             -> [source link] -> ['source link' link] -> [target]
             -> [source link] -> ['source link' link] -> etc
    

    【讨论】:

      【解决方案3】:

      这是 Dijkstra 算法在 python 中的实现:http://code.activestate.com/recipes/119466/

      【讨论】:

        【解决方案4】:

        假设你有一个IEnumerable<Link> PageLinks(Link link)

        跳数可以通过以下方式解决:

        Link curentPage = "somepage";
        Link destinationPage = "otherpage";
        if (currentPage == destinationPage) return 0;
        int hops = 1;
        IEnumerable<Link> currentLinks = PageLinks(currentPage);
        IEnumerable<Link> visited = new [] {currentPage};
        while(!currentLinks.Contains(destinationPage)) 
        {
            currentLinks = currentLinks
                .SelectMany(l => PageLinks(l).Where(f => !visited.Contains(f)));
            visited = visited.Union(currentLinks);
            hops++;
        }
        return hops;
        

        经过编辑以加快骑行速度,尽管如果没有它,该算法也可以工作。如果页面没有链接,它可能会一直运行到 StackOverflow 左右。

        【讨论】:

        • 非常好。我喜欢您使用 IEnumerables 来包含内存,同时循环遍历呈指数增长的数据集。但是对于问题中的循环图,您不需要循环检测吗?此外,在永远找不到目的地的情况下,您还需要一个终止条件。
        【解决方案5】:

        我认为在这种情况下图表是稀疏的。因此,为每个 Wikipedia 页面使用 HashSet 之类的东西可能是一个好主意,它链接到集合内的页面。

        在这种情况下,您实际上不需要实现 Dijikstra 的最短路径算法。因为这等于每条边的权重等于 1 的最短路径问题。您可以执行 Breadth-first search 并获取找到目标页面的深度。

        【讨论】:

        • 是的,CaptnCraig 已经发表了这条评论 - 广度优先也可以。
        猜你喜欢
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 2018-09-18
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 2021-05-25
        相关资源
        最近更新 更多