Scheme/Racket/Lisp 中嵌套列表的 Minimax 运算?
我正在尝试编写一个函数来分析游戏树。树由嵌套列表表示,其中每个子列表代表一个分支。基本上,我想弄清楚两件事:
- 嵌套列表的极小极大值是多少?
- 该值的索引是什么?
我以为我已经基本解决了第一个问题,但我的代码不断返回错误的值——我已经检查了所有内容,但看不出我做错了什么。
任何帮助将不胜感激,谢谢!
;MINIMAX*
(define minimax*
(lambda (l operation hilo)
(cond
((null? l) hilo)
((equal? operation 'max)
(cond
((null? (cdr l)) (if
(list? (car l))
(minimax* (car l) 'min hilo)
(if
(> (car l) hilo)
(car l)
hilo)))
(else (if
(list? (car l))
(if
(> (minimax* (car l) 'min hilo) hilo)
(minimax* (cdr l) 'max (minimax* (car l) 'min hilo))
(minimax* (cdr l) 'max hilo))
(if
(> (car l) hilo)
(minimax* (cdr l) 'max (car l))
(minimax* (cdr l) 'max hilo))))))
((equal? operation 'min)
(cond
((null? (cdr l)) (if
(list? (car l))
(minimax* (car l) 'max hilo)
(if
(< (car l) hilo)
(car l)
hilo)))
(else (if
(list? (car l))
(if
(< (minimax* (car l) 'max hilo) hilo)
(minimax* (cdr l) 'min (minimax* (car l) 'max hilo))
(minimax* (cdr l) 'min hilo))
(if
(< (car l) hilo)
(minimax* (cdr l) 'min (car l))
(minimax* (cdr l) 'min hilo))))))
(else (error "Invalid operation type, must be 'max or 'min")))))
I'm trying to write a function to analyze game trees. The trees are represented by nested lists where each sub-list represents a branch. Basically, there are two things I want to figure out:
- what is the minimax value of a nested list?
- what is the index of that value?
I thought I had mostly solved the first problem, but my code keeps returning the wrong values--I've checked everything over and can't see what I've done wrong.
Any help would be much appreciated, thanks!
;MINIMAX*
(define minimax*
(lambda (l operation hilo)
(cond
((null? l) hilo)
((equal? operation 'max)
(cond
((null? (cdr l)) (if
(list? (car l))
(minimax* (car l) 'min hilo)
(if
(> (car l) hilo)
(car l)
hilo)))
(else (if
(list? (car l))
(if
(> (minimax* (car l) 'min hilo) hilo)
(minimax* (cdr l) 'max (minimax* (car l) 'min hilo))
(minimax* (cdr l) 'max hilo))
(if
(> (car l) hilo)
(minimax* (cdr l) 'max (car l))
(minimax* (cdr l) 'max hilo))))))
((equal? operation 'min)
(cond
((null? (cdr l)) (if
(list? (car l))
(minimax* (car l) 'max hilo)
(if
(< (car l) hilo)
(car l)
hilo)))
(else (if
(list? (car l))
(if
(< (minimax* (car l) 'max hilo) hilo)
(minimax* (cdr l) 'min (minimax* (car l) 'max hilo))
(minimax* (cdr l) 'min hilo))
(if
(< (car l) hilo)
(minimax* (cdr l) 'min (car l))
(minimax* (cdr l) 'min hilo))))))
(else (error "Invalid operation type, must be 'max or 'min")))))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你应该稍微改变一下你的方法。您可以实现一些实用程序,而不是编写一个基本过程来完成所有事情。
对于极小极大过程,数据是在树中还是在列表中并不重要。因此,您可以自己编写一个过程,将树转换为像这样的列表。
检查最小值或最大值基本上是对列表或树的迭代。所以你可以用
fold
来做到这一点。请参阅 http://www. gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Reduction-of-Lists.html所以你可以像这样编写你的程序:
进一步阅读 计算机程序的结构和解释。这是一本学习方案和一般编程的好书。
You should change your approach a little bit. Instead of programming one fundamental procedure that makes the everything, you can implement some utility procedures.
For the minimax procedure it does not matter if the data comes in a tree or a list. So you can write yourself a procedure that converters your tree into a list like this one
Checking for minimum or maximum is basically an iteration over a list or tree. So you could do that with
fold
. See http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Reduction-of-Lists.htmlSo you can write your procedure like this:
For further reading Structure and Interpretation of Computer Programs. It is a great book for learning Scheme and programing in general.