2D交通堵塞


17

比哈姆-米德尔顿-莱文流量模型是一个自组织的细胞自动机模型简化流量。

它由许多汽车组成,这些汽车由具有随机起始位置的点阵上的点表示,其中每辆汽车可能是以下两种类型之一:仅向下移动的汽车(在本文中显示为蓝色),以及仅向下方移动的汽车右(在本文中显示为红色)。两种类型的汽车轮流行驶。在每一转弯期间,如果相应类型的所有汽车都没有被另一辆汽车挡住,则它们前进一个步骤。

您的任务是将该模型可视化为动画。这是一些很好的示范。

在此处输入图片说明

输入项

0到1之间的浮点数表示密度,而两个整数表示所显示的网格高度和宽度。假设输入是有效的,并且函数的参数或从用户输入读取的参数都很好。

示例:(0.38 144 89对应于上图)

输出量

至少80x80的网格显示正在运行的模型的动画。开始时,将汽车随机放置在网格上,直到网格达到输入密度,其中一半为红色,另一半为蓝色(即密度乘以网格正方形的总数,但可以四舍五入)。密度必须是此值,这意味着您不能以密度填充每个像元。对于每一步,一种类型的汽车要么向下移动要么向右移动,如果它们越过边缘则环绕。移动的汽车类型交替出现。为了使动画可见,每个步骤之间必须至少有10毫秒。

规则

  • 这些汽车可以是任何颜色或符号,只要它们可以与背景和背景区分开即可,并且每种汽车类型都是相同的颜色或符号。

  • 都允许控制台和图形输出。对于控制台输出,任何可打印的符号都可以,但是输出必须为字符网格。

  • 如果没有屏幕截图或gif,请指定产生的输出类型。

  • 模拟必须永远运行。

输出有点复杂,因此如果您有任何疑问,请发表评论。


对动画必须多慢或多快运行有任何限制吗?
xnor

也许值得指出的是,移动汽车的类型会交替出现。
格雷格·马丁

@xnor我在考虑每个循环至少5到10毫秒,但是我不确定这是否很难测量。
qwr

3
密度是意味着密度必须是该值,还是仅仅每个像素都有被填充的概率d?另外,我们是否必须随机分配汽车的颜色?如果是随机的,如果它们只有50-50种颜色的可能性,那又可以吗?
2016年

1
@JarkoDubbeldam密度必须是该值。他们每种颜色都有50-50的机会。但是我回答晚了,所以答案可能有所不同。汽车可以向上或向左移动。
qwr

Answers:


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。它先检查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是示例中的参数。
2016年

在正方形网格上玩时,我得到0.35的密度来干扰jasondavies.com/bml/#0.35/100/100,但它几乎总是一条45度粗线,而不是细对角线。由于您的线条看起来更垂直,因此我认为两种类型的汽车
都已停工

我现在看到了问题。卡拉只有在没有被其他汽车阻挡的情况下才能前进。因此,在Wikipedia示例中,所有行驶中的汽车在其前面都有一个空间。但是在您的动画中,汽车沿直线运动。有趣。
qwr

嗯,那样就可以了。
2016年

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。创建一个Listof {0, 2},其长度为floor(密度*宽度*高度/ 2)(由于{0, 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管它了。如果没有,转置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,定义函数小号,然后定义和显示一随机38%14×29网格,ģ

  2. 下移一个。

  3. 向右移动。

  4. 转到步骤2。

    交通
    先前算法的动画,不能保证密度。

说明

S←{定义直接函数S(此处从右到左说明):

÷4 倒数4(0.25)

⎕DL 等待那么多秒(返回实际经过的时间)

⍵⊣ 抛弃赞成⍵的观点(正确的论点;网格)

⎕← 输出

 转置

⍉⍣⍺ 如果⍺(左引数; 0 =向下,1 =右边),再次转置

( 应用功能火车(在这里从左到右解释):

  ,⍨ 论点附加到自身

  , 附加到

   本身

)

 将矩阵拆分为列表列表

( 搜索正则表达式(此处从左到右说明):

  ⍺⊃ 根据从以下两个中选择一个(0 =下/第一,1 =右/秒)

  '(↓+) ' '(→+) ' 向下和向左箭头序列,后跟一个空格

)⎕R' \1' 替换为空格,后跟找到的序列

 将列表列表混合到矩阵中

 转置

d[⍺]↓ 如果⍺(左参数)为0(向下),则删除“高度”行;如果⍺为1(右),则为“宽度”行

d[⍺]↑ 然后走那么多行

 通过(用作分隔符)

⍉⍣⍺ 如果⍺(左参数; 0 =向下,1 =右侧)转置

}


' ↓→'[ 索引字符串(在这里从右到左解释):

 数字输入(尺寸)

d← 分配给d

×/ 乘以尺寸(查找细胞数)

c← 分配给c

⎕× 用数字输入(密度)乘以

 四舍五入

1 2⍴⍨ 循环重复一和二,直到达到该长度

c↑ 扩展到长度c,用零填充

d⍴ 使用d(尺寸)重塑形状

{ 对此应用此匿名函数(此处从左到右解释):

  ⍵[ 索引的正确参数(零,一和二的列表)

   ?⍨ 洗牌指数直至

   ⍴⍵ 参数的长度

  ]

}

]

{ 应用以下匿名函数(从右到左解释):

0S⍵ 将S(0(向下))用作左参数,将grid(网格)用作右参数

1S 将其作为右参数,将1(右)作为S应用于左参数

}⍣≡ 直到两个连续的迭代都相同(交通拥堵)

笔记

  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. 现在,保证了所需的分配,并且除了舍入之外,两种类型的汽车正好以50-50的比例出现。


您最初的电路板生成不能保证电路板具有输入密度。我想是否允许它是OP的选择。
JungHwan Min

哦,@ JarkoDubbeldam已经问过了。
JungHwan Min

@JungHwanMin怎么样?令密度为d。每个位置的值都在0到1之间。如果在0到⁄⁄2之间,它将变成一个.。如果在ᵈ⁄²和d之间,则变为。如果介于d和1之间,则保持为空。
阿达姆,2013年

好吧,一个极端的情况是:每个头寸都以某种方式获取价值0(因为它们是(伪)随机生成的(伪);非常不可能,但是可能)。则您的面板上满是s。
JungHwan Min

@JungHwanMin啊,我明白你的意思了。
阿达姆,2013年

1

Java(624字节+ 18字节的Java.awt。* = 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,但是红色,蓝色和白色是您可以使用的颜色的最短名称吗?(也许灰色是一种选择,与白色相比节省了一个字节)
JAD 2016年

屏幕快照似乎显示出与我在此处描述的问题相同的问题codegolf.stackexchange.com/questions/104742/a-2d-traffic-jam/…–
qwr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.