前言: 前一天接触了囚徒困境,觉得挺有意思的。两位囚徒为了自己的利益和最大的好处,仅仅站在自己的角度去考虑问题,而忽略了集体利益可最大化,都会选择认罪。但自己以为个人利益最大化的同时,却中了警察的圈套,结果是两位都得坐牢5年。但仔细想想,人可能都会如此选择,因为一个人很难走进一个人的内心。说了这么多,什么······你还不知到什么是囚徒困境?那就赶紧科普一下吧!囚徒困境背景
一、想法:
在用JAVA模拟囚徒困境时,这里只用了3种策略,分别是:
1、好人策略:一直选择合作,不会背叛团队中的另一个人。(现实世界中是不会存在的,活雷锋一般的存在)
2、随机策略:合作概率50%,背叛概率50%
3、Tit For Tat策略:总是根据团队中另一人的选择,来决定决定自己下一次的选择是什么。但是在最开始的时候,都是处于好意,本着和他人合作的心思,所以第一次都是选择合作。为了体现善良、宽容的特性。如果另一人这次选择了背叛,下一次自己的选择结果为95%的背叛,5%的合作。依此方式对团队中的另一人进行报复。
二、JAVA代码:
prisoner类:
public class prisoner {
public String name;
//构造函数
public void prisoner(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
SelectCooperation类:(一直都会选择合作)
public class SelectCooperation extends prisoner{
public SelectCooperation(String name){
super.prisoner(name);
}
//老好人策略,一直选择合作
public int select() {
return 1;
}
}
SelectRandom类:(50%合作,50%背叛)
public class SelectRandom extends prisoner{
public SelectRandom(String name) {
super.prisoner(name);
}
//在合作和背叛之间随机选择
public int select() {
//Random r = new Random();
int r = (int)(Math.random()*100);
if(r < 50) {
return 1;
}else {
return 0;
}
}
}
SelectTitForTat类:(Tit For Tat策略)
import java.util.Random;
public class SelectTitForTat extends prisoner{
public SelectTitForTat(String name) {
super.prisoner(name);
}
/* “Tit For Tat”策略:
* 通过记录另一囚徒的选择,分析本次该做出如何选择
* 在第一次进行选择时,都是好意进行合作
* 后一次的选择判断另一人上次的选择,进行本次的选择
* 若上一次另一人选择了背叛,在本次选择中1%-5%的概率继续选择合作
* */
/*
* boolean flag = true; //获取另一人上一次的选择 public void otherSelect(int selectWhat) {
*
* if(selectWhat == 1) { flag = true; }else { flag = false; }
*
* }
*/
public int select(int selectWhat) {
int myselect = 0;
//如果对手上次选择了合作,本次选择合作
if(selectWhat == 1) {
myselect = 1;
}else {
//如果对手选择了背叛,本次95%选择背叛
Random r = new Random();
int [] a = {0,1,2,3,4};
for(int i = 0;i<5;i++) {
if(r.nextInt(100) == a[i]) {
myselect = 1;
break;
}
}
myselect = 0;
}
return myselect;
}
mian函数:(程序入口)
import java.util.Scanner;
public class test01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
//用户实例化
SelectCooperation cooperation = new SelectCooperation("好人");
SelectRandom random = new SelectRandom("随机选择");
SelectTitForTat tit = new SelectTitForTat("Tit For Tat");
//记录坐牢情况
int score_1 = 0;
int score_2 = 0;
int totalScore = 0;
//选择情况
System.out.println("输入你想要查看的结果(1———好人和随机策略,2———代表好人和Tit For Tat策略,3———代表随机策略和Tit For Tat策略)");
int sc = cin.nextInt();
switch(sc) {
case 1:
//第一种:老好人策略与随机策略
System.out.println("你选择的是好人和随机策略,10轮结果如下:");
for(int i = 0;i < 10;i++){
int selectCooper = cooperation.select();
int selectRandom = random.select();
if(selectCooper == 1) {
System.out.println(cooperation.getName() + "选择了合作————抵赖");
}else {
System.out.println(cooperation.getName() + "选择了背叛————认罪");
}
if(selectRandom == 1) {
System.out.println(random.getName() + "选择了合作————抵赖");
}else {
System.out.println(random.getName() + "选择了背叛————认罪");
}
//本轮各囚徒坐牢年数
int s1 = 0;
int s2 = 0;
System.out.println();
//囚徒1选择认罪,囚徒2选择抵赖 囚徒1坐牢8年
if(selectCooper == 1&&selectRandom == 0){
s1 = 8;
}
//囚徒1选择抵赖,囚徒2选择认罪 囚徒2坐牢8年
else if(selectCooper == 0&&selectRandom == 1){
s2 = 8;
}
//囚徒1、囚徒2都选择抵赖 囚徒1、囚徒2都坐1年
else if(selectCooper == 1&&selectRandom == 1){
s1 = s2 = 1;
}else{
//囚徒1、囚徒2都选择认罪 囚徒1、囚徒2都坐5年
s1 = s2 = 5;
}
//坐牢年数之和
score_1 += s1;
score_2 += s2;
totalScore = score_1 + score_2;
System.out.println("本轮结束, 情况如下");
System.out.println(cooperation.getName() + "需要坐牢年数" + s1 + ",总的坐牢年数:"+score_1);
System.out.println(random.getName() + "需要坐牢年数" + s2 + ",总的坐牢年数:"+score_2);
System.out.println("两位囚徒总的坐牢年数:" + totalScore);
System.out.println("======================================");
}
break;
case 2:
//第二种:好人和Tit For Tat策略结果
score_1 = 0;
score_2 = 0;
totalScore = 0;
System.out.println("你选择的是好人和Tit For Tat策略,10轮结果如下:");
for(int i = 0;i < 10;i++){
int selectCooper = cooperation.select();
//记录另一人的选择
int selectTit = tit.select(selectCooper);
if(selectCooper == 1) {
System.out.println(cooperation.getName() + "选择了合作————抵赖");
}else {
System.out.println(cooperation.getName() + "选择了背叛————认罪");
}
if(selectTit == 1) {
System.out.println(tit.getName() + "选择了合作————抵赖");
}else {
System.out.println(tit.getName() + "选择了背叛————认罪");
}
//本轮各囚徒坐牢年数
int s1 = 0;
int s2 = 0;
System.out.println();
//囚徒1选择认罪,囚徒2选择抵赖 囚徒1坐牢8年
if(selectCooper == 1&&selectTit == 0){
s1 = 8;
}
//囚徒1选择抵赖,囚徒2选择认罪 囚徒2坐牢8年
else if(selectCooper == 0&&selectTit == 1){
s2 = 8;
}
//囚徒1、囚徒2都选择抵赖 囚徒1、囚徒2都坐1年
else if(selectCooper == 1&&selectTit == 1){
s1 = s2 = 1;
}else{
//囚徒1、囚徒2都选择认罪 囚徒1、囚徒2都坐5年
s1 = s2 = 5;
}
//坐牢年数之和
score_1 += s1;
score_2 += s2;
totalScore = score_1 + score_2;
System.out.println("本轮结束, 情况如下");
System.out.println(cooperation.getName() + "需要坐牢年数" + s1 + ",总的坐牢年数:"+score_1);
System.out.println(tit.getName() + "需要坐牢年数" + s2 + ",总的坐牢年数:"+score_2);
System.out.println("两位囚徒总的坐牢年数:" + totalScore);
System.out.println("======================================");
}
break;
case 3:
//Tit For Tat和随机选择的结果
System.out.println("你选择的是随机策略和Tit For Tat,10轮结果如下:");
int []selectRanomResult = new int[11];
for(int i = 0;i < 10;i++) {
int selectRadom = random.select();
int j = i;
selectRanomResult[j] = selectRadom;
//记录另一人的选择
int selectTit;
if(i == 0) {
selectTit = tit.select(1);
}else {
System.out.println("上次随机选择的值是:" + selectRanomResult[j--]);
selectTit = tit.select(selectRanomResult[j--]);
}
if(selectRadom == 1) {
System.out.println(random.getName() + "选择了合作————抵赖");
}else {
System.out.println(cooperation.getName() + "选择了背叛————认罪");
}
if(selectTit == 1) {
System.out.println(tit.getName() + "选择了合作————抵赖");
}else {
System.out.println(tit.getName() + "选择了背叛————认罪");
}
//本轮各囚徒坐牢年数
int s1 = 0;
int s2 = 0;
System.out.println();
//囚徒1选择认罪,囚徒2选择抵赖 囚徒1坐牢8年
if(selectRadom == 1&&selectTit == 0){
s1 = 8;
}
//囚徒1选择抵赖,囚徒2选择认罪 囚徒2坐牢8年
else if(selectRadom == 0&&selectTit == 1){
s2 = 8;
}
//囚徒1、囚徒2都选择抵赖 囚徒1、囚徒2都坐1年
else if(selectRadom == 1&&selectTit == 1){
s1 = s2 = 1;
}else{
//囚徒1、囚徒2都选择认罪 囚徒1、囚徒2都坐5年
s1 = s2 = 5;
}
//坐牢年数之和
score_1 += s1;
score_2 += s2;
totalScore = score_1 + score_2;
System.out.println("本轮结束, 情况如下");
System.out.println(random.getName() + "需要坐牢年数" + s1 + ",总的坐牢年数:"+score_1);
System.out.println(tit.getName() + "需要坐牢年数" + s2 + ",总的坐牢年数:"+score_2);
System.out.println("两位囚徒总的坐牢年数:" + totalScore);
System.out.println("======================================");
}
break;
default:
break;
}
}
三、模拟实现:
在main函数中,实现了3钟模拟,
1、好人策略与随机策略:结果可想而知。不管好人怎么做,随机就是一直随机。真的是像极了爱情。
2、好人策略与Tit For Tat:一旦Tit For Tat明白了好人是真的好人,那就是“你浓,我也浓”。
3、随机策略与Tit For Tat策略:你不仁就别怪我不义。当然我Tit For Tat大人也不是无情,只要你肯悔改,商量的余地还是有的。