我需要使用Repast Simphony作为模拟器开发
Java版本的迭代囚徒困境.
这些想法是每个玩家都是一个代理人,我们有一个无法移动的n x n播放器网格.每个玩家必须与4个邻居(北部,南部,西部和东部)玩,根据每轮中4种不同游戏的结果找到最佳策略.
由于没有内置系统在Repast Simphony中的代理之间交换消息,我必须实施某种解决方法来处理代理的同步(A vs B和B vs A应该算作同一轮,这就是他们需要的原因要同步).
这是通过将每一轮视为:
>玩家我为4个敌人中的每一个选择下一步行动
>玩家我向4个敌人中的每一个发送正确的动作
>玩家我等待4个敌人中的每一个回复
根据我对Repast Simphony的理解,预定的方法是顺序的(没有代理级并行),这意味着我被迫以与发送方式不同的方式进行等待(以较低的pritority安排以确保完成所有发送)在开始等待之前).
这里的问题是,尽管收到了所有4条预期的消息(至少这是打印的内容),一旦等待方法启动它报告的接收元素少于4个.
// myPoint is the location inside the grid (unique,agents can't move and only one per cell is allowed) public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((myPoint == null) ? 0 : myPoint.hashCode()); return result; } // Returns enemy's choice in the prevIoUs round private byte getLastPlay(Player enemy) { return (neighbors.get(enemy)[1]) ? COOPERATE : DEFECT; } // Elements are saved as (player,choice) private void receivePlay(Player enemy,byte play) { System.out.println(this + " receives (" + play + ") from " + enemy); while (!playSharedQueue.add(new Object[] { enemy,play })){ // This doesn't get printed,meaning that the insertion is successful! System.out.println(this + " Failed inserting"); } } @ScheduledMethod(start = 1,interval = 1,priority = 10) public void play() { System.out.println(this + " started playing"); // Clear prevIoUs plays playSharedQueue.clear(); for (Player enemy : neighbors.keySet()) { // properties[0] = true if we already played together // properties[1] = true if enemy choose to cooperate on the prevIoUs round Boolean[] properties = neighbors.get(enemy); // Choose which side we take this time byte myPlay; if (properties[0]) { // First time that we play,use memory-less strategy myPlay = (Math.random() <= strategy[0]) ? COOPERATE : DEFECT; // Report that we played properties[0] = false; neighbors.put(enemy,properties); } else { // We already had a round,use strategy with memory byte enemyLastPlay = enemy.getLastPlay(this); // Choose which side to take based on enemy's prevIoUs decision myPlay = (Math.random() <= strategy[(enemyLastPlay) == COOPERATE ? 1 : 2]) ? COOPERATE : DEFECT; } // Send my choice to the enemy System.out.println(this + " sent (" + myPlay + ") to " + enemy); enemy.receivePlay(this,myPlay); } } // Waits for the results and processes them @ScheduledMethod(start = 1,priority = 5) public void waitResults() { // Clear prevIoUs score lastPayoff = 0; System.out.println(this + " waits for results [" + playSharedQueue.size() + "]"); if (playSharedQueue.size() != 4) { // Well,this happens on the first agent :( System.exit(1); } // ... process ... }
这是控制台输出,因此您可以看到所有内容似乎都没有问题地发送和接收(使用3 x 3网格):
Player[2,0] started playing Player[2,0] sent (0) to Player[2,1] Player[2,1] receives (0) from Player[2,0] Player[2,2] Player[2,2] receives (0) from Player[2,0] sent (0) to Player[0,0] Player[0,0] receives (0) from Player[2,0] sent (0) to Player[1,0] Player[1,2] started playing Player[1,2] sent (1) to Player[2,2] receives (1) from Player[1,2] Player[1,2] sent (1) to Player[0,2] Player[0,2] sent (1) to Player[1,0] receives (1) from Player[1,1] Player[1,1] receives (1) from Player[1,2] started playing Player[0,2] receives (1) from Player[0,0] receives (1) from Player[0,1] Player[0,1] receives (1) from Player[0,1] started playing Player[0,1] sent (1) to Player[2,1] sent (1) to Player[0,1] sent (1) to Player[1,0] started playing Player[1,0] receives (0) from Player[1,1] receives (0) from Player[1,2] receives (0) from Player[1,1] started playing Player[1,1] sent (0) to Player[2,1] sent (0) to Player[0,1] sent (0) to Player[1,2] started playing Player[2,2] sent (0) to Player[2,2] sent (0) to Player[0,2] sent (0) to Player[1,0] started playing Player[0,0] sent (1) to Player[2,0] sent (1) to Player[0,0] sent (1) to Player[1,1] started playing Player[2,0] receives (1) from Player[2,2] receives (1) from Player[2,1] receives (1) from Player[2,2] waits for results [1]
正如你在最后一行中看到的那样,playSharedQueue.size()是1,我真的不明白为什么.
如果方法调用是顺序的,则在9play()`执行后调用waitResults()方法,并且假设每个正确发送4条消息,我找不到该大小仍为1的原因.
当然,所有顺序意味着没有同步问题,即使我使用LinkedBlockingQueue而不是HashSet也有同样的问题.
你们有什么暗示吗?