这是我很喜欢的一个案例,
是以前我做关于博奕论(Game Theory)的报告时看到的,
一直觉得结论挺有意思的,
现在我把它作为prolog的一个题目写出来,
我不知道程序好写还是不好写(感觉要完全写对好像也不是很简单),
总之这是我自己出的题目,并不是什么国际prolog竞赛题目,
出得不好的话请多包含。
题目内容:
有一群民主的海盗,这里先假设为5个,
他们要瓜分他们抢来的金子,这里先假设为100个,
他们在如何瓜分抢来的东西这个问题上采用自己定下的特有的民主方式,
规则如下:
1. 由最凶狠到最懦弱的5个海盗依次轮流提案如何分配这100个金子,
最凶狠的是海盗1号,次凶狠的是海盗2号,最懦弱的是海盗5号,
每个人提出的议案为5个数字的数组,比如像[24, 22, 20, 18, 16]的形式,
表式提案人提议给海盗1拿24个金子、海盗2拿22个金子……,依此类推。
2. 如果提出的议案获得剩余海盗数量的至少半数的支持(看完本项规则你会知道为什么是"剩余"),
(总人数5个人的话,2.5个人算半数,也就是至少要3个人支持才算过半数),
则提案通过,海盗们按照此提案去分配金子;但若支持人数不足一半,
提案的海盗会被其他海盗合力丢进海里去喂鲨鱼,并由下一顺位海盗继续提案,
规则还是一样,如此循环下去。
规则主要就是这两点,不难,下面要说的是这个案例的2个重要假设:
1. 所有海盗都是追求本身利益极大化的,也就是说对任何一位海盗来说,
A议案和B议案比较,如果自己能从A议案获得的金子多于B议案,
那肯定支持A议案而不支持B议案。
并且,获得0个金子也好过被丢进海里喂鲨鱼。
(如果某海盗P从A议案得到的金子与B议案一样多,而A议案是目前最凶狠的海盗提出的议案,
那海盗P会投反对票,因为海盗都乐于看到比自己凶狠强悍的同伴被丢下海。)
2. 所有海盗相互之间都知道彼此是"极其聪明"的(看来这个行业门槛很高哈哈),
这意谓着对任意两个海盗A和B,A知道轮到B时B会提怎样的分配案,
而B也知道A知道轮到B时B会如何提案。
请试着编写ending/3谓词用来算出这些海盗最后的下场,
比如ending(Gold, Pirate, Get),
使得给定金子个数Gold与海盗人数Pirate后,
传回ListGet,Get的第i项代表第i个海盗最终会获得多少个金子,
第i项如果为-1代表第i个海盗下场是被丢进海里喂鲨鱼。
当海盗人数太多时,Get会变得很长无法一次显示出来,
可以多编写一个ending/4谓词,比如ending(Gold, Pirate, Index, Get),
多加一个参数Index,传回第Index个海盗最终获得的金子数Get。
例:
?- ending(100, 5, Get).
Get = [98, 0, 1, 0, 1].
如果不跑程序,自己用想的,想得出为什么答案是(98, 0, 1, 0, 1)吗?
?- ending(100, 201, 1, Get).
Get = 0.
?- ending(100, 203, 1, Get).
Get = -1.
?- ending(100, 204, 1, Get).
Get = 0.
?- ending(100, 205, 1, Get).
Get = -1.
?- ending(100, 216, 1, Get).
Get = 0.
?- ending(100, 500, 44, Get).
Get = -1.
是以前我做关于博奕论(Game Theory)的报告时看到的,
一直觉得结论挺有意思的,
现在我把它作为prolog的一个题目写出来,
我不知道程序好写还是不好写(感觉要完全写对好像也不是很简单),
总之这是我自己出的题目,并不是什么国际prolog竞赛题目,
出得不好的话请多包含。
题目内容:
有一群民主的海盗,这里先假设为5个,
他们要瓜分他们抢来的金子,这里先假设为100个,
他们在如何瓜分抢来的东西这个问题上采用自己定下的特有的民主方式,
规则如下:
1. 由最凶狠到最懦弱的5个海盗依次轮流提案如何分配这100个金子,
最凶狠的是海盗1号,次凶狠的是海盗2号,最懦弱的是海盗5号,
每个人提出的议案为5个数字的数组,比如像[24, 22, 20, 18, 16]的形式,
表式提案人提议给海盗1拿24个金子、海盗2拿22个金子……,依此类推。
2. 如果提出的议案获得剩余海盗数量的至少半数的支持(看完本项规则你会知道为什么是"剩余"),
(总人数5个人的话,2.5个人算半数,也就是至少要3个人支持才算过半数),
则提案通过,海盗们按照此提案去分配金子;但若支持人数不足一半,
提案的海盗会被其他海盗合力丢进海里去喂鲨鱼,并由下一顺位海盗继续提案,
规则还是一样,如此循环下去。
规则主要就是这两点,不难,下面要说的是这个案例的2个重要假设:
1. 所有海盗都是追求本身利益极大化的,也就是说对任何一位海盗来说,
A议案和B议案比较,如果自己能从A议案获得的金子多于B议案,
那肯定支持A议案而不支持B议案。
并且,获得0个金子也好过被丢进海里喂鲨鱼。
(如果某海盗P从A议案得到的金子与B议案一样多,而A议案是目前最凶狠的海盗提出的议案,
那海盗P会投反对票,因为海盗都乐于看到比自己凶狠强悍的同伴被丢下海。)
2. 所有海盗相互之间都知道彼此是"极其聪明"的(看来这个行业门槛很高哈哈),
这意谓着对任意两个海盗A和B,A知道轮到B时B会提怎样的分配案,
而B也知道A知道轮到B时B会如何提案。
请试着编写ending/3谓词用来算出这些海盗最后的下场,
比如ending(Gold, Pirate, Get),
使得给定金子个数Gold与海盗人数Pirate后,
传回ListGet,Get的第i项代表第i个海盗最终会获得多少个金子,
第i项如果为-1代表第i个海盗下场是被丢进海里喂鲨鱼。
当海盗人数太多时,Get会变得很长无法一次显示出来,
可以多编写一个ending/4谓词,比如ending(Gold, Pirate, Index, Get),
多加一个参数Index,传回第Index个海盗最终获得的金子数Get。
例:
?- ending(100, 5, Get).
Get = [98, 0, 1, 0, 1].
如果不跑程序,自己用想的,想得出为什么答案是(98, 0, 1, 0, 1)吗?
?- ending(100, 201, 1, Get).
Get = 0.
?- ending(100, 203, 1, Get).
Get = -1.
?- ending(100, 204, 1, Get).
Get = 0.
?- ending(100, 205, 1, Get).
Get = -1.
?- ending(100, 216, 1, Get).
Get = 0.
?- ending(100, 500, 44, Get).
Get = -1.
由Mercury Liao于周二 四月 03, 2012 10:46 am进行了最后一次编辑,总共编辑了1次