2D 교통 체증


17

Biham - 미들 - 레빈 트래픽 모델은 모델은 트래픽을 단순화하는 자기 조직 세포 자동자입니다.

임의의 시작 위치를 가진 격자의 점으로 표시되는 여러 자동차로 구성되며, 각 자동차는 아래로만 움직이는 자동차 (이 기사에서는 파란색으로 표시)와 오른쪽 (이 기사에서는 빨간색으로 표시). 두 종류의 자동차가 교대로 이동합니다. 매 턴마다 해당 유형의 모든 차량이 다른 차량에 의해 차단되지 않은 경우 한 단계 씩 전진합니다.

당신의 임무는이 모델을 애니메이션으로 시각화하는 것입니다. 다음은 좋은 데모입니다.

여기에 이미지 설명을 입력하십시오

입력

밀도를 나타내는 0과 1 사이의 부동 소수점 숫자와 표시되는 격자 높이와 너비를 나타내는 두 정수 입력이 유효하다고 가정하고 함수에 대한 매개 변수 또는 사용자 입력에서 읽은 매개 변수는 모두 양호합니다.

예 : 0.38 144 89(위의 이미지에 해당)

산출

실행중인이 모델의 애니메이션을 표시하는 그리드 (최소 80x80)입니다. 시작시, 그리드가 입력 밀도에 도달 할 때까지 빨간색과 절반이 파란색으로 표시됩니다 (즉, 원하는대로 반올림 한 그리드 사각형의 총 밀도 수). 밀도 이 값 이어야합니다. 즉, 밀도로 각 셀을 확률로 채울 수 없습니다. 각 단계마다 한 가지 유형의 자동차가 아래쪽 또는 오른쪽으로 이동하여 가장자리를 지나갈 때 감싸집니다. 움직이는 차의 종류는 각 단계를 번갈아 가며 나타냅니다. 애니메이션을 볼 수있게하려면 각 단계 사이에 10ms 이상이 있어야합니다.

규칙

  • 자동차는 서로 및 배경이 구별 될 수있는 한 임의의 색상 또는 기호 일 수 있으며, 각 자동차 유형은 동일한 색상 또는 기호입니다.

  • 콘솔 및 그래픽 출력이 모두 허용됩니다. 콘솔 출력의 경우 인쇄 가능한 기호는 괜찮지 만 출력은 문자 그리드 여야합니다.

  • 스크린 샷이나 gif가없는 경우 어떤 종류의 출력을 생성했는지 지정하십시오.

  • 시뮬레이션은 영원히 실행되어야합니다.

출력은 약간 복잡하므로 질문이 있으면 의견을 말하십시오.


애니메이션을 얼마나 느리게 또는 빠르게 실행해야하는지에 대한 제한이 있습니까?
xnor

아마도 이동하는 자동차 유형이 각 단계를 번갈아 가며 지정하는 것이 좋습니다.
Greg Martin

@ xnor 루프 당 5 ~ 10 ms 이상을 생각하고 있었지만 측정하기 어려운지 확실하지 않습니다.
qwr

3
밀도 밀도 해당 값이어야하거나 각 픽셀에 채울 확률 d가 있다는 의미입니까? 또한 자동차의 색상을 무작위로 지정해야합니까? 무작위로, 그들이 50-50의 기회 중 하나라도 색상이 될 수 있다면 다시 괜찮습니까?
JAD

1
@JarkoDubbeldam 밀도는 그 값이어야합니다. 그들은 각각의 색이 될 확률이 50-50입니다. 그러나 늦게 답변했기 때문에 답변이 다를 수 있습니다. 차는 상하로 움직일 수 있습니다.
qwr

답변:


5

R, 350 338 293 291 273 268 264 바이트

function(d,x,y){f=function(w){v=length(w);for(j in which(w>0&!w[c(2:v,1)]))w[c(j,j%%v+1)]=0:1;w};m=matrix(sample(c(rep(1,q<-floor(d*y*x/2)),rep(-1,q),rep(0,x*y-2*q))),x);p=animation::ani.pause;o=image;a=apply;repeat{o(m<-t(a(m,1,f)));p();o(m<--1*a(-1*m,2,f));p()}}

언 골프 드 :

function(d,x,y){
  q=floor(d*y*x/2)

  m=matrix(sample(c(rep(1,q),rep(-1,q),rep(0,x*y-2*q))),x)

  f=function(w){
    v=length(w)
    for(j in which(w>0&!w[c(2:v,1)])){
      w[c(j,j%%v+1)]=0:1
    }
    w
  }


  library(animation)
  repeat{
    m=t(apply(m,1,f))
    image(m)
    m=-1*apply(-1*t(m),2,f))
    ani.pause()
    image(m)  
    ani.pause()
  }
}

d밀도와 치수로 3 가지 인수를 취하는 함수 x,y. q각 색상의 자동차 수입니다. m자동차가 포함 된 행렬로, 처음에는 임의의 수의 자동차와 빈 공간을 사용하여 채워집니다. 자동차는 1또는 -1빈 공간입니다 0.

f로 코딩 된 자동차를보고 자동차를 한 행씩 이동시키는 기능입니다 1. 1s 다음에을 확인하여 차량이 움직일 수 있는지 확인합니다 0. 우리는 어떤 차에 따라 모든 행이나 열에서 apply달리기 f를 사용 합니다 .

f핸들이 상기 움직이는 1이동하는 차량 -1의 차를 우리에 의한 행렬을 곱하여, 이동 방향을 chaninging 행렬 전치 -1이렇게, -1자동차가 1자동차와 VV 얻어진 행렬은 다시 변환된다.

image3 가지 값에 대해 3 가지 기본 색상을 사용하여 플롯을 만드는 데 사용 됩니다. 용도 animation1 FPS입니다 기본 옵션을 사용하여 애니메이션을 처리 할 수있는 패키지를.

0.38, 144, 89:

GIF에 연결

0.2, 144, 89:

GIF에 연결

0.53, 144, 89:

GIF에 연결


애니메이션이 정말 멋져 보입니다-어떤 밀도를 사용 했습니까? 빈 공간이 많기 때문에 모든 것이 꽤 빨리
걸리는

실제로 나를 귀찮게했던 @qwr. 내 프로그램에서 모든 것이 연결 한 예제보다 밀도가 낮습니다. 그래도 플롯에 사용 된 정확한 매개 변수를 기억할 수는 없지만 0.38 144 89예제에서 나온 것일 수 있습니다 .
JAD

정사각형 그리드로 놀고 jasondavies.com/bml/#0.35/100/100 을 잼하기 위해 0.35의 밀도를 얻었 지만 얇은 대각선 대신 거의 항상 하나의 두꺼운 45deg 선입니다. 선이 좀 더 수직으로 보이기 때문에 두 가지 유형의 자동차에 무언가가 꺼져 있다고 생각합니다.
qwr

나는 지금 문제를 본다. Cara는 다른 차량에 의해 막히지 않은 경우에만 전진 할 수 있습니다. Wikipedia 예제에서 모든 움직이는 자동차는 그 앞에 공간이 있습니다. 그러나 애니메이션에서 자동차는 선으로 움직입니다. 흥미 롭군
qwr

아, 그렇습니다.
JAD

5

매쓰, 237 228 203 198 181 바이트

(b=RandomSample@ArrayReshape[Table[{0,i=2},##/2],{1##2},1]~Partition~#2;Dynamic@Colorize[i=-i;b=CellularAutomaton[{193973693,{3,{a=0{,,},{3,9,1},a}},{1,1}},b];If[i>0,b,2-b]])&

출력은 동적 Image입니다. 배경은 연한 녹색이며, 자동차는 방향에 따라 검은 색 또는 자홍색입니다.

설명

b=RandomSample@ArrayReshape[Table[{i=1,2},##/2],{1##2},1]~Partition~#2

초기 보드를 만듭니다.

Table[{0,i=2},##/2]

설정 i2. 길이가 floor (density * width * height / 2) 인 Listof를 만듭니다 {0, 2}( {0, 2}length-2 이므로 2로 나눔 ).

ArrayReshape[ ... ,{1##2},1]

결과 2-D List(2 x 무언가)를 1-D List(길이 = 너비 * 높이)로 재구성합니다. 패드 1충분한 값이없는 경우.

RandomSample@ ...

(의사) 무작위로 결과를 정렬합니다.

... ~Partition~#2

그 결과 길이 (폭)로 분할됩니다.

b= ...

에 저장하십시오 b.


Dynamic@Colorize[i=-i;b=CellularAutomaton[{193973693,{3,{a=0{,,},{3,9,1},a}},{1,1}},b];If[i>0,b,2-b]]

Dynamic Image: 만들기

i=-i;

의 부호를 뒤집습니다 i.

b=CellularAutomaton[{193973693,{3,{a=0{,,},{3,9,1},a}},{1,1}},b]

193973693과 이웃 가중치 {{0, 0, 0}, {3, 9, 1}, {0, 0, 0}}를 사용하여 셀룰러 오토 마톤을 적용하십시오 b. b동일하게 설정하십시오 .

If[i>0,b,2-b]

경우 i긍정적 떠나 b혼자. 그렇지 않은 경우 b( 조금 2-골프를 했으므로 거기에 있습니다 CellularAutomaton)를 바꿉니다 . 본질적으로 이것은 b다른 모든 반복을 바꿉니다 (조옮김을 취소하기 위해)

Colorize[ ... ]

배열을 화려한로 변환하십시오 Image.

Dynamic@ ...

식을 만드십시오 Dynamic. 즉, 위의 기능은 반복적으로 실행됩니다.

산출

다음 0.35, 192, 108은 2000 프레임 (확대 된 2 배)에 대한 샘플 출력 (입력 :)입니다.

https://i.imgur.com/zmSyRut.mp4


응, 내장을 사용하는 것이 그것을 사용하지 않는 것보다 길다?!
Adám

3

Dyalog APL , 190 108 115 112 바이트

해결책

S←{⍉⍣⍺⊢d[⍺]↑d[⍺]↓⍉↑(⍺⊃'(↓+) ' '(→+) ')⎕R' \1'↓(,⍨,⊢)⍉⍣⍺⍉⎕←⍵⊣⎕DL÷4}
{1S 0S⍵}⍣≡' ↓→'[d⍴{⍵[?⍨⍴⍵]}c1 2⍴⍨⌊⎕×c←×/d←⎕]

TryAPL 온라인 (온라인 제한으로 인해 약간 수정 됨) :

  1. 를 설정 ⎕IO←0하고 함수 S 를 정의한 다음 임의의 38 % 14x29 격자 G 를 정의하고 표시합니다 .

  2. 한 번 아래로 이동하십시오.

  3. 한 번 오른쪽으로 이동하십시오.

  4. 2 단계로 이동하십시오.

    교통
    밀도를 보장하지 않은 이전 알고리즘의 애니메이션.

설명

S←{직접 함수 S를 정의하십시오 (여기에서 오른쪽에서 왼쪽으로 설명).

÷4 4의 역수 (0.25)

⎕DL 몇 초 기다립니다 (실제 경과 시간을 반환 함)

⍵⊣ ⍵ (올바른 논증; 격자)에 찬성하여 폐기

⎕← 출력

 바꾸어 놓다

⍉⍣⍺ ⍺ (왼쪽 인수; 0 = 아래, 1 = 오른쪽)이면 다시 전치하십시오.

( 기능 트레인을 적용하십시오 (왼쪽에서 오른쪽으로 설명).

  ,⍨ 그 자체에 추가 된 논쟁

  , 에 추가

   그 자체

)

 행렬을 목록으로 나누기

( 정규식 검색 (왼쪽에서 오른쪽으로 설명) :

  ⍺⊃ ⍺ (0 = down / first, 1 = right / second)에 따라 다음 두 가지 중 하나를 선택하십시오.

  '(↓+) ' '(→+) ' 아래쪽 및 왼쪽 화살표 순서와 공백

)⎕R' \1' 찾은 시퀀스 뒤에 공백으로 교체

 목록을 행렬로 혼합

 바꾸어 놓다

d[⍺]↓ ⍺ (왼쪽 인수)가 0 (아래) 인 경우 "높이"행을 삭제하고 ⍺이 1 (오른쪽)이면 "폭"행을 삭제합니다.

d[⍺]↑ 그런 다음 그 많은 행을

 통과 (구분자로 사용)

⍉⍣⍺ if (왼쪽 인수; 0 = 아래, 1 = 오른쪽)이면 전치

}


' ↓→'[ 문자열을 색인화하십시오 (여기에서 오른쪽에서 왼쪽으로 설명).

 숫자 입력 (치수)

d←d에  할당

×/ 차원을 곱하십시오 (셀 수 찾기)

c← 그것을 c에 할당

⎕× 숫자 입력 (밀도)을 곱하십시오.

 반올림

1 2⍴⍨ 그 길이까지 주기적으로 1과 2를 반복

c↑ 길이 c 까지 0으로 채우십시오.

d⍴ 사용 D 바꿀 (치수)

{ 이 익명 함수를 적용하십시오 (왼쪽에서 오른쪽으로 설명).

  ⍵[ 인덱스 된 올바른 인수 (0, 1 및 2 목록)

   ?⍨ 셔플 지수

   ⍴⍵ 인수의 길이

  ]

}

]

{ 다음 익명 기능을 적용하십시오 (오른쪽에서 왼쪽으로 설명).

0S⍵S를  적용 0 왼쪽 인수로 (아래)과 오른쪽 인수로 그리드

1S 오른쪽 인수로 S 를 왼쪽 인수로 1 (오른쪽)으로 적용하십시오.

}⍣≡ 두 번의 반복이 동일 할 때까지 (교통 체증)

노트

  1. ⎕IO←0많은 시스템에서 기본값 인이 필요합니다 .

  2. (높이, 너비)를 묻는 메시지가 표시되고 밀도가 표시됩니다.

  3. 내장 오토 마톤을 사용하지 않습니다.

  4. 내장 정규식 지원을 사용합니다.

  5. 교통 체증이있을 경우 정지합니다 (자동차가 움직일 수 없음).

  6. 오른쪽으로 움직이는 자동차를 나타내는 문자 행렬을 출력 하고 아래로 움직이는 자동차를 나타내는 공간은 빈 도로입니다.

  7. 위와 같이 4Hz에서 세션으로 출력되지만 주파수를 변경하여 주파수를 조정할 수 있습니다 ÷4. 예를 들어 ÷33Hz이고 .3³⁄₁₀Hz입니다.

  8. ]Box on -s=max -f=on먼저 실행하면 무슨 일이 일어나고 있는지 쉽게 알 수 있습니다 .

  9. 필요한 분포가 보장되었으며 두 종류의 자동차가 정확히 50-50으로 발생하여 반올림을 줄입니다.


초기 보드 생성은 입력 밀도가있는 보드를 보장하지 않습니다. 나는 그것을 허용할지 아닌지를 OP의 선택이라고 생각합니다.
JungHwan Min

아, @JarkoDubbeldam이 이미 물었습니다.
JungHwan Min

@JungHwanMin 어떻게 그렇게? 밀도를 d로하자. 모든 위치는 0과 1 사이의 값을 얻습니다. 0과 ᵈ⁄₂ 사이의 값은 ,가됩니다. ᵈ⁄₂와 d 사이에 있으면 a가됩니다 . d와 1 사이에 있으면 비어 있습니다.
Adám

글쎄, 극단적 인 경우는 : 모든 위치가 어떻게 든 가치를 얻습니다 0. 그런 다음 보드는 s 로 가득 합니다.
JungHwan Min

@JungHwanMin 아, 무슨 말인지 알 겠어.
Adám

1

Java (Java.awt. * = 642 바이트의 경우 624 바이트 + 18 바이트)

static void k(double b,final int c,final int d){final int[][]a=new int[c+1][d+1];int i=0,j;for(;i<c;i++){for(j=0;j<d;j++){a[i][j]=Math.random()<b?Math.random()<0.5?1:2:0;}}Frame e=new Frame(){public void paint(Graphics g){setVisible(1>0);int i=0,j;for(;i<c;i++){for(j=0;j<d;j++){g.setColor(a[i][j]==2?Color.BLUE:a[i][j]==1?Color.RED:Color.WHITE);g.drawLine(i,j,i,j);}}for(i=c-1;i>=0;i--){for(j=d-1;j>=0;j--){if(a[i][j]==1&&a[i][(j+1)%d]==0){a[i][(j+1)%d]=1;a[i][j]=0;}else if(a[i][j]>1&&a[(i+1)%c][j]==0){a[(i+1)%c][j]=2;a[i][j]=0;}}}}};e.show();while(1>0){e.setSize(c,d+i++%2);try{Thread.sleep(400L);}catch(Exception f){}}}

언 골프 드 :

static void k(double b,final int c,final int d){
        final int[][]a=new int[c+1][d+1];
        int i=0,j;
        for(;i<c;i++) {
            for(j=0;j<d;j++) {
                a[i][j]=Math.random()<b?Math.random()<0.5?1:2:0;
            }
        }

        Frame e=new Frame(){
            public void paint(Graphics g){
                setVisible(1>0);
                int i=0,j;
                for(;i<c;i++) {
                    for(j=0;j<d;j++) {
                        g.setColor(a[i][j]==2?Color.BLUE:a[i][j]==1?Color.RED:Color.WHITE);
                        g.drawLine(i,j,i,j);
                    }
                }
                for(i=c-1;i>=0;i--) {
                    for(j=d-1;j>=0;j--) {
                        if(a[i][j]==1&&a[i][(j+1)%d]==0){
                            a[i][(j+1)%d]=1;a[i][j]=0;
                        }else if(a[i][j]>1&&a[(i+1)%c][j]==0){
                            a[(i+1)%c][j]=2;a[i][j]=0;
                        }
                    }
                }
            }
        };
        e.show();
        while(1>0){e.setSize(c,d+i++%2);try{Thread.sleep(400L);}catch(Exception f){}}
    }

그림:

여기에 이미지 설명을 입력하십시오


Java에 익숙하지 않지만 사용할 수있는 색상의 가장 짧은 이름은 빨간색, 파란색 및 흰색입니까? (아마도 회색은 옵션이며 1 바이트 대 흰색을 절약합니다)
JAD

스크린 샷은 여기에서 설명한 것과 동일한 문제를 나타내는 것으로 보입니다. codegolf.stackexchange.com/questions/104742/a-2d-traffic-jam/…
qwr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.