การจราจรติดขัด 2D


17

Biham-Middleton-Levineเป็นระบบอัตโนมัติเซลลูลาร์ที่จัดระเบียบตัวเองซึ่งจำลองรูปแบบการรับส่งข้อมูลที่ง่ายขึ้น

ประกอบด้วยจำนวนรถยนต์ที่เป็นตัวแทนจากจุดบนโครงตาข่ายที่มีตำแหน่งเริ่มต้นแบบสุ่มซึ่งรถแต่ละคันอาจเป็นหนึ่งในสองประเภท: รถยนต์ที่เลื่อนลงด้านล่างเท่านั้น ขวา (แสดงเป็นสีแดงในบทความนี้) รถยนต์ทั้งสองประเภทเลี้ยวไปไหนมาไหน ในแต่ละเทิร์นทุกคันสำหรับประเภทที่เกี่ยวข้องล่วงหน้าหนึ่งก้าวหากพวกเขาไม่ได้ถูกบล็อคโดยรถคันอื่น

งานของคุณคือการมองเห็นโมเดลนี้เป็นภาพเคลื่อนไหว นี่คือการสาธิตที่ดี

ป้อนคำอธิบายรูปภาพที่นี่

อินพุต

จำนวนจุดลอยตัวระหว่าง 0 ถึง 1 แสดงถึงความหนาแน่นและจำนวนเต็มสองจำนวนแทนความสูงและความกว้างของตารางที่แสดง สมมติว่าอินพุตถูกต้องและพารามิเตอร์ของฟังก์ชันหรือการอ่านจากอินพุตของผู้ใช้นั้นใช้ได้ทั้งคู่

ตัวอย่าง: 0.38 144 89(สอดคล้องกับภาพด้านบน)

เอาท์พุต

กริดอย่างน้อย 80x80 ที่แสดงภาพเคลื่อนไหวของรุ่นนี้ทำงาน ในตอนแรกรถยนต์จะถูกสุ่มวางบนกริดจนกระทั่งกริดถึงความหนาแน่นอินพุตด้วยสีแดงครึ่งและสีน้ำเงินครึ่ง (นั่นคือความหนาแน่นคูณด้วยจำนวนรวมของกริดสแควร์ส ความหนาแน่นต้องเป็นค่านี้ซึ่งหมายความว่าคุณไม่สามารถเติมความหนาแน่นของแต่ละเซลล์ให้เต็มความน่าจะเป็น ในแต่ละขั้นตอนรถประเภทหนึ่งอาจเลื่อนลงหรือหมุนไปทางขวาหากว่าผ่านไปได้ ประเภทของรถยนต์ที่เคลื่อนที่สลับในแต่ละขั้นตอน ในการทำให้ภาพเคลื่อนไหวสามารถดูได้ต้องมีอย่างน้อย 10 ms ระหว่างแต่ละขั้นตอน

กฎระเบียบ

  • รถยนต์สามารถเป็นสีหรือสัญลักษณ์ใด ๆ ตราบเท่าที่พวกเขาสามารถแยกออกจากกันและพื้นหลังและรถแต่ละประเภทเป็นสีหรือสัญลักษณ์เดียวกัน

  • ทั้งคอนโซลและเอาต์พุตกราฟิกได้รับอนุญาต สำหรับเอาต์พุตคอนโซลสัญลักษณ์ที่พิมพ์ได้ใด ๆ นั้นใช้ได้ แต่เอาต์พุตต้องเป็นกริดของอักขระ

  • โปรดระบุประเภทผลลัพธ์ที่คุณได้รับหากคุณไม่มีภาพหน้าจอหรือ 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()}}

Ungolfed:

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,yqm1-10

f1เป็นฟังก์ชั่นที่ย้ายรถยนต์หนึ่งแถวที่กำลังมองหารถยนต์รหัสตาม มันจะตรวจสอบว่ารถสามารถเคลื่อนย้ายได้โดยการตรวจสอบสำหรับ1s 0ตามด้วย เราใช้applyเพื่อวิ่งfบนทุกแถวหรือคอลัมน์ขึ้นอยู่กับรถคันไหน

fจัดการกับการเคลื่อนที่ของ1รถยนต์เพื่อเคลื่อนย้าย-1รถยนต์เราเปลี่ยนเมทริกซ์ไปตามทิศทางของการเคลื่อนที่คูณเมทริกซ์ด้วย-1ดังนั้น-1รถจะกลายเป็น1รถยนต์และ vv และเมทริกซ์ที่ได้จะถูกเปลี่ยนอีกครั้ง

สิ่งนี้ใช้imageเพื่อสร้างพล็อตโดยใช้ 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

การเล่นกับกริดแบบสี่เหลี่ยมฉันมีความหนาแน่น 0.35 ถึงติดขัดjasondavies.com/bml/#0.35/100/100แต่เกือบ 45deg เส้นหนาหนึ่งเส้นแทนที่จะเป็นเส้นทแยงมุมบางเส้น ตั้งแต่สายของคุณดูแนวตั้งมากขึ้นผมคิดว่าสิ่งที่มีสองประเภทของรถยนต์ที่ปิด
qwr

ฉันเห็นปัญหาตอนนี้ คาร่าสามารถเลื่อนไปได้ก็ต่อเมื่อพวกเขาไม่ได้ถูกบล็อคโดยรถคันอื่น ดังนั้นในตัวอย่างวิกิพีเดียรถที่เคลื่อนที่ทุกคันจะมีช่องว่างอยู่ข้างหน้าพวกเขา แต่ในอนิเมชั่นของคุณรถจะเคลื่อนที่เป็นเส้น น่าสนใจ
qwr

อานั่นจะทำเช่นนั้น
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]

ตั้งค่าการi 2สร้างListของ{0, 2}ซึ่งมีความยาวชั้น (ความหนาแน่น * กว้าง * สูง / 2) (หารด้วยสองเพราะ{0, 2}มีความยาว -2)

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

เปลี่ยนรูปร่างของผล 2-D List(2 x อะไร) เป็น 1-D List(length = width * height) แพด1หากมีค่าไม่เพียงพอ

RandomSample@ ...

(Pseudo-) เรียงลำดับผลลัพธ์แบบสุ่ม

... ~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 เฟรม (ขยาย 2x)

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


หืมมการใช้งานในตัวนั้นนานกว่าการใช้งานไม่ได้เหรอ!
อดัม

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% 14 × 29 ตารางG

  2. ทำให้เลื่อนลงหนึ่งครั้ง

  3. เลื่อนไปทางขวาหนึ่งครั้ง

  4. ไปที่ขั้นตอนที่ 2

    การจราจร
    แอนิเมชันของอัลกอริทึมก่อนหน้าซึ่งไม่รับประกันความหนาแน่น

คำอธิบาย

S←{กำหนดฟังก์ชั่นโดยตรงS (อธิบายที่นี่จากขวาไปซ้าย):

÷4 ส่วนกลับของ 4 (0.25)

⎕DL รอหลายวินาที (ส่งคืนเวลาที่ผ่านไปจริง)

⍵⊣ ยกเลิกการสนับสนุน⍵ (อาร์กิวเมนต์ที่ถูกต้อง; กริด)

⎕← เอาท์พุทที่

 transpose

⍉⍣⍺ ย้ายกลับอีกครั้งถ้า⍺ (อาร์กิวเมนต์ซ้าย; 0 = ลง, 1 = ขวา)

( ใช้รถไฟฟังก์ชั่น (อธิบายที่นี่จากซ้ายไปขวา):

  ,⍨ อาร์กิวเมนต์ต่อท้ายตัวเอง

  , ผนวกเข้ากับ

   ตัวเอง

)

 แบ่งเมทริกซ์เป็นรายการ

( ค้นหา regex (อธิบายที่นี่จากซ้ายไปขวา):

  ⍺⊃ เลือกหนึ่งในสองสิ่งต่อไปนี้โดยยึดตาม⍺ (0 = ลง / ก่อน 1 = ขวา / วินาที)

  '(↓+) ' '(→+) ' ลำดับลูกศรลงและซ้ายตามด้วยเว้นวรรค

)⎕R' \1' แทนที่ด้วยช่องว่างตามด้วยลำดับที่พบ

 รายการผสมของรายการลงในเมทริกซ์

 transpose

d[⍺]↓ วางแถว "height" ถ้า⍺ (อาร์กิวเมนต์ซ้าย) เป็น 0 (ลง) หรือ "width" แถวถ้า⍺คือ 1 (ขวา)

d[⍺]↑ จากนั้นใช้หลายแถว

 ผ่าน (ทำหน้าที่เป็นตัวคั่น)

⍉⍣⍺ ไขว้ถ้า⍺ (อาร์กิวเมนต์ซ้าย; 0 = ลง, 1 = ขวา)

}


' ↓→'[ จัดทำดัชนีสตริงด้วย (อธิบายที่นี่จากขวาไปซ้าย):

 อินพุตตัวเลข (ขนาด)

d← กำหนดให้กับd

×/ คูณมิติ (ค้นหาจำนวนเซลล์)

c← กำหนดให้กับc

⎕× คูณด้วยอินพุตตัวเลข (ความหนาแน่น)

 ปัดเศษลง

1 2⍴⍨ วนซ้ำหนึ่งและสองจนครบรอบ

c↑ ขยายจนความยาวc , padding ด้วยศูนย์

d⍴ ใช้d (ขนาด) เพื่อปรับรูปร่างใหม่

{ ใช้ฟังก์ชันที่ไม่ระบุชื่อนี้กับที่ (อธิบายที่นี่จากซ้ายไปขวา):

  ⍵[ อาร์กิวเมนต์ที่ถูกต้อง (รายการของศูนย์, คน, และสอง) ทำดัชนีโดย

   ?⍨ ดัชนีที่สับได้สูงสุด

   ⍴⍵ ความยาวของการโต้แย้ง

  ]

}

]

{ ใช้ฟังก์ชันที่ไม่ระบุชื่อต่อไปนี้ (อธิบายจากขวาไปซ้าย):

0S⍵ ใช้Sกับ 0 (ลง) เป็นอาร์กิวเมนต์ด้านซ้ายและกริดเป็นอาร์กิวเมนต์ที่ถูกต้อง

1S เมื่อใช้อาร์กิวเมนต์ขวาให้ใช้Sกับ 1 (ขวา) เป็นอาร์กิวเมนต์ซ้าย

}⍣≡ จนกว่าจะมีการทำซ้ำสองครั้งติดต่อกัน (การจราจรติดขัด)

หมายเหตุ

  1. ต้องการ⎕IO←0ซึ่งเป็นค่าเริ่มต้นในหลาย ๆ ระบบ

  2. พร้อมต์สำหรับ (ความสูงความกว้าง) และจากนั้นสำหรับความหนาแน่น

  3. ห้ามใช้ออโตเมติกในตัว

  4. ใช้การสนับสนุน regex ในตัว

  5. หยุดหากมีการจราจรติดขัด (ไม่มีรถยนต์เคลื่อนที่ได้)

  6. เอาท์พุทเมทริกซ์อักขระที่แสดงถึงรถยนต์ที่กำลังเคลื่อนที่ขวาหมายถึงรถยนต์ที่กำลังเคลื่อนลงและพื้นที่เป็นถนนที่ว่างเปล่า

  7. ดังกล่าวข้างต้นจะส่งออกไปยังเซสชั่นที่ 4 Hz แต่ความถี่สามารถปรับได้โดยการเปลี่ยน÷4; เช่น÷33 Hz และ.3³⁄₁₀ Hz

  8. มันง่ายกว่าที่จะเห็นสิ่งที่เกิดขึ้นหากดำเนินการ]Box on -s=max -f=onครั้งแรก

  9. รับประกันการกระจายที่ต้องการตอนนี้และรถยนต์สองประเภทเกิดขึ้นใน 50-50 ที่แน่นอนประหยัดสำหรับการปัดเศษ


การสร้างบอร์ดเริ่มต้นของคุณไม่รับประกันว่าบอร์ดจะมีความหนาแน่นของอินพุต ฉันเดาว่าเป็นตัวเลือกของ OP ว่าจะอนุญาตหรือไม่
จองฮันมิน

โอ้ @JarkoDubbeldam ถามแล้ว
จองฮันมิน

@JungHwanMin เหรอ? ปล่อยให้ความหนาแน่นเป็น d ทุกตำแหน่งจะได้รับค่าระหว่าง 0 และ 1 หากระหว่าง 0 ถึง ᵈ⁄₂ จะกลายเป็น a , หากระหว่างᵈ/₂และงมันจะกลายเป็น ถ้าอยู่ระหว่าง d ถึง 1 มันจะว่างเปล่า
2559

กรณีที่รุนแรงก็คือ: ทุก ๆ ตำแหน่งจะได้รับค่า0(เพราะพวกเขา (หลอก) - สร้างขึ้นแบบสุ่ม (หลอก) - พึ่งพากันไม่น่าจะเป็นไปได้มาก แต่เป็นไปได้) บอร์ดของคุณก็เต็มไปด้วย
JungHwan Min

@JungHwanMin อ่าฉันเห็นว่าคุณหมายถึงอะไร
2559

1

Java (624 Bytes + 18 Bytes สำหรับ 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){}}}

Ungolfed:

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 แต่ชื่อแดงน้ำเงินและขาวเป็นชื่อที่สั้นที่สุดสำหรับสีที่คุณสามารถใช้ได้ใช่หรือไม่ (อาจเป็นสีเทาเป็นตัวเลือกประหยัดหนึ่งไบต์กับขาว)
JAD

ภาพหน้าจอปรากฏขึ้นเพื่อแสดงปัญหาเดียวกับที่ฉันอธิบายไว้ที่นี่codegolf.stackexchange.com/questions/104742/a-2d-traffic-jam/…
qwr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.