Haskell中的图形表示

时间:2010-05-05 19:37:48

标签: haskell graph

我选择通过节点列表(例如n=[1,2,3,4])和表示边缘的对列表(例如m=[(1,2), (2,3)])来表示Haskell中的图形。现在我必须看看图表是否有很强的连接。

我的主要问题是如何查找图中2个节点之间是否有路径。我写了类似的东西:

-- 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级节点时,它可以工作,但对于程度较大的节点,它并不总是有效。你能给我一些线索吗?

2 个答案:

答案 0 :(得分:4)

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

  1. adjacent 3 2 [(1,2),(2,3)]应该True吗?
  2. 1
  3. [(1,2),(2,3),(1,4),(3,4)]有多少后继者
  4. way为什么或不需要x==y案例和adjacent x y ...案件?
  5. way的递归步骤中,== False测试是否真的告诉您一些可以让您在m的较小图表上进行递归的内容?
  6. 通常,您尚未为顶级函数编写类型签名。这样做通常非常有启发性,并且会更清楚地传达您的设计:

    type Vertex = Int
    type Edge = (Vertex, Vertex)
    type Graph = [Edge]
    
    adjacent :: Vertex -> Vertex -> Graph -> Bool
    suc :: Vertex -> Graph -> Vertex
    way :: Vertex -> Vertex -> Graph -> Bool
    

    考虑一下这些类型是否有意义,如果它们像您期望的那样分解您的问题,只需考虑一般的图形。

    您的目标确实是way功能,还是确定图表是否已连接?您可能会过多地假设您可以确定图表是否已连接。

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

    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 
    

答案 1 :(得分:3)

您有两个理解错误:

  1. m,您的边缘列表在整个搜索过程中都是静态的。请勿在{{1​​}}中重复使用它。
  2. 每个顶点可以有多个边缘离开它。您想知道x的邻居的way是否具有any到y。要查找邻居,首先必须way边缘列表才能找到离开x的边缘。
  3. 您还需要建立一个已经访问过的节点列表,以查找连接。如果您最终在已经看过的节点上,则该特定路径已失败。

    一些提示可以缩短您的代码:对于filter,请尝试adjacent。 对于elem,请尝试succData.Maybe.fromMaybe