You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Haskell自定义图类型实现无环路径枚举函数paths的求助

Haskell 无环路径函数实现

嘿,咱们先把题目给定的基础定义和示例图明确下来,这是实现的前提:

类型定义

type Node = Integer
type Edge = (Integer, Integer)
type Graph = [Edge]
type Path = [Node]

示例图

g :: Graph
g = [(1,2), (1,3), (2,3), (2,4), (3,4)]

h :: Graph
h = [(1,2), (1,3), (2,1), (3,2), (4,4)]

实现paths函数

要生成所有从起点到终点的无环路径,核心就是不能走回头路——得时刻记住已经访问过哪些节点。我写了个带辅助函数的实现,主函数负责初始化参数,递归逻辑交给辅助函数处理:

完整代码

paths :: Node -> Node -> Graph -> [Path]
paths start end graph = pathsHelper start end graph [start] [start]
  where
    pathsHelper :: Node -> Node -> Graph -> [Node] -> [Node] -> [Path]
    -- 递归终止:当前节点就是终点,返回这条有效路径
    pathsHelper curr end _ _ path | curr == end = [path]
    pathsHelper curr end graph visited path =
      -- 筛选出所有从当前节点出发、且未被访问过的下一个节点
      let nextNodes = [to | (from, to) <- graph, from == curr, to `notElem` visited]
      -- 对每个下一个节点递归探索,最后合并所有路径
      in concatMap (\next -> pathsHelper next end graph (next:visited) (path ++ [next])) nextNodes

代码拆解

  • 主函数paths初始化已访问列表为[start](一开始只有起点被走过),当前路径也设为[start],然后调用辅助函数。
  • 辅助函数的终止条件很直观:如果当前节点就是终点,直接返回这条路径。
  • 非终止情况时,先筛选出符合要求的下一个节点(必须是当前节点的邻接点,且没被访问过),然后对每个节点递归探索,把所有递归得到的路径合并成一个大列表。

测试验证

调用paths 1 4 g的预期输出是:

[[1,2,3,4],[1,2,4],[1,3,4]]

(给定的图g里,这就是所有从1到4的无环路径啦)

内容的提问来源于stack exchange,提问作者nwelch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:51:43