Haskell 在图中找出三角形

Haskell 在图中找出三角形,haskell,graph,Haskell,Graph,我有一个这样的图表: 作为家庭作业的一部分,我想找到三角形(1->2->5)。我不知道怎么找到这个 在我的例子中,我定义了我的图形: type Graph = (Int, Int -> Int -> Bool) g 2 3 = True g 3 2 = True g 1 2 = True g 2 1 = True g 1 1 = True g n m = False 对2条评论的答复。 我这样做了,我想它是有效的 triangles :: [(Int, Int, Int)] t

我有一个这样的图表:

作为家庭作业的一部分,我想找到三角形
(1->2->5)
。我不知道怎么找到这个

在我的例子中,我定义了我的图形:

type Graph = (Int, Int -> Int -> Bool)

g 2 3 = True
g 3 2 = True
g 1 2 = True
g 2 1 = True
g 1 1 = True
g n m = False
对2条评论的答复。 我这样做了,我想它是有效的

triangles :: [(Int, Int, Int)]
triangles = [(x, y, z) | x <- [1..3], y <- [1..x], z <- [1..y], isTriangle (x, y, z)]

isTriangle :: (Int, Int, Int) -> Bool
isTriangle  (x, y, z) = g x y && g y z && g x z
三角形::[(Int,Int,Int)]

三角形=[(x,y,z)| x我猜图的第一个Int是节点的界(比如,如果节点在
[1..6]
中,则为6)

因此,您需要一个返回图形三角形的函数,因此类型可能是:

triangles :: Graph -> [(Int, Int, Int)]
现在,对于3个节点,例如
x
y
z
,只要所有组合通过
g
返回
True
,就存在一个三角形

这样,您可能需要考虑生成所有这些组合(可能避免通过重新排序等价的那些组合),而只过滤那些验证标准的组合:

isTriangle :: Graph -> (Int, Int, Int) -> Bool
isTriangle (_, g) (x, y, z) == g x y && g y z && g x z
为此,您可以使用,或者使用类型为
(a->Bool)->[a]->[a]


回答您的第一个评论:

首先,您需要实现
三角形
函数,这是错误的原因。但是,正如您在
测试
中所做的那样,您可以快速生成这些三角形

现在,你写道:

test = filter (isTriangle) [(x,y,z) | x <- [1..3], y <- [1..3], z <- [1..3]]
或者,您可以通过在列表理解语法中提供一个保护来关闭
filter
函数,如下所示:

[(x, y, z) | x <- [1..3],  y <- [1..x], z <- [1..y], isTriangle yourGraph (x, y, z)]
将替换为前面的正确内容(x、y和z的范围,以及谓词为三角形)

或者,您可以将其分为两个功能:

allTriangles :: Int -> [(Int, Int, Int)]
allTriangles n = [(x, y, z) | ...]

graphTriangles :: Graph -> [(Int, Int, Int)]
graphTriangles (n, g) = [t | t <- allTriangles n, isGraphTriangle t]
    where isGraphTriangle (x, y, z) = ...
allTriangles::Int->[(Int,Int,Int)]
所有三角形n=[(x,y,z)|……]
graphTriangles::Graph->[(Int,Int,Int)]

graphTriangles(n,g)=[t | t我真的不喜欢你的图形类型,但不管怎样。下面是我们将使用的算法:

  • 首先找到图的节点
    x
  • 对于每个其他节点
    y
    查看它是否连接到
    x
  • 如果
    y
    确实连接到
    x
    ,则对于每个节点
    z
    ,查看它是否连接到
    x
    y
  • 如果是这样,请将其退回

  • 为了避免重复,我们需要
    zSorry,但我不知道如何连接
    isTriangle
    filter
    。我尝试了这个方法,但它不起作用(当然)。在这个字符串中
    isTriangle(u,g)(x,y,z)==gxy&&gyz&&gxz
    控制台写入
    解析错误:顶层的裸表达式
    三角形::图形->[(Int,Int,Int)]
    isTriangle::图形->(Int,Int,Int)->Bool
    isTriangle(ug)(x,y,z)==gxy&&gyz&&gxz
    过滤器::(a->[Bool][a]
    测试=过滤器(isTriangle)[(x,y,z)| x好的。最后一个问题。我不明白什么是
    图形
    。我只看到几个函数显示两个顶点之间的链接。我应该在参数中传输什么?再次编辑。试着想想你想要实现什么,以及你需要的函数类型,它们都应该到位。你的更正是错误的,请参阅我的编辑答案以了解原因。
    triangles :: Graph -> [(Int, Int, Int)]
    triangles (n, g) = [(x, y, z) | ...]
    
    allTriangles :: Int -> [(Int, Int, Int)]
    allTriangles n = [(x, y, z) | ...]
    
    graphTriangles :: Graph -> [(Int, Int, Int)]
    graphTriangles (n, g) = [t | t <- allTriangles n, isGraphTriangle t]
        where isGraphTriangle (x, y, z) = ...
    
    nodes (n,_) = [1..n]
    nodesBefore (n,_) k = [1..min n (k - 1)]
    edge (_,e) x y = e x y
    neighboursBefore g x = [ y | y <- nodesBefore g x, edge g x y]
    triangles g = [(x,y,z) | x <- nodes g, y <- neighboursBefore g x, z <- neighboursBefore g y, edge g x z]