Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Repast Simphony的意外结果_Java_Repast Simphony - Fatal编程技术网

Java 使用Repast Simphony的意外结果

Java 使用Repast Simphony的意外结果,java,repast-simphony,Java,Repast Simphony,我需要使用Repast Simphony作为模拟器开发迭代囚徒困境的Java版本 其思想是每个玩家都是一个代理,我们有一个nxn的玩家网格,无法移动。每个玩家必须与4个邻居(北部、南部、西部和东部)进行游戏,根据每轮4场不同游戏的结果找到最佳策略 由于在Repast Simphony中没有一个内置的系统来在代理之间交换消息,所以我不得不实施一些解决方案来处理代理的同步(a对B和B对a应该算作同一轮,这就是为什么它们需要同步) 通过将每一轮视为: 玩家我为4个敌人中的每一个选择下一步 玩家我向4

我需要使用Repast Simphony作为模拟器开发迭代囚徒困境的Java版本

其思想是每个
玩家
都是一个代理,我们有一个
nxn
玩家
网格,无法移动。每个
玩家
必须与4个邻居(北部、南部、西部和东部)进行游戏,根据每轮4场不同游戏的结果找到最佳策略

由于在Repast Simphony中没有一个内置的系统来在代理之间交换消息,所以我不得不实施一些解决方案来处理代理的同步(a对B和B对a应该算作同一轮,这就是为什么它们需要同步)

通过将每一轮视为:

  • 玩家
    我为4个敌人中的每一个选择下一步
  • 玩家
    我向4个敌人中的每一个发送正确的移动
  • Player
    我等待4个敌人中的每一个回复
根据我对Repast Simphony的理解,计划的方法是顺序的(没有代理级别的并行性),这意味着我必须使用与发送不同的方法进行等待(计划的优先级较低,以确保在开始等待之前完成所有发送)

这里的问题是,尽管收到了所有4条预期消息(至少这是打印的消息),但一旦waiting方法启动,它报告的接收元素就少于4个

以下是取自
Player
课程的代码:

// 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, interval = 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 ...
}
正如您在最后一行中看到的,
playSharedQueue.size()
1
,我真的不明白为什么

如果方法调用是连续的,那么waitResults()
Methodos将在9次执行之后调用,并且假设每个方法都正确地发送了4条消息,那么我找不到该大小仍然为1的原因

当然,所有内容都是连续的意味着没有
同步问题
,即使我使用
LinkedBlockingQueue
而不是
HashSet
时遇到同样的问题


你们对此有什么提示吗?

过了一段时间,我再次打开代码,发现我犯了一个简单但严重的错误:

@ScheduledMethod(start = 1, interval = 1, priority = 10)
public void play() {
    System.out.println(this + " started playing");
    // Clear previous plays
    playSharedQueue.clear();
playSharedQueue.clear()被执行以清除先前的结果,但是由于调用是连续的,第二个玩家将在第一个玩家向他发送游戏后调用它,因此游戏被丢弃


移动
waitResults
末尾的那条线解决了问题。

如果playSharedQueue是玩家
敌人的本地玩家。receivePlay(这是我的游戏)将只有一个对象[]进入playSharedQueue,并且始终为1。你能发布整个玩家类吗。
@ScheduledMethod(start = 1, interval = 1, priority = 10)
public void play() {
    System.out.println(this + " started playing");
    // Clear previous plays
    playSharedQueue.clear();