【问题标题】:How to implement multi-threading for a recursive function如何为递归函数实现多线程
【发布时间】:2018-05-05 02:12:28
【问题描述】:

考虑一个简单的 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)))

【问题讨论】:

    标签: multithreading recursion clojure


    【解决方案1】:

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

    第二种方法可能是更改助手以将工作放在任务队列中并让一些线程来处理它们。这会更好,但可能会更慢。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-14
      • 2017-11-13
      相关资源
      最近更新 更多