在Haskell中将图形表示为两个列表

时间:2016-08-02 15:38:24

标签: haskell graph-theory

我有一个这样的清单:

[(1,1.0,0.0),(2,2.0,0.0),(3,2.0,1.0),(4,3.0,0.0),(5,3.0,1.0),(14,3.0,2.0),(6,4.0,0.0),(7,4.0,1.0),(13,4.0,2.0),(8,5.0,0.0),(9,5.0,1.0),(10,6.0,0.0),(11,6.0,1.0),(12,7.0,0.0)]

其中第一个元素是节点ID,第二个元素是 x - 第三个元素是 y - 坐标。

第二个清单代表

[(1,[2,3]),(2,[4,5]),(3,[14]),(4,[6]),(5,[7]),(14,[6,7,13]),(6,[8]),(7,[9]),(13,[]),(8,[10]),(9,[11]),(10,[12]),(11,[12]),(12,[13])]`

其中first元素是此节点的ID,关联列表包含每个节点的后继元素。

我想编写一个带有节点ID的函数,返回节点本身及其后继者的相应 x y 。例如:节点1产生

  

[(1.0,0.0,2.0,0.0),(1.0,0.0,2.0,1.0)]

因为节点1有后继2(2.0,0.0)和3(2.0,1.0)

编辑:

我写了函数:

pairs [] = []
pairs ((nodeId,nodesucc):xs) =  map (nodeId,) nodesucc : pairs xs

pairsConcat = concat $ pairs $ edg graph2

所以现在第二个列表看起来像:

[(1,2),(1,3),(2,4),(2,5),(3,14),(4,6),(5,7),(14,6),(14,7),(14,13),(6,8),(7,9),(8,10),(9,11),(10,12),(11,12),(12,13)]

如何用4个元素创建元组?

1 个答案:

答案 0 :(得分:1)

我在上面的评论中说你应该尝试阅读更多内容,但是如果可以解决这个问题的一个例子仍然有用:

这与您的问题没有直接关系,但一般情况下我会建议您为节点ID和位置使用newtype:

newtype Id = ID Int deriving (Eq, Ord)
data Point = Point Int Int

我还建议使用Data.Map来存储这些数据,而不是关联列表:

neighbors :: Map Id [Id]
points :: Map Id Point

然后这是一个简单的解决方案,将其分解为(1)获取相邻点和(2)将此点添加到所有这些点。这使用Maybe monad来编写可能失败的东西,非常干净:

neighborPoints :: Id -> Maybe [Point]
neighborPoints id = lookup id neighbors >>= sequence . map (flip lookup points)

neighborPointsWithThisPoint :: Id -> Maybe [(Point, Point)]
neighborPointsWithThisPoint id = do
  p <- lookup points id
  ps <- neighborPoints id
  pure $ zip (repeat p) ps