Kemacetan Lalu Lintas 2D

17

The Model lalu lintas Biham-Middleton-Levine adalah robot seluler mengorganisir diri bahwa model disederhanakan lalu lintas.

Ini terdiri dari sejumlah mobil yang diwakili oleh titik-titik pada kisi-kisi dengan posisi awal acak, di mana masing-masing mobil mungkin salah satu dari dua jenis: yang hanya bergerak ke bawah (ditunjukkan dengan warna biru dalam artikel ini), dan yang hanya bergerak ke arah kanan (ditampilkan sebagai merah di artikel ini). Kedua jenis mobil itu bergiliran bergerak. Selama setiap belokan, semua mobil untuk tipe yang sesuai maju satu langkah jika tidak diblokir oleh mobil lain.

Tugas Anda adalah memvisualisasikan model ini sebagai animasi. Berikut ini beberapa demonstrasi yang bagus.

masukkan deskripsi gambar di sini

Memasukkan

Angka titik mengambang antara 0 dan 1 mewakili kerapatan, dan dua bilangan bulat mewakili tinggi dan lebar kisi yang ditampilkan. Asumsikan input valid, dan parameter ke fungsi atau membaca dari input pengguna baik-baik saja.

Contoh: 0.38 144 89(sesuai dengan gambar di atas)

Keluaran

Kotak, setidaknya 80x80, yang menampilkan animasi dari model ini berjalan. Pada awalnya, mobil ditempatkan secara acak di grid sampai grid mencapai kepadatan input, dengan setengah merah dan setengah biru (yaitu kepadatan kali jumlah total kotak kuadrat, bulat bagaimanapun Anda suka). Kerapatan harus berupa nilai ini, yang berarti Anda tidak dapat mengisi setiap sel dengan kerapatan sebagai probabilitas. Untuk setiap langkah, satu jenis mobil bergerak ke bawah atau ke kanan, membungkus jika melewati tepi. Jenis mobil yang bergerak bergantian setiap langkah. Untuk membuat animasi dapat dilihat, harus ada setidaknya 10 ms antara setiap langkah.

Aturan

  • Mobil dapat berupa warna atau simbol apa pun selama mereka dapat dibedakan satu sama lain dan latar belakang, dan setiap jenis mobil memiliki warna atau simbol yang sama.

  • Konsol dan output grafis keduanya diperbolehkan. Untuk output konsol, simbol apa pun yang dapat dicetak baik-baik saja, tetapi output harus berupa kisi-kisi karakter.

  • Silakan tentukan jenis keluaran apa yang Anda hasilkan jika Anda tidak memiliki tangkapan layar atau gif.

  • Simulasi harus berjalan selamanya.

Outputnya agak rumit, jadi jika Anda memiliki pertanyaan, silakan komentar.

qwr
sumber
Adakah batasan seberapa lambat atau cepat animasi harus dijalankan?
xnor
Mungkin ada baiknya menyebutkan bahwa jenis mobil yang bergerak bergantian setiap langkah.
Greg Martin
@ xnor Saya berpikir setidaknya 5 atau 10 ms per loop, tapi saya tidak begitu yakin apakah itu akan sulit untuk diukur.
qwr
3
Apakah kepadatan berarti bahwa kepadatan memiliki menjadi nilai itu, atau hanya bahwa setiap pixel memiliki probabilitas d untuk diisi? Juga, apakah kita harus menetapkan warna mobil secara acak atau tidak? Jika secara acak, sekali lagi apakah boleh jika mereka hanya memiliki peluang 50-50 untuk menjadi salah satu warna?
JAD
1
@JarkoDubbeldam Kepadatan harus nilai itu. Mereka memiliki peluang 50-50 untuk menjadi masing-masing warna. Namun saya menjawab terlambat sehingga jawabannya mungkin berbeda. Mobil dapat bergerak ke atas atau ke kiri.
qwr

Jawaban:

5

R, 350 338 293 291 273 268 264 byte

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

Tidak Disatukan:

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

Fungsi yang mengambil 3 argumen: dsebagai kepadatan, dan dimensi x,y. qadalah jumlah mobil di setiap warna. madalah matriks dengan mobil, yang pada awalnya diisi dengan mengambil secara acak jumlah mobil dan ruang kosong. Mobil adalah salah satu 1atau -1, ruang kosong itu 0.

fadalah fungsi yang menggerakkan mobil satu baris, memandang mobil yang diberi kode 1. Ini memeriksa apakah mobil dapat bergerak dengan memeriksa untuk 1diikuti oleh 0. Kami menggunakan applyuntuk berjalan fdi setiap baris atau kolom, tergantung pada mobil mana.

fmenangani pergerakan 1mobil, untuk memindahkan -1mobil, kami mentransposisikan matriks, menyalurkan arah pergerakan, mengalikan matriks dengan -1, sehingga -1mobil menjadi 1mobil, dan vv dan matriks yang dihasilkan ditransformasikan kembali.

Ini digunakan imageuntuk membuat plot, menggunakan 3 warna default untuk tiga nilai. Menggunakan animationpaket untuk menangani animasi menggunakan opsi default, yaitu 1 fps.

0.38, 144, 89:

Tautan ke GIF

0.2, 144, 89:

Tautan ke GIF

0.53, 144, 89:

Tautan ke GIF

JAD
sumber
Animasi Anda terlihat sangat keren - kepadatan apa yang Anda gunakan? Sepertinya semuanya macet dengan cukup cepat dengan banyak ruang kosong
qwr
@ qr itu sebenarnya adalah sesuatu yang menggangguku. Dalam program saya semuanya macet pada kepadatan yang lebih rendah daripada pada contoh yang Anda tautkan. Saya tidak dapat mengingat parameter yang tepat digunakan untuk plot, tetapi bisa jadi 0.38 144 89itu contohnya.
JAD
Bermain-main dengan kisi-kisi persegi saya mendapat kerapatan 0,35 untuk macet jasondavies.com/bml/#0.35/100/100 tetapi hampir selalu satu garis 45deg tebal daripada garis diagonal tipis. Karena garis Anda terlihat lebih vertikal, saya pikir sesuatu dengan dua jenis mobil tidak aktif
qwr
Saya melihat masalahnya sekarang. Cara hanya dapat maju jika mereka tidak diblokir oleh mobil lain. Jadi, dalam contoh Wikipedia, semua mobil yang bergerak memiliki ruang di depannya. Tetapi dalam animasi Anda, mobil-mobil bergerak sebagai garis. Menarik.
qwr
Ah, itu akan melakukannya.
JAD
5

Mathematica, 237 228 203 198 181 byte

(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]])&

Outputnya adalah dinamis Image. Latar belakangnya hijau muda, dan mobil-mobil itu berwarna hitam atau magenta, tergantung pada arahnya.

Penjelasan

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

Buat papan awal:

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

Setel ike 2. Buat Listdari {0, 2}, yang panjangnya lantai (density * lebar * tinggi / 2) (dibagi dua karena {0, 2}merupakan panjang-2).

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

Bentuk kembali 2-D yang dihasilkan List(2 x sesuatu) menjadi 1-D List(panjang = lebar * tinggi). Pad 1jika tidak ada nilai yang cukup.

RandomSample@ ...

(Pseudo-) secara acak mengurutkan hasilnya.

... ~Partition~#2

Partisi itu menghasilkan panjang (lebar).

b= ...

Simpan itu di b.


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

Buat Dynamic Image:

i=-i;

Balikkan tanda i.

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

Terapkan otomat seluler dengan aturan 193973693dan bobot tetangga {{0, 0, 0}, {3, 9, 1}, {0, 0, 0}}untuk bditransposisikan. Set bsama dengan itu.

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

Jika ipositif, biarkan bsendiri. Jika tidak, transpos b( 2-ada karena saya CellularAutomatonbermain golf sedikit). Pada dasarnya, ini mentranspos bsetiap iterasi lainnya (untuk membatalkan transposisi)

Colorize[ ... ]

Ubah array menjadi warna-warni Image.

Dynamic@ ...

Buat ekspresi Dynamic. yaitu fungsi di atas dijalankan berulang kali.

Keluaran

Berikut ini contoh output (input:) 0.35, 192, 108untuk 2000 frame (diperbesar 2x).

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

JungHwan Min
sumber
Huh, menggunakan built-in lebih lama daripada tidak menggunakannya ?!
Adám
3

Dyalog APL , 190 108 115 112 byte

Larutan

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

TryAPL online (sedikit dimodifikasi karena batasan online):

  1. Set ⎕IO←0, mendefinisikan fungsi S , dan kemudian menentukan dan menampilkan random 38% 14 × 29 grid, G .

  2. Buat satu langkah ke bawah.

  3. Lakukan satu gerakan ke kanan.

  4. Lanjutkan ke langkah 2.

    Lalu lintas
    Animasi algoritma sebelumnya, yang tidak menjamin kepadatan.

Penjelasan

S←{tentukan fungsi langsung S (dijelaskan di sini dari kanan ke kiri):

÷4 kebalikan dari 4 (0,25)

⎕DL tunggu beberapa detik (mengembalikan waktu yang sebenarnya berlalu)

⍵⊣ Buang yang mendukung ⍵ (argumen yang tepat; kisi)

⎕← output itu

 mengubah urutan

⍉⍣⍺ transpos kembali lagi jika ⍺ (argumen kiri; 0 = turun, 1 = kanan)

( terapkan kereta fungsi (dijelaskan di sini dari kiri ke kanan):

  ,⍨ argumen ditambahkan ke dirinya sendiri

  , ditambahkan ke

   diri

)

 membagi matriks menjadi daftar daftar

( search regex (dijelaskan di sini dari kiri ke kanan):

  ⍺⊃ pilih salah satu dari dua berikut berdasarkan ⍺ (0 = bawah / pertama, 1 = kanan / detik)

  '(↓+) ' '(→+) ' urutan panah bawah dan kiri diikuti oleh spasi

)⎕R' \1' ganti dengan spasi diikuti oleh urutan yang ditemukan

 mencampur daftar daftar ke dalam matriks

 mengubah urutan

d[⍺]↓ jatuhkan baris "tinggi" jika ⍺ (argumen kiri) adalah 0 (bawah) atau baris "lebar" jika ⍺ adalah 1 (kanan)

d[⍺]↑ lalu ambil banyak baris

 pass through (berfungsi sebagai pemisah)

⍉⍣⍺ transpos jika ⍺ (argumen kiri; 0 = turun, 1 = kanan)

}


' ↓→'[ mengindeks string dengan (dijelaskan di sini dari kanan ke kiri):

 input numerik (dimensi)

d← tetapkan itu untuk d

×/ kalikan dimensi (temukan jumlah sel)

c← menetapkan itu untuk c

⎕× kalikan dengan input numerik (densitas)

 bulat ke bawah

1 2⍴⍨ ulangi secara siklis satu dan dua sampai sepanjang itu

c↑ memperpanjang itu sampai panjang c , padding dengan nol

d⍴ gunakan d (dimensi) untuk membentuk kembali

{ terapkan fungsi anonim ini untuk itu (dijelaskan di sini dari kiri ke kanan):

  ⍵[ argumen yang benar (daftar nol, satu, dan dua) diindeks oleh

   ?⍨ indeks dikocok hingga

   ⍴⍵ panjang argumen

  ]

}

]

{ terapkan fungsi anonim berikut (dijelaskan dari kanan ke kiri):

0S⍵ terapkan S dengan 0 (turun) sebagai argumen kiri dan kisi sebagai argumen kanan

1S dengan argumen yang benar, terapkan S dengan 1 (kanan) sebagai argumen kiri

}⍣≡ sampai dua iterasi berturut-turut adalah identik (kemacetan lalu lintas)

Catatan

  1. Membutuhkan ⎕IO←0, yang merupakan standar pada banyak sistem.

  2. Anjuran untuk (tinggi, lebar), dan kemudian untuk kepadatan.

  3. Tidak menggunakan otomat bawaan.

  4. Apakah menggunakan dukungan regex bawaan.

  5. Berhenti jika ada kemacetan (tidak ada mobil yang bisa bergerak).

  6. Matriks karakter keluaran di mana mewakili mobil yang bergerak ke kanan, mewakili mobil yang bergerak ke bawah, dan spasi adalah jalan yang kosong.

  7. Seperti di atas, output ke sesi pada 4 Hz, tetapi frekuensi dapat disesuaikan dengan mengubah ÷4; misal ÷33 Hz dan .3³⁄₁₀ Hz.

  8. Lebih mudah untuk melihat apa yang terjadi jika mengeksekusi ]Box on -s=max -f=on terlebih dahulu.

  9. Distribusi yang diperlukan sekarang dijamin, dan dua jenis mobil terjadi tepat 50-50, kecuali untuk pembulatan.

Adm
sumber
Pembuatan papan awal Anda tidak menjamin papan yang memiliki kepadatan input. Saya kira itu adalah pilihan OP apakah mengizinkannya atau tidak.
JungHwan Min
Oh, @JarkoDubbeldam sudah menanyakan hal itu.
JungHwan Min
@JungHwanMin Bagaimana bisa begitu? Biarkan kerapatan menjadi d. Setiap posisi mendapat nilai antara 0 dan 1. Jika antara 0 dan ᵈ⁄₂ itu menjadi ,. Jika antara ᵈ⁄₂ dan d itu menjadi a . Jika antara d dan 1 tetap kosong.
Adm
Nah, kasus ekstrem adalah: setiap posisi entah bagaimana mendapatkan nilai 0(karena mereka (pseudo) - dihasilkan secara acak (pseudo) - secara independen; sangat tidak mungkin tetapi mungkin). Maka papan Anda penuh dengan s.
JungHwan Min
@JungHwanMin Ah, saya mengerti maksud Anda.
Adem
1

Java (624 Bytes + 18 Bytes untuk Java.awt. * = 642 Bytes)

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

Tidak Disatukan:

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

Gambar:

masukkan deskripsi gambar di sini

Guci Gurita Ajaib
sumber
Tidak terbiasa dengan java, tetapi apakah merah, biru dan putih nama terpendek untuk warna yang dapat Anda gunakan? (mungkin abu-abu adalah pilihan, menghemat satu byte vs putih)
JAD
Tangkapan layar tampaknya menunjukkan masalah yang sama dengan apa yang saya jelaskan di sini codegolf.stackexchange.com/questions/104742/a-2d-traffic-jam/…
qwr