Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何计算单元格';带包围的元胞自动机中的s邻域_Java_Cellular Automata - Fatal编程技术网

Java 如何计算单元格';带包围的元胞自动机中的s邻域

Java 如何计算单元格';带包围的元胞自动机中的s邻域,java,cellular-automata,Java,Cellular Automata,所以我正在制作一个模拟生命的细胞自动机的程序,但是我在计算细胞活邻居的方法上遇到了一些问题。问题是我希望能够改变网格的缠绕方式——也就是说,它是从左到右缠绕(即圆柱形),从上到下缠绕,还是从左到右缠绕(即环形),或者完全不缠绕(即扁平)--我不知道该如何用我的方法来解释这一点。以下是我目前掌握的情况: public int getLiveNeighbors(int row, int col) { int count = 0; // "topology" is an int th

所以我正在制作一个模拟生命的细胞自动机的程序,但是我在计算细胞活邻居的方法上遇到了一些问题。问题是我希望能够改变网格的缠绕方式——也就是说,它是从左到右缠绕(即圆柱形),从上到下缠绕,还是从左到右缠绕(即环形),或者完全不缠绕(即扁平)--我不知道该如何用我的方法来解释这一点。以下是我目前掌握的情况:

public int getLiveNeighbors(int row, int col)
{
    int count = 0;

    // "topology" is an int that represents wraparound:
    // 0 = flat; 1 = cylindrical; 2 = toroidal
    int top = topology != 2 ? row - 1 : (row + ROWS - 1) % ROWS;
    int bottom = topology != 2 ? row + 1 : (row + 1) % ROWS;
    int left = topology != 0 ? (col + COLS - 1) % COLS : col - 1;
    int right = topology != 0 ? (col + 1) % COLS : col + 1;

    for (int r = top; r < bottom + 1; r++)
        for (int c = left; c < right + 1; c++)
            if (!(r == row && c == col) && getCell(r, c).equals(LIVE))
                count++;
}
public int getlivenextries(int行,int列)
{
整数计数=0;
//“topology”是一个整数,表示环绕:
//0=平面;1=圆柱形;2=环形
int top=拓扑!=2?行-1:(行+行-1)%ROWS;
int bottom=拓扑!=2?行+1:(行+1)%ROWS;
int left=拓扑!=0?(列+列-1)%COLS:col-1;
int right=拓扑!=0?(列+1)%COLS:col+1;
对于(int r=top;r
我认为,关键是
for
-循环中的
if
-语句——必须有某种方法来检查
r
c
是否在网格的边界内,同时要记住,“边界”的定义将根据网格是否缠绕/如何缠绕而有所不同。在过去,我通过使用八个不同的
if
-语句的三个不同集合(每个环绕设置一个)来解决这个问题,分别检查组成原始单元格邻域的八个单元格中的每一个;正如你所能想象的,它不是很漂亮,但至少它起作用了


我不太擅长解释我自己的代码,所以我希望这不会太让人困惑——我自己也觉得有点不对劲(哈)。如果有任何问题,请随时提问

您可能已经有了一个类似于
Board
的类,其方法类似于
getCell(x,y)
(您的代码中至少存在一个此类方法)

从某种意义上说,我只是想让这个方法变得宽松,它可以接受负的
x
y
x
y
大于或等于
COLS
。因此,您可以只迭代
col-1
col+1
row-1
row+1
(减去
col
row
),而不关心这些坐标是否“在板上”。
板的任务是正确地进行坐标查找

使您的代码更难的另一个原因是您在一个地方处理不同的拓扑。这很难理解


通过实现
Board
的不同子类,例如
CylindricalBoard
ToroidalBoard
FlatBoard
,您可以使它变得更简单。每个子类实现的
getCell
都不同,但是在子类的上下文中,它是可以清楚理解的。

您可能已经有了一个类似
Board
的类,其方法类似于
getCell(x,y)
(您的代码中至少存在这种方法)

从某种意义上说,我只是想让这个方法变得宽松,它可以接受负的
x
y
x
y
大于或等于
COLS
。因此,您可以只迭代
col-1
col+1
row-1
row+1
(减去
col
row
),而不关心这些坐标是否“在板上”。
板的任务是正确地进行坐标查找

使您的代码更难的另一个原因是您在一个地方处理不同的拓扑。这很难理解

通过实现
Board
的不同子类,例如
CylindricalBoard
ToroidalBoard
FlatBoard
,您可以使它变得更简单。每个子类实现的
getCell
都不同,但是在子类的上下文中,它是可以清楚理解的。

您正在寻找:

当类只在行为上有所不同时,存在一些常见情况。对于这种情况,最好将算法隔离在单独的类中,以便能够在运行时选择不同的算法

在这种情况下,您可能需要这样的内容(为了清晰起见,缩写为):

类点{
int x;
int-y;
}
接口包装策略{
点向上移动(点p);
点向下移动(点p);
点向左移动(点p);
向右移动点(p点);
}
class Cylinder包装实现包装策略{
内部高度;
整数周长;
点向上移动(点p){
如果(p.y=高度-1)
返回null;//不能向下移动
返回新点(p.x,p.y+1);
}
点向左移动(点p){
如果(p.x=周长-1)
返回新点(0,p.y);
返回新点(p.x+1,p.y);
}
}
您正在寻找:

当类只在行为上有所不同时,存在一些常见情况。对于这种情况,最好将算法隔离在单独的类中,以便能够在运行时选择不同的算法

在这种情况下,您可能需要这样的内容(为了清晰起见,缩写为):

类点{
int x;
int-y;
}
接口包装策略{
点向上移动(点p);
点向下移动(点p);
点向左移动(点p);
向右移动点(p点);
}
class Cylinder包装实现包装策略{
内部高度;
整数周长;
点向上移动(点p){
如果(p.y=高度-1)
返回null;//canno
import java.awt.Point;

public class Neighbours {

    public static void main(String[] args) {
        Neighbours inst=new Neighbours();
        int r=3;//<ROWS
        int c=3;//<COLS
        for(int i :new int[]{0,1,2}){
            inst.type=i;
            System.out.format("There are %d neighbours of point (%d,%d), topography type %d\n", inst.countLiveNeighbours(r, c), c, r,i);
        }
    }

    int ROWS=4;
    int COLS=4;
    int type=0;//0=flat, 1=cylinder, 2=toroid

    /**
     * Is x,y a neighbour of r,c?
     * @return coordinates of neighbour or null
     */
    Point neighbour(int x, int y, int r, int c){
        if((x==c)&&(y==r))
            return null;
        switch (type){
/*this is wrong for the reasons explained below
        case 0: return ((x<COLS)&&(y<ROWS)) ? new Point (x,y) : null;
        case 1: return y<ROWS ? new Point(x%COLS,y) : null;
        case 2: return new Point(x%COLS,y%ROWS);
*/
 //replacement statements produce the correct behaviour
    case 0: return ((x<COLS)&&(x>-1)&&(y<ROWS)&&(y>-1)) ? new Point (x,y) : null;
    case 1: return ((y<ROWS)&&(y>-1)) ? new Point(Math.floorMod(x,COLS),y) : null;
    case 2: return new Point(Math.floorMod(x,COLS),Math.floorMod(y,ROWS));
        }
        return null;
    }

    int countLiveNeighbours(int r, int c){
        int result=0;
        for(int x=c-1; x<c+2; x++)
            for(int y=r-1; y<r+2; y++){
                Point p=neighbour(x,y,r,c);
                if(live(p)){
                    System.out.format("\tpoint (%d,%d)\n",(int)p.getX(),(int)p.getY());
                    result++;
                }
            }
        return result;
    }

    boolean live(Point p){
        boolean result=true;
        if(p==null)
            return false;
        //perform tests for liveness here and set result
        return result;
    }
}