2016-12-26 1 views
0

J'ai un automate cellulaire bidimensionnel. Dans certaines cellules, il peut y avoir un acteur (agent). Chaque acteur est un fil. Je dois déplacer l'acteur basé sur les 9 cellules autour de la cellule de l'acteur. Je veux faire cela simultanément afin que l'acteur dans une cellule (4,5) puisse utiliser des cellules voisines (3,4), (4,4), (5,4), (3,5), (5,5) , (3,6), (4,6), (5,6) et aucun autre acteur ne peut utiliser ces cellules. Si un acteur a ces cellules dans son quartier, il doit attendre que le premier acteur déménage. Mais je veux permettre de déplacer l'acteur, qui n'a pas de voisinage commun, en même temps. Ainsi l'acteur de (4,5) peut se déplacer en même temps qu'un acteur en (10,5) car ils n'ont pas de voisinage commun.Mouvements d'automates cellulaires simultanés en mouvement

Quelle est la meilleure solution? Pouvez-vous proposer quelque chose?

+0

Plusieurs questions sur ce qui devrait être mis en œuvre: 1. Quand le fil se déplace vers la nouvelle cellule, montrez-il dormir à temps fixe (disons 1 sec) ou non? 2. Avez-vous besoin d'une visualisation de l'interface utilisateur (Swing)? Dans ce cas, vous pouvez marquer les threads «en attente de déplacement» en rouge et les threads en mouvement/dormant en vert. En option, vous pouvez créer une matrice de cellules 'Cell [] [] matrix'. Chaque fois que Thread va à la cellule suivante, il possède le moniteur sur cette cellule: 'synchronized (matrix [i] [j]) {Thread.sleep (1000); } ' –

Répondre

1

L'idée générale est la suivante.

  1. Créer matrice d'objets cellulaires, qui seront utilisés pour la synchronisation
  2. Acteurs assignent aux cellules
  3. Chaque fois que acteur se déplace vers une autre cellule, il doit obtenir un moniteur sur la cellule

Remarque que la cellule, à partir de laquelle Actor commence à se déplacer, n'est pas protégée dans le code ci-dessous. En outre, à quoi s'attendre si chaque cellule est peuplée a un acteur?

import java.util.ArrayList; 
import java.util.List; 

public class CellularAutomata { 

    public static void main(String ... args) throws InterruptedException { 
     final int rows = 5; 
     final int cols = 5; 
     Cell[][] matrix = new Cell[rows][cols]; 
     List<Actor> actors = new ArrayList<>(); 
     for (int i = 0; i < rows; i++) { 
      for (int j = 0; j < cols; j++) { 
       matrix[i][j] = new Cell(); 
       //populate actors 
       if ((i + j) % 2 == 0) { 
        Actor actor = new Actor(matrix, i, j); 
        actor.setName(String.format("Actor %d %d", i, j)); 
        actors.add(actor); 
       } 
      } 
     } 
     for (Actor actor : actors) { 
      actor.start(); 
     } 
     for (Actor actor : actors) { 
      actor.join(); 
     } 
    } 

    public static class Cell {} 

    public static class Actor extends Thread { 

     private final static int[][] circleMoves = { 
       {-1, -1}, {-1, 0}, {-1, 1} 
       , {0, 1}, {1, 1}, {1, 0} 
       , {1, -1}, {0, -1}, {0, 0} 
     }; 
     private final Cell[][] matrix; 
     private final int row; 
     private final int col; 

     public Actor(Cell[][] matrix, int row, int col) { 
      this.matrix = matrix; 
      this.row = row; 
      this.col = col; 
     } 

     @Override 
     public void run() { 
      for (int i = 0; i < circleMoves.length; i++) { 
       int nextRow = row + circleMoves[i][0]; 
       int nextCol = col + circleMoves[i][1]; 
       if (nextRow >= 0 && nextRow < matrix.length 
         && nextCol >= 0 && nextCol < matrix[nextRow].length) { 
        Cell targetCell = matrix[nextRow][nextCol]; 
        System.out.println(Thread.currentThread().getName() + " waiting for cell (" + nextRow + ";" + nextCol + ")"); 
        synchronized (targetCell) { 
         try { 
          System.out.println(Thread.currentThread().getName() + " moved to cell (" + nextRow + ";" + nextCol + ")"); 
          Thread.sleep(1000); 
         } catch (InterruptedException e) { 
          throw new IllegalStateException(e); 
         } 
        } 
       } 
      } 
     } 

    } 

} 
+0

Il y avait une faute de frappe dans l'extrait de code ci-dessus, la synchronisation doit être faite sur' targetCell', pas sur 'matrix'. La faute de frappe est fixée maintenant –