2Dトラフィックジャム


17

Biham-ミドルトン・レヴァインのトラフィックモデルは、モデルがトラフィックを簡素化自己組織化セルオートマトンです。

ランダムな開始位置を持つ格子上の点で表される多数の車で構成されます。各車は2つのタイプのいずれかです。右(この記事では赤で表示)。2種類の車が交互に移動します。各ターン中、対応するタイプのすべての車は、別の車によってブロックされていない場合、1ステップ進みます。

あなたの仕事は、このモデルをアニメーションとして視覚化することです。ここにいくつかの良いデモンストレーションがあります。

ここに画像の説明を入力してください

入力

密度を表す0〜1の浮動小数点数、および表示されるグリッドの高さと幅を表す2つの整数。入力が有効であり、関数へのパラメーターまたはユーザー入力からの読み取りが両方とも問題ないと仮定します。

例:(0.38 144 89上の画像に対応)

出力

実行中のこのモデルのアニメーションを表示する、少なくとも80x80のグリッド。開始時に、グリッドはグリッドが入力密度に達するまでランダムに配置されます。入力密度は、赤と青の半分になります(つまり、密度にグリッドの正方形の総数を掛け、好きなように丸めます)。密度この値である必要あります。つまり、確率として各セルを密度で埋めることはできません。各ステップで、1種類の車が下または右に移動し、端を通過すると折り返します。移動する車のタイプは各ステップを交互に切り替えます。アニメーションを表示可能にするには、各ステップ間に少なくとも10ミリ秒が必要です。

ルール

  • 車は、互いに区別でき、背景と区別でき、各車のタイプが同じ色または記号である限り、任意の色または記号を使用できます。

  • コンソールとグラフィック出力の両方が許可されています。コンソール出力の場合、印刷可能な記号は問題ありませんが、出力は文字のグリッドとしてなければなりません。

  • スクリーンショットまたはgifがない場合は、作成した出力の種類を指定してください。

  • シミュレーションは永久に実行する必要があります。

出力は少し複雑なので、質問がある場合はコメントしてください。


アニメーションの実行速度の制限はありますか?
xnor

おそらく、移動する車のタイプが各ステップを交互に繰り返すことを指定する価値があります。
グレッグマーティン

@xnorループあたり少なくとも5ミリ秒または10ミリ秒と考えていましたが、測定が難しいかどうかはわかりません。
qwr 16

3
密度、密度その値でなければならないことを意味しますか、それとも各ピクセルが満たされる確率dを持っていることを意味しますか?また、車の色をランダムに割り当てる必要がありますか?ランダムな場合は、どちらかの色になる可能性が50〜50あればよいのでしょうか。
JAD

1
@JarkoDubbeldam密度はその値でなければなりません。彼らはそれぞれの色である可能性が50-50です。しかし、私は遅く答えたので、答えは異なるかもしれません。車は上下に移動できます。
qwr 16

回答:


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()
  }
}

3つの引数を取る関数:d密度として、および次元x,yq各色の車の数です。m車の行列で、最初は車と空きスペースの数をランダムに並べることで埋められます。車はどちら1-1、または空きスペースは0です。

fは、としてコード化された車を見て、車を1行移動する関数です11sに続いてをチェックして、車が動くかどうかをチェックし0ます。どの車に応じて、すべての行または列でapply実行するために使用しますf

f1車の移動を処理し、車を移動する-1には、行列を転置し、移動方向を変更し、行列にを乗算します。車-1-1車になり1、vvと結果の行列は再び変換されます。

これはimage、3つの値に3つのデフォルト色を使用して、プロットを作成するために使用します。animationパッケージを使用して、デフォルトオプション(1 fps)を使用してアニメーションを処理します。

0.38, 144, 89:

GIFへのリンク

0.2, 144, 89:

GIFへのリンク

0.53, 144, 89:

GIFへのリンク


あなたのアニメーションは本当にクールに見えます-どの密度を使用しましたか?全部が空に多くのスペースをかなり迅速に詰まってしまったように思える
QWR

@qwrは実際に私を悩ませていたものでした。私のプログラムでは、リンクした例よりも全体が低密度でジャムします。ただし、プロットに使用された正確なパラメーターを思い出すことはできませんが0.38 144 89、例から非常によくわかる可能性があります。
JAD

正方形のグリッドで遊んでいると、jasondavies.com / bml /#0.35 / 100/100をジャムするために0.35の密度が得られましたが、ほとんどの場合、細い斜めの線ではなく、太い45度の線です。あなたのラインがより垂直に見て以来、私は車の2種類で何かがオフになっていると思います
QWR

今、問題が見えます。Caraは、他の車にブロックされていない場合にのみ前進できます。そのため、ウィキペディアの例では、すべての移動中の車の前にスペースがあります。しかし、アニメーションでは、車は一直線に動きます。面白い。
qwr 16

ああ、それでいいでしょう。
JAD

5

Mathematica、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ます。Listofを作成します{0, 2}。その長さはfloor(density * width * height / 2)({0, 2}length-2であるため2で除算されます)。

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

結果の2次元List(2 x何か)を1次元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ます。そうでなければ、転置しますb2-CellularAutomatonは少しゴルフをしたのでそこにあります)。基本的に、これbは他のすべての反復を転置します(転置を元に戻すため)

Colorize[ ... ]

配列をカラフルなに変換しImageます。

Dynamic@ ...

式を作成しDynamicます。すなわち、上記の機能は繰り返し実行されます。

出力

0.35, 192, 1082000フレーム(2倍に拡大)のサンプル出力(入力:)を次に示します。

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


組み込みの使用は、使用しないよりも長いのですか?!
アダム

3

Dyalog APL190の 108 115 112 バイト

解決

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

TryAPLオンライン(オンライン制限のため若干変更されています):

  1. ⎕IO←0関数Sを設定、定義してから、ランダムな38%14×29グリッドGを定義して表示します。

  2. 1つ下に移動します。

  3. 1つ右に移動します。

  4. ステップ2に進みます。

    トラフィック
    密度を保証しなかった以前のアルゴリズムのアニメーション。

説明

S←{直接関数Sを定義します(ここで右から左に説明します)。

÷4 4の逆数(0.25)

⎕DL 何秒も待つ(実際の経過時間を返す)

⍵⊣ discard(正しい引数;グリッド)を支持してそれを破棄する

⎕← それを出力する

 転置

⍉⍣⍺ if(左引数、0 =下、1 =右)の場合、再び転置します

( 関数トレインを適用します(ここで左から右に説明します):

  ,⍨ 自身に追加される引数

  , に追加

   自体

)

 行列をリストのリストに分割する

( 検索正規表現(ここで左から右に説明):

  ⍺⊃ onに基づいて次の2つのいずれかを選択します(0 =下/最初、1 =右/秒)

  '(↓+) ' '(→+) ' 下矢印と左矢印のシーケンスとそれに続くスペース

)⎕R' \1' 見つかったシーケンスが続くスペースに置き換えます

 リストのリストをマトリックスに混ぜる

 転置

d[⍺]↓ ⍺(左引数)が0(下)の場合は「高さ」行を、orが1(右)の場合は「幅」行をドロップします

d[⍺]↑ その後、その多くの行を取ります

 パススルー(セパレーターとして機能)

⍉⍣⍺ pose(左引数、0 =下、1 =右)の場合に転置

}


' ↓→'[ 文字列にインデックスを付けます(ここで右から左に説明します):

 数値入力(次元)

d← それをdに割り当てる

×/ 次元を乗算します(セルの数を見つけます)

c← それをcに割り当てる

⎕× それに数値入力(密度)を掛けます

 切り捨てる

1 2⍴⍨ その長さまで1と2を周期的に繰り返します

c↑ それを長さcまで拡張し、ゼロでパディングする

d⍴d(寸法)を 使用して形状を変更します

{ この匿名関数をそれに適用します(ここで左から右に説明します):

  ⍵[ によってインデックス付けされた正しい引数(0、1、2のリスト)

   ?⍨ シャッフルされたインデックス

   ⍴⍵ 引数の長さ

  ]

}

]

{ 次の匿名関数を適用します(右から左に説明):

0S⍵ 適用Sを 0左引数として(下)と右の引数としてグリッドに

1S それを右引数として、左引数として1(右)のSを適用します

}⍣≡ 連続する2回の繰り返しが同一になるまで(交通渋滞)

ノート

  1. が必要⎕IO←0です。これは多くのシステムでデフォルトです。

  2. (高さ、幅)を求め、次に密度を求めます。

  3. 組み込みのオートマトンを使用しません。

  4. 組み込みの正規表現サポートを使用します。

  5. 交通渋滞がある場合は停止します(車は移動できません)。

  6. 右に移動する車を表し、下に移動する車を表し、スペースが空の道路である文字行列を出力します。

  7. 上記のように、4 Hzでセッションに出力しますが、周波数を変更することで調整できます÷4。たとえば÷3、3 Hzおよび.3³⁄₁₀ Hzです。

  8. ]Box on -s=max -f=on最初に実行すると、何が起こっているかを簡単に確認できます。

  9. これで、必要な配分が保証され、2種類の車が正確に50〜50で発生し、丸めを除きます。


最初のボード生成では、入力密度のあるボードは保証されません。許可するかどうかはOPの選択だと思います。
ジョンファンミン

ああ、@ JarkoDubbeldamはすでにそれを尋ねました。
ジョンファンミン

@JungHwanMinどうして?密度をdとします。すべての位置は0から1の間の値を取得します。0からᵈ⁄₂の間の場合、aになります。ᵈ⁄₂とdの間の場合、aになります。dと1の間では空のままです。
アダム16

さて、極端なケースは次のとおりです。すべての位置が何らかの方法で値を取得します0(それらは(擬似)-ランダムに生成(擬似)-独立しているため、非常にありえないが可能です)。それからあなたのボードはs でいっぱいです。
ジョンファンミン

@JungHwanMinああ、私はあなたの意味がわかります。
アダム16

1

Java(624バイト+ Java.awt。*の場合は18バイト= 642バイト)

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.