标题: [技术讨论] 细胞自动机Python脚本运行到最后都稳定在一个状态不变了,高手给看看算法对不对 [打印本页]
作者: 普大喜奔 时间: 2014-9-27 20:54 标题: 细胞自动机Python脚本运行到最后都稳定在一个状态不变了,高手给看看算法对不对
- import random
- import os
- import time
- def init(level):
- return random.randint(0,level)
- dict={' ':0,'●':1}
- cells=[[' ' for x in range(32)] for y in range(22)]
- grid=[[' ' for x in range(32)] for y in range(22)]
- while True:
- level=input('larger number,less cells (>0):')
- try:
- if int(level)>0:
- for y in range(1,21):
- for x in range(1,31):
- r=random.randint(0,int(level))
- if r==0:cells[y][x]='●'
- break
- except:pass
-
- for y in cells:print(' '.join(y))
- print("press key to begin...")
- os.system('pause >nul')
- i=0
- while True:
- for y in range(1,21):
- for x in range(1,31):
- num=dict[cells[y-1][x-1]]+\
- dict[cells[y-1][x+1]]+\
- dict[cells[y-1][x]]+\
- dict[cells[y+1][x-1]]+\
- dict[cells[y+1][x+1]]+\
- dict[cells[y+1][x]]+\
- dict[cells[y][x-1]]+\
- dict[cells[y][x+1]]
- if num==3:grid[y][x]='●'
- elif num==2:grid[y][x]=cells[y][x]
- elif num :grid[y][x]=' '
- for y in range(1,21):
- for x in range(1,31):
- cells[y][x]=grid[y][x]
- time.sleep(0.05)
- os.system('cls')
- i+=1
- print('time: '+str(i))
- for y in cells:print(' '.join(y))
复制代码
这是出生概率为33%时的稳定状态,基本不变了,个别在动
概率50%的
如果要把这个脚本用迭代函数或者生成器写出来,该怎么改啊,加上是二维数组我更不会写了
作者: 普大喜奔 时间: 2014-9-27 20:55
开头那个函数忘了删掉了 没有用
作者: CrLf 时间: 2014-9-27 21:20
看图好像没什么问题吧,有些形状就是稳定的
作者: 普大喜奔 时间: 2014-9-27 21:45
回复 3# CrLf
原来是运气问题 10%概率的时候竟然运行到1200多次才稳定 先前没几下就死完了
作者: CrLf 时间: 2014-9-27 21:52
运行了一下,发现结果好像不太对,有些“孤独”的细胞也不会死亡,看代码没看出来为什么
作者: 普大喜奔 时间: 2014-9-27 22:02
回复 5# CrLf
对啊 肯定有问题
作者: 普大喜奔 时间: 2014-9-27 22:07
回复 5# CrLf
有一行我写错了 elif:num 应该改成else:
作者: 普大喜奔 时间: 2014-9-27 22:08
回复 5# CrLf
在第37行那 可是逻辑上这两者没什么不同啊
作者: 普大喜奔 时间: 2014-9-27 22:17
回复 5# CrLf
改了37行以后应该对了运行了几次都类似这种
我还奇怪呢 10%的概率那么小怎么变化那么久 你不说我都想不起来孤立这回事
作者: 普大喜奔 时间: 2014-9-27 22:24
改制后基本各种概率下基本都在200次以内稳定了
作者: 523066680 时间: 2014-9-27 22:38
本帖最后由 523066680 于 2014-9-27 22:42 编辑
我在写perl版本细胞自动机的时候遇到这样的问题:数组赋值变成了引用。
修改赋值方式后得以解决,会不会是相同的问题?
现在不搞python了,没心思细看。
作者: 普大喜奔 时间: 2014-9-27 22:42
回复 11# 523066680
很有可能啊 我试试看直接引用是什么效果 然后对比一下
作者: 普大喜奔 时间: 2014-9-27 22:51
回复 11# 523066680
改成引用后明显运动没规律了 细胞较多时好像不像能稳定的样子 我原先改过的应该是对的 都稳定了 形态也符合算法
作者: 523066680 时间: 2014-9-27 22:53
回复 13# 普大喜奔
恩 我就是说要避免引用。
作者: 523066680 时间: 2014-9-27 22:57
如果要验证显示结果对不对,可以把典型的生命矩阵代入- ......................**...............
- ......................**...............
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .........*..........**...**............
- .......*.*............***..............
- ......*.*............*...*.............
- **...*..*.............*.*..............
- **....*.*..............*...............
- .......*.*......*.*....................
- .........*......**.....................
- .................*...*.................
- .....................**......*.........
- ....................*.*......*.*.......
- ...............*..............*.*....**
- ..............*.*.............*..*...**
- .............*...*............*.*......
- ..............***............*.*.......
- ............**...**..........*.........
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- .......................................
- ...............**......................
- ...............**......................
复制代码
作者: 普大喜奔 时间: 2014-9-27 22:58
回复 14# 523066680
谢啦版主 看来细胞自动机最后都要稳定啊
作者: 523066680 时间: 2014-9-27 23:00 标题: RE: 细胞自动机脚本运行到最后都稳定在一个状态不变了,高手给看看算法对不对
本帖最后由 523066680 于 2014-9-27 23:04 编辑
回复 16# 普大喜奔
前面发的一个矩阵是无限循环的。
再发一个典型的刷了很久的轰炸模型, 挺精彩的,运行好一段时间才进入稳定状态,当然,还要看你的空间设置为多大。- .........................**.....**
- .........................**.....**
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ...........................**.**..
- ..........................*.....*.
- ..................................
- .........................*.......*
- .........................*..*.*..*
- .........................***...***
- ..................................
- ..................................
- ..................................
- ..................................
- .................*................
- **...............**...............
- **................**..............
- .............**..**...............
- ..................................
- ..................................
- ..................................
- .............**..**...............
- **................**.......**.....
- **...............**........**.....
- .................*................
复制代码
作者: 普大喜奔 时间: 2014-9-27 23:06
回复 17# 523066680
版主好人!
只是输入矩阵麻烦些 我试试吧
作者: 523066680 时间: 2014-9-27 23:06 标题: Perl版,轰炸机模型
- use strict;
- use Term::ReadKey;
- use Win32::Console;
- use Time::HiRes 'sleep';
- use IO::Handle;
- STDOUT->autoflush(1);
- system("mode con lines=40 cols=200");
-
- our $OUT=Win32::Console->new(STD_OUTPUT_HANDLE);
- $OUT->Cursor(20, 20, 99, 0); #hide cursor
-
- my ($i, $j);
- our ($rows, $cols) = (40, 90);
- our ($mxrow, $mxcol) = ($rows-1, $cols-1);
-
- # init
- our @coord;
- my (@h, @n);
- my $y = 0;
-
- foreach (<DATA>) {
- s/\r?\n$//;
- tr/\*\./10/;
- @{$h[$y++]} = ( split("", $_) );
- }
-
- foreach $i (0 .. $mxrow) {
- foreach $j (0 .. $mxcol) {
- $coord[$i][$j]{'x'} = $j*2;
- $coord[$i][$j]{'y'} = $i;
- $h[$i][$j] = 0 unless (defined $h[$i][$j]);
- $n[$i][$j] = 0;
- }
- }
-
- &Draw(\@n, \@h);
- while (1) {
- sleep 0.02;
- @n = ();
- &NextBuffer(\@h, \@n);
- &Draw(\@h, \@n);
- @h = (@n);
-
- &KeyFunc();
- }
-
- sub NextBuffer {
- my ($ra, $rb) = (shift, shift);
- my ($i, $j, $sum);
- my ($L, $R, $U, $D);
- foreach $i (0 .. $mxrow) {
- $U = ($i-1) < 0 ? $mxrow : ($i-1);
- $D = ($i+1) > $mxrow ? 0 : ($i+1);
- foreach $j (0 .. $mxcol) {
- $L = ($j-1) < 0 ? $mxcol : ($j-1);
- $R = ($j+1) > $mxcol ? 0 : ($j+1);
- $sum = $ra->[$U][$L] + $ra->[$U][$j] + $ra->[$U][$R] +
- $ra->[$i][$L] + 0 + $ra->[$i][$R] +
- $ra->[$D][$L] + $ra->[$D][$j] + $ra->[$D][$R];
-
- if ($sum == 3) {
- $rb->[$i][$j] = 1;
- } elsif ($sum == 2) {
- $rb->[$i][$j] = $ra->[$i][$j];
- } else {
- $rb->[$i][$j] = 0;
- }
- }
- }
- }
-
- sub Draw {
- my ($ra, $rb) = (shift, shift);
- foreach $i (0 .. $mxrow) {
- foreach $j (0 .. $mxcol) {
- if ($rb->[$i][$j] != $ra->[$i][$j]) {
- &Point(
- $coord[$i][$j]{'x'},
- $coord[$i][$j]{'y'},
- $rb->[$i][$j],
- );
- }
- }
- }
- }
-
- sub Point {
- my ($mx, $my, $light) = (shift, shift, shift);
- my $color;
- if ($light == 1) {
- $color = $FG_WHITE|$BG_GRAY;
- } else {
- $color = $FG_WHITE|$BG_BLACK;
- }
- $OUT->Cursor($mx, $my);
- $OUT->FillAttr($color, 2, $mx, $my);
- }
-
- sub KeyFunc {
- my $key;
- $key = ReadKey(-1);
- return if (not defined $key);
- if ( ord($key) == 27 ) {
- exit;
- }
- }
-
-
-
- __DATA__
- .........................**.....**
- .........................**.....**
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ..................................
- ...........................**.**..
- ..........................*.....*.
- ..................................
- .........................*.......*
- .........................*..*.*..*
- .........................***...***
- ..................................
- ..................................
- ..................................
- ..................................
- .................*................
- **...............**...............
- **................**..............
- .............**..**...............
- ..................................
- ..................................
- ..................................
- .............**..**...............
- **................**.......**.....
- **...............**........**.....
- .................*................
复制代码
作者: 523066680 时间: 2014-9-27 23:07
回复 18# 普大喜奔
也搞一个读入矩阵的函数嘛,我在wiki挖了好多经典的模型。
作者: CrLf 时间: 2014-9-27 23:13
回复 8# 普大喜奔
不一样啊,num 变量不包括 dict[cells[y][x]],所以当周围的格子都是空的时候 elif num: 将不成立,cells[x][y] 的内容会维持上一轮循环的状态,所以会出现独立的细胞永垂不朽的现象
作者: 普大喜奔 时间: 2014-9-27 23:14
回复 20# 523066680
读入应该不难 难的是cmd窗口太小了 cmd30列就到头了 行只有20左右 难不成再学下GUI!版主有没有好办法教教小弟
作者: 普大喜奔 时间: 2014-9-27 23:20
回复 21# CrLf
高手就是高手 我的理解有问题 我以为num只要不为空就成立了 忘了0也是 C语言没学好
作者: 普大喜奔 时间: 2014-9-28 00:17
回复 20# 523066680
才发现cmd原来可以设置的
作者: CrLf 时间: 2014-9-28 00:19
回复 22# 普大喜奔
高宽各 1000,这样够大了吧,超出屏幕部分得拉动滚动条查看...- mode con:cols=1000 lines=1000
复制代码
再将置字体为 3*5 大小,就能显示不少东西了
作者: CrLf 时间: 2014-9-28 00:55
回复 11# 523066680
浅拷贝/深拷贝,不过话说回来深拷贝的效率确实不如用俩数组将就了(泥们就是这么干的!魂淡!),反正脚本也不大
作者: 普大喜奔 时间: 2014-9-28 18:31
回复 20# 523066680
版主这个模型叫什么来着
作者: CrLf 时间: 2014-9-30 00:45
本帖最后由 CrLf 于 2014-9-30 00:52 编辑
回复 11# 523066680
想请教个问题,perl 可以用列表直接交换变量值:- $a=1;
- $b=2;
- ($a,$b)=($b,$a);
- print "\$a=$a;\$b=$b;"
复制代码
数组肯定不能直接用 (@a,@b)=(@b,@a),但为什么改成引用就报错?是否是只有在调用函数时可以用 \@ 呢?一对数组、列表、hash 表是不是无法直接交换内容呢?- @a=1..3;
- @b=4..5;
- (\@a,\@b)=(\@b,\@a);
- print "@a";
复制代码
作者: 523066680 时间: 2014-9-30 08:25
本帖最后由 523066680 于 2014-9-30 12:05 编辑
回复 28# CrLf
因为引用是一个地址,\@a = \@b 就是地址=地址,就那啥了……
只能是 变量名 = 引用地址
可以这么做,一开始就用引用对数组操作比如:
($ar, $br) = (\@a, \@b);
用 $ar->[下标] 的方式访问元素,用 @{$ar} 的方式访问整个数组
交换的时候也就和标量交换一样了。
($ar, $br) = ($br, $ar);
经过思考,发现可以这样(其实是在Perl高效编程里面看过这样的用法:片段赋值)- my @a=1..5;
- my @b=6..10;
-
- (@a[0..$#b], @b[0..$#a]) = (@b, @a);
复制代码
这样的话指定了长度,列表元素自然对号入座,嘿嘿。
作者: 523066680 时间: 2014-10-1 10:39
本帖最后由 523066680 于 2014-10-1 18:26 编辑
回复 28# CrLf
居然不理我
还有个"正确"方法,发到Perl区了。
作者: 523066680 时间: 2014-10-1 11:49
本帖最后由 523066680 于 2014-10-1 18:23 编辑
回复 27# 普大喜奔
:new gun: An old name for the second known basic {gun} (found, like
the first, by Bill Gosper), shown below. A number of other ways of
constructing a gun from two {twin bees shuttle}s have since been
found - see {edge shooter} for one of these.
来源:
LIFE LEXICON
Release 25, 2006 February 28
ASCII version
INTRODUCTION
This is a lexicon of terms relating to John Horton Conway's
Game of Life. It is also available in single-page and multipage
HTML versions.
This lexicon was compiled by Stephen A. Silver - see
below for additional credits. I can be contacted at
life(at)argentum.freeserve.co.uk.
The latest versions of this lexicon (both HTML and ASCII)
should be available from the Life Lexicon Home Page at
http://www.argentum.freeserve.co.uk/lex_home.htm
作者: neorobin 时间: 2014-10-1 16:31
回复 31# 523066680
链接地址多了个点号, 点击不开
作者: CrLf 时间: 2014-10-1 18:31
回复 30# 523066680
手机上看的,忘了回
($ar, $br) = ($br, $ar); 是个好办法
(@a[0..$#b], @b[0..$#a]) = (@b, @a); 就只能适用于元素个数相等的特殊情况了,感觉还不如用临时变量
作者: 523066680 时间: 2014-10-1 18:45
本帖最后由 523066680 于 2014-10-1 19:03 编辑
回复 33# CrLf
no, no, no 看我设定的下标
另,
还有个方法,发到perl区了
看来已经回到老家了,还上论坛巡查,真敬业。
作者: CrLf 时间: 2014-10-1 21:44
回复 34# 523066680
你猜错鸟,今年不回去~
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |