当前位置: 首页 > 知识库问答 >
问题:

如何为递归函数实现多线程

韦衡
2023-03-14

考虑一个简单的2人游戏,如下所示:偶数枚硬币排成一行。每个玩家轮流在一行的一端移除硬币。目标是当所有硬币都被拿走时,硬币的价值最高。

玩家1找到所有偶数硬币和所有奇数硬币的总和。如果奇数硬币的总和较高,玩家1拿最左边的硬币;否则他拿最右边的。

玩家2现在有一个选择,有奇数个硬币。选择第一个硬币或最后一个硬币将导致玩家1的硬币列表略有不同。玩家2使用递归搜索的结果来确定是选择第一个还是最后一个硬币。

我希望能够以某种方式实现多线程上的p2-helper递归函数,现在确定如何。任何建议或想法将不胜感激,谢谢!

(ns game.core
  (:gen-class))

; function that returns the vector of a string (split up by spaces)
(defn vector-from-string [s]
  (drop 1 (map read-string (clojure.string/split (clojure.string/trim-newline s) #" "))))

; function that returns the slurped string of a read-in file
(defn string-from-file [f]
  (slurp f))

; function that returns the sum of all the odd-indexed items in a vector
(defn sum-of-evens [v]
  (reduce + (take-nth 2 (rest v))))

; function that returns the sum of all the odd-indexed items in a vector
(defn sum-of-odds [v]
  (reduce + (take-nth 2 v)))

; function that returns the vector that is left after player one moves, and then the coin that player one took
(defn p1 [v]
  (if (> (sum-of-odds v) (sum-of-evens v))
    [(drop 1 v) (first v)]
    [(drop-last v) (last v)]))

; nearly identical to 'p1' but this function only returns the affected vector after player 1 has moved
(defn p2-p1 [v]
  (if (even? (count v))
    (if (> (sum-of-odds v) (sum-of-evens v))
      (drop 1 v)
      (drop-last v))
    (drop 0 v)))

; recursive search for player two
(defn p2-helper [v]
  (if (or (= (count v) 1) (= (count v) 0))
    (reduce + v)
    (max (+ (p2-helper (drop 1 (p2-p1 v))) (first (p2-p1 v))) (+ (p2-helper (drop-last (p2-p1 v))) (last (p2-p1 v))))))

; function that returns the vector that is left after player two moves, and then the coin that player two took
(defn p2 [v]
  (if (> (+ (p2-helper (drop 1 (p2-p1 v))) (first (p2-p1 v))) (+ (p2-helper (drop-last (p2-p1 v))) (last (p2-p1 v))))
    [(drop 1 v) (first v)]
    [(drop-last v) (last v)]))

; function to play the game out until no coins are left
(defn play-game [v]
  (def coins v)
  (def p1score 0)
  (def p2score 0)
  (while (not (empty? coins))
    (do
      (let [[new-vec score] (p1 coins)]
        (def coins new-vec)
        (def p1score (+ p1score score)))
      (let [[new-vec score] (p2 coins)]
        (def coins new-vec)
        (def p2score (+ p2score score)))))
  (println "player 1 score:" p1score)
  (println "player 2 score:" p2score))

; main
(defn -main [& args]
  (let [v (vector-from-string (string-from-file "10.txt")) ]
    (play-game v)))

共有1个答案

鄢博简
2023-03-14

最初的方法是在每个递归调用周围添加@(future)(p2 helpet…),这可能会运行太多线程,运行速度较慢。

第二种方法可能是更改助手,将工作放入任务队列,并使一些线程处理它们。这会更好,尽管速度可能会更慢。

我将继续改进它,通过调用trampoline来展开递归,以阻止它破坏堆栈。然后试着让顶层平行,或者只让两个顶层平行。

 类似资料:
  • 本文向大家介绍C++实现递归函数的方法,包括了C++实现递归函数的方法的使用技巧和注意事项,需要的朋友参考一下 递归函数通俗来讲就是自己调用自己本身。这样有很大的好处,代码很方便简洁,把复杂的有规律的运算交给计算机去做。 1、首先定义问题。递归函数(recursion)需要设置一个函数,然后再可以循环往复的执行下去。 2、把问题换成公式。 如把阶乘之和定义为f(n)=n*f(n-1)。也就是说n*

  • 嗯,我已经试过多次了。不过,我一度认为最长的序列函数会有所帮助,因为它显示的是最长的冰雹序列。尽管如此,我似乎不知道如何查找或存储它用于查找的值。如果有人能解释一下,我将不胜感激。 我遇到的问题是我最长的启动顺序: 我不知道如何将其转换为递归,我注意到对于一些递归,我看到人们仍然在使用for循环,但我确信我们不应该使用循环。这可能是一个愚蠢的问题,但如果有人知道的话,有没有一个公式可以将循环转换为

  • 问题 你想在一个函数中调用相同的函数。 解决方案 使用一个命名函数: ping = -> console.log "Pinged" setTimeout ping, 1000 若为未命名函数,则使用 @arguments.callee@: delay = 1000 setTimeout((-> console.log "Pinged" setTimeout arg

  • 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出: fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n 所以,fact(n)可以表示为n x fact(n-1),

  • 在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出: fact(n)=n!=1\times2\times3\times\cdot\cdot\cdot\times(n-1)\times n=(n-1)!\times n=fact(n-1)\times n

  • 问题内容: 我是python(programming)的新手,我发现下面的递归程序很难遵循。在调试程序时,我发现每次递归时都会经历递归并且递减值-1。在某一点是-1,编译器移至该部分并返回0。 最终该值变为1,这是怎么发生的? 并输出: 递归示例结果 1 3 6 10 15 21 问题答案: 尝试用铅笔和纸追踪该功能。在这种情况下,该函数的打印语句可能会引起误解。 考虑一下程序的这一部分, 从这里