【发布时间】:2021-08-19 19:19:58
【问题描述】:
-- 1. Graph structure: nodes and adjacency matrix (i.e. the edges)
data Node = A | B | C | D | E | F deriving (Show,Eq,Ord)
adj :: (Node,Node) -> Bool
adj p = case p of
(A,B) -> True
(A,C) -> True
(B,C) -> True
(B,F) -> True
(C,D) -> True
(D,E) -> True
(E,B) -> True
(E,F) -> True
(F,A) -> True
(_,_) -> False
type Path = [Node]
-- 2. Auxiliary functions
adjacentNodes :: Node -> [Node] -> [Node]
adjacentNodes n ns = filter (\x -> adj(n,x)) ns
allNodes :: [Node]
allNodes = [A,B,C,D,E,F]
choice :: ([a],[a]) -> [a]
choice = uncurry (++)
-- 3. To do
addtoEnd :: Path -> [Node] -> [Path]
addtoEnd p ns = undefined
hCycles :: Node -> [Path]
hCycles n = undefined
我有这个代码(它是给我们的,我不能改变它或类型)并且需要使用 list monad(和 do 表示法)定义函数 hCycles。 hCycles 应该为图像中图形的任何通用节点计算哈密顿循环。
问题是我不太确定如何用 list monad 来做到这一点......尽管如此,我想我有这个函数的第一个版本:
hCycles :: Node -> [Path]
hCycles n = do
p <- [[n]]
nextNode <- adjacentNodes n allNodes
if n == nextNode
then [p]
else addtoEnd p allNodes
if/else 仍然有一个奇怪的行为,因为 hCycles 没有被再次调用,我什至不认为它是递归的......我该如何解决这个问题?
【问题讨论】:
-
这是一个相当大的练习——到目前为止你尝试了什么?
hCycles node应该返回列表中第一个和最后一个元素为node的所有路径,路径中的所有节点但除了node两次? -
看起来这与 monads 或 do 符号关系不大。您应该首先考虑要用于计算此类循环的算法。 (然后,该算法中的某些非确定性选择可能可以使用 list monad 来实现。)
-
@Carsten 就是这样
-
@chi 事情是我不太确定从哪里开始,我知道第一个和最后一个节点是相同的,并且没有其他节点可以出现两次......也许开始建立一个列表(路径)访问的节点,每次添加一个,检查它是否不是第二次发生?
-
您的
addtoEnd太慢了。使用:前置a而不是附加。你不在乎这条路是哪条路。
标签: haskell functional-programming monads do-notation