Haskell中的图表示

Haskell中的图表示,haskell,graph,Haskell,Graph,我选择用节点列表(例如n=[1,2,3,4])和表示边的对列表(例如m=[(1,2)、(2,3)])来表示Haskell中的图。现在我要看看这个图是否是强连通的 我的主要问题是如何找到图中两个节点之间是否存在路径。我写了这样的东西: -- sees if 2 nodes are adjacent adjacent x y [] = False adjacent x y (mu:m) = if(x== (fst mu) && y==(snd mu)) the

我选择用节点列表(例如
n=[1,2,3,4]
)和表示边的对列表(例如
m=[(1,2)、(2,3)]
)来表示Haskell中的图。现在我要看看这个图是否是强连通的

我的主要问题是如何找到图中两个节点之间是否存在路径。我写了这样的东西:

-- sees if 2 nodes are adjacent

adjacent x y [] = False

adjacent x y (mu:m) =  
        if(x== (fst mu) && y==(snd mu)) then True  
        else adjacent x y m

-- the successor of a node, ex for the edge (1,2) the succ of 1 is 2  
suc x [] = 0  
suc x (l:list) =   
        if(x==(fst l)) then snd l  
        else suc x list

-- my main function
way 0 y list = False 

way x y (mu:m)  
    | x==y = True  
    | (adjacent x y (mu:m)) == True = True  
    | otherwise =   
        if ((way (suc x (mu:m)) y (mu:m))==False) then way (suc x m) y m  
        else True  

当节点的阶数为1时,它可以工作,但对于阶数较大的节点,它并不总是工作。你能给我一个线索吗?

你有两个理解错误:

  • m
    ,在整个搜索过程中,您的边列表是静态的。当你以
    的方式反复出现时,不要把它吃掉
  • 每个顶点可以有多条边离开它。您想知道x的邻域中是否有
    到y的
    路径。要找到邻居,首先必须对边列表进行
    过滤
    以仅查找离开x的边
  • 你还需要建立一个你在寻找连接时已经访问过的节点列表。如果您在已经看到的节点上结束,则该特定路径已失败

    一些使代码更短的提示:对于
    相邻的
    ,请尝试
    elem

    对于
    succ
    ,请尝试
    Data.Maybe.fromMaybe
    lookup

    以下是要问自己的一些问题:

  • 相邻的32[(1,2),(2,3)]
  • 应该是
    真的吗
    
  • [(1,2)、(2,3)、(1,4)、(3,4)]
  • 为什么
    way
    需要一个
    x==y
    案例和一个
    相邻的xy…
    案例
  • way
    的递归步骤中,
    ==False
    测试是否真的告诉了您一些让您在
    m
    的较小图形上递归的东西
  • 通常,您还没有为顶级函数编写类型签名。这样做通常很有启发性,并且可以更清楚地传达您的设计:

    type Vertex = Int
    type Edge = (Vertex, Vertex)
    type Graph = [Edge]
    
    adjacent :: Vertex -> Vertex -> Graph -> Bool
    suc :: Vertex -> Graph -> Vertex
    way :: Vertex -> Vertex -> Graph -> Bool
    
    考虑一下这些类型是否有意义,以及它们是否如您所期望的那样分解了您的问题,只需考虑一般的图形

    您的目标真的是
    方式
    功能,还是确定图形是否连接?您可能对确定图形是否连接的方式预先假定了太多

    最后,关于Haskell语法的一小部分:与大多数其他语言一样,函数应用程序绑定非常紧密,比
    =
    &&
    运算符更紧密。和大多数其他语言不同,函数应用程序不使用括号。因此,
    相邻的
    可以重新编码为:

    adjacent x y [] = False
    adjacent x y (mu:m) =  
        if x == fst mu && y == snd mu then True  
        else adjacent x y m 
    
    这反过来又可以简化为:

    adjacent x y [] = False
    adjacent x y (mu:m) = (x == fst mu && y == snd mu) || adjacent x y m 
    

    +我很清楚这是家庭作业!让我们了解如何寻求帮助。一旦某个特定答案帮助您成功解决了问题,选择它(单击计票下的复选标记)是正常的,这样so就知道问题已经解决。向会员表示,他们现在可能想花时间讨论其他问题。感谢您的评论,欢迎您提出。我已经修改,现在它的工作!