Manipulating Graph-- 球拍/方案

问题描述 投票:0回答:0

我希望在 Racket 中执行图的传递闭包。为此,我需要在您找到匹配的 (a,b) 和 (b,c) 时迭代添加链接。我应该使用 foldl、hash-keys、set->list、hash-ref 和 add-link。如果我也愿意,我可以使用递归辅助函数而不是 foldl。为此,我不能使用哈希的可变变体。

我的添加链接函数用在传递闭包函数中,定义如下:

(define (add-link graph from to)
  (let* ((outgoing (hash-ref graph from #{}))
         (new-outgoing (set-add outgoing to))
         (new-graph (hash-set graph from new-outgoing)))
    new-graph))

这是我到目前为止关于传递闭包函数的内容:

(define (transitive-closure graph)
  (define (helper graph)
    (foldl (lambda (x acc)
             (foldl (lambda (y acc)
                      (foldl (lambda (z acc)
                               (let ((ys (hash-ref acc y (set))))
                                 (when (member z (set->list ys))
                                   (add-link acc x z)))
                               acc)
                             acc
                             (hash-ref graph y (set)))
                      acc)
                   acc
                   (hash-ref graph x (set))))
           graph
           (hash-keys graph)))

  (define (iterator graph)
    (let ((new-graph (helper graph)))
      (if (equal? new-graph graph)
          graph
          (iterator new-graph))))
    
  (iterator graph))

功能总是测试失败,我真的不知道为什么。

代码使用两个函数,一个辅助函数和一个迭代器函数,来计算图的传递闭包。这些函数使用嵌套的 foldl 过程来遍历图中所有可能的顶点组合。辅助函数根据需要向图形添加链接以创建传递闭包,并应用 foldl 三次。另一方面,迭代器函数重复调用辅助函数,直到传递闭包不再变化。

在测试过程中,一条失败消息显示 foldl 函数接收到一个集合而不是列表作为第三个参数。这可能是因为哈希表值是集合而不是列表。该代码使用 hash-ref 根据给定键从哈希表中检索值,但返回的值不是预期的列表格式。此错误可能是由添加链接功能的实施问题引起的。但是,由于添加链接的测试已经通过,所以情况不太可能是这样。

代码看起来确实是正确的。传递闭包函数定义了两个辅助函数,helper 和 iterator,它们使用嵌套的 foldl 来获得输入图的传递闭包。

辅助函数使用 foldl 迭代图中所有可能的顶点组合,并在需要的地方添加链接以创建传递闭包。迭代器函数重复应用辅助函数,直到传递闭包不再改变。

传递闭包函数用输入图调用迭代器函数,并返回结果传递闭包。

总的来说,代码似乎结构良好,遵循函数式编程范式,没有使用任何可变数据结构。为什么它没有通过测试?这是测试消息的内容:

foldl: contract violation

预期:列表? 给定:(设置“n0”) 论点位置:第三

hash scheme racket hashtable transitive-closure
© www.soinside.com 2019 - 2024. All rights reserved.