根据Matrix67的"囚徒与灯泡"文章而写:
public class Wakeup {
static class People {
//记录第一次进入时确定的位置 0未确定,-1 左边 1右边.
public int Position;
//手上的球
public int BallNum;
//标识
public int Id;
//是否还在参与跷跷板游戏
public boolean OnLine;
public People(int Id) {
this.Id = Id;
Position = 0;
BallNum = 2;
OnLine = true;
}
}
private static int PeopleCount=100;//参与者人数
private static boolean BoxIsEmpty = true;// 盒子是否是空的
private static boolean LeftIsWeight = false;//跷跷板左边低
public static void main(String[] args) {
People[] thePeoples = new People[100];
for (int i = 0; i < PeopleCount; i++) {
thePeoples[i] = new People(i);
}
boolean finished = false;
int k = 0;
int i = 0;
int outNum = 0;
while (!finished) {
k++;
i = (new Random().nextInt(PeopleCount)) % PeopleCount;
People theP = thePeoples[i];
if (theP.OnLine) {
if (theP.Position == 0) {
theP.Position = LeftIsWeight ? -1 : 1;
LeftIsWeight = !LeftIsWeight;
} else {
if (theP.Position == -1) {
if (LeftIsWeight) { // 左边本侧低,如果有球则取
if (!BoxIsEmpty) {
BoxIsEmpty = true;
theP.BallNum++;
}
} else {// 本侧高,空就放球
if (BoxIsEmpty) {
if (theP.BallNum > 0) {
theP.BallNum--;
BoxIsEmpty = false;
}
}
}
} else {
if (LeftIsWeight) {// 本侧高,空就放球
if (BoxIsEmpty) {
if (theP.BallNum > 0) {
theP.BallNum--;
BoxIsEmpty = false;
}
}
} else {// 本侧低,非空就取球
if (!BoxIsEmpty) {
BoxIsEmpty = true;
theP.BallNum++;
}
}
}
}
//如果没有球,则退出,什么都不做
if (theP.BallNum <= 0) {
LeftIsWeight = !LeftIsWeight;
theP.OnLine = false;
outNum++;
System.out.println("Out:" + theP.Id);
}
//如果收集到200个球或者199个球,另外一个球在盒子里,则表示获得胜利.
if (theP.BallNum + (BoxIsEmpty ? 0 : 1) >= PeopleCount * 2) {
System.out.println("胜利者:" + theP.Id + ",共执行:" + k);
finished = true;
}
}
}
}
}
PS:这个算法提供了一种很好的思路,但在实际选举策略中一般都不会用,因为条件不会如文章所假设的那种苛刻的场景。