2016-12-26 12 views
0

2 차원 셀룰러 오토마타가 있습니다. 일부 세포에는 배우 (대리인)가있을 수 있습니다. 각 액터는 스레드입니다. 배우 세포 주위의 9 개의 세포를 기반으로 배우를 움직여야합니다. 이 작업을 동시에 수행하여 셀 (4,5)의 액터가 이웃 셀 (3,4), (4,4), (5,4), (3,5), (5,5) , (3,6), (4,6), (5,6) 등 다른 배우가이 셀을 사용할 수 없습니다. 어떤 배우가 이웃에이 세포를 가지고 있다면, 그는 첫 번째 배우가 움직일 때까지 기다려야합니다. 그러나 공통의 이웃이없는 배우를 동시에 움직일 수있게하고 싶습니다. 그래서 (4,5)의 배우는 공통의 이웃이 없기 때문에 (10,5)의 배우와 동시에 이동할 수 있습니다.Concurrent Cellular Automata 액터 이동

무엇이 최선의 해결책입니까? 뭔가 제안 할 수 있니?

+0

몇 가지 질문 : 새로운 셀에 1. 스레드 이동, 그것은 고정 된 시간 동안이 잠을 표시하거나하지 (의 1 초를 가정 해 봅시다)? 2. UI 시각화 (스윙)가 필요합니까? 이 경우 '이동 대기 중'스레드를 빨간색으로 표시하고 이동/슬립 스레드를 녹색으로 표시 할 수 있습니다. 구현 옵션으로 셀 행렬 [Cell [] [] matrix'을 만들 수 있습니다. Thread가 다음 셀로 갈 때마다이 셀의 모니터를 소유합니다 :'synchronized (matrix [i] [j]) {Thread.sleep (1000); }' –

답변

1

대략적인 아이디어는 다음과 같습니다.

  1. 세포에 동기화
  2. 지정 배우 사용되는 셀 객체의 행렬을 만들기
  3. 때마다이 셀

주에 모니터를 받아야 다른 셀에 배우로 이동 액터가 움직이기 시작한 셀은 아래 코드에서 보호되지 않습니다. 또한 모든 셀에 채워지는 액터에 액터가 있으면 어떻게 될까요? 구현해야하는지에 대한

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

위의 코드 스 니펫에 오타가 있었지만 동기화는'matrix'가 아니라'targetCell'에서 수행해야합니다. 오타가 지금 수정되었습니다. –