⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sand2d.java

📁 模拟砂堆的元胞自动机源代码。对于认识和学习元胞自动机(CA)很有帮助
💻 JAVA
字号:
// Sand2D.javaimport comphys.graphics.*;import comphys.Easy;import java.awt.*;import java.awt.event.*;public class Sand2D extends Animation {    // 2-dimensional sandpile automaton    int L = 21;                 // number of sites = L * L    int[][] m;                  // slope at each site    int[][] mOld;               // old value of slope at each site    boolean[][] unstable;       // if m > 3    boolean pileUnstable;       // at least one unstable site    int t;                      // time step    int topplings;              // number of unstable sites    int[] N;                    // distribution of avalanche sizes    int minSize;                // minimum size to determine exponent    int maxSize;                // maximum size to determine exponent    boolean random;             // if false add sand at central site    void setBoundaryValues () {        // open boundaries        for (int i = 1; i <= L; i++)            m[i][0] = m[0][i] = m[i][L + 1] = m[L + 1][i] = 0;    }        void initial () {        if (m == null || m.length < L + 2) {            m = new int[L + 2][L + 2];            mOld = new int[L + 2][L + 2];            unstable = new boolean[L + 2][L + 2];            N = new int[L];        }        // interior values        for (int i = 1; i <= L; i++) {            for (int j = 1; j <= L; j++)                m[i][j] = 0;        }        setBoundaryValues();        for (int i = 0; i < L + 2; i++) {            for (int j = 0; j < L + 2; j++)                unstable[i][j] = false;        }        t = 0;        topplings = 0;        for (int i = 0; i < N.length; i++)            N[i] = 0;        minSize = 1;        maxSize = L;    }    void addGrain () {        int i = (L + 1) / 2;        int j = (L + 1) / 2;        if (random) {            i = 1 + (int) (Math.random() * L);            j = 1 + (int) (Math.random() * L);        }        m[i][j] += 1;    }    void markUnstableSites () {        pileUnstable = false;        for (int i = 1; i <= L; i++) {            for (int j = 1; j <= L; j++) {                if (m[i][j] > 3) {                    unstable[i][j] = true;                    pileUnstable = true;                    ++topplings;                } else {                    unstable[i][j] = false;                }            }        }    }    void topple () {        for (int i = 1; i <= L; i++) {            for (int j = 1; j <= L; j++) {                if (unstable[i][j]) {                    m[i][j] -= 4;                    m[i][j - 1] += 1;                    m[i][j + 1] += 1;                    m[i - 1][j] += 1;                    m[i + 1][j] += 1;                }            }        }    }    void updatePile () {        if (pileUnstable) {            markUnstableSites();            topple();            setBoundaryValues();        } else {            if (N.length < topplings + 1) {                int[] temp = new int[topplings + 10];                for (int i = 0; i < N.length; i++)                    temp[i] = N[i];                N = temp;            }            ++N[topplings];            topplings = 0;            addGrain();            ++t;            markUnstableSites();        }    }    class Pile extends Plot {        Pile () {            setSize(300, 300);        }        String[] color = {"white", "yellow", "orange", "red",                          "green", "cyan", "blue", "magenta"};        public void paint () {            clear();            setWindow(0, L + 2, 0, L + 2);            for (int i = 0; i < L + 2; i++) {                for (int j = 0; j < L + 2; j++) {                    setColor(color[m[i][j]]);                    boxArea(i, i + 1, j, j + 1);                }            }        }    }    class PowerLaw extends Plot {        PowerLaw () {            setSize(300, 300);        }        // power law and exponent        int maxIndex;        double[] logData;        double exponent;        void analyze (int[] data) {            if (logData == null || logData.length < data.length)                logData = new double[data.length];            maxIndex = 0;            int numValues = 0;            double maxValue = 0;            double xAv = 0, yAv = 0, xxAv = 0, xyAv = 0;            for (int i = 0; i < data.length; i++) {                double value = 0;                if (data[i] > 0) {                    maxIndex = i;                    value = Math.log(data[i]);                    if (value > maxValue)                        maxValue = value;                    xAv += i;                    yAv += value;                    xxAv += i * (double) i;                    xyAv += i * value;                    ++numValues;                } else {                    logData[i] = 0;                }                logData[i] = value;            }            exponent = 0;            if (numValues > 0) {                for (int i = 0; i <= maxIndex; i++) {                    logData[i] /= maxValue;                }                xAv /= numValues;                yAv /= numValues;                xxAv /= numValues;                xyAv /= numValues;                exponent = (xyAv - xAv * yAv) / (xxAv - xAv * xAv);            }        }        public void paint () {            clear();            setWindow(-0.1, 1.1, -0.15, 1.15);            setColor("cyan");            analyze(N);            double d = 0.5 / (maxIndex + 1);            if (maxIndex > 0) {                for (int i = 0; i <= maxIndex; i++) {                    double x1 = i / (maxIndex + 1.0);                    double x2 = (i + 1) / (maxIndex + 1.0);                    double y1 = 0;                    double y2 = logData[i];                    plotLine(x2, y1, x2, y2);                    boxArea(x1, x2, y1, y2);                }                setColor("blue");                plotStringLeft("power = " + Easy.format(exponent, 3), 1, 1.0);                plotStringCenter("0", d, -0.1);                plotStringCenter("" + maxIndex, 1 - d, -0.1);            }            setColor("black");            plotString("log(N)", 0, 1.05);            plotLine(0, 0, 0, 1);            plotLine(0, 0, 1, 0);            plotStringCenter("Topplings", 0.5, -0.1);        }    }    class Output extends Plot {        Output () {            setSize(610, 30);        }        public void paint () {            clear();            setWindow(0, 100, 0, 3);            setColor("blue");            boxArea(0, 100, 0, 3);            setColor("white");            plotString("time step = " + t, 5, 1);            plotString("topplings = " + topplings, 25, 1);        }    }    Pile pile;    PowerLaw powerLaw;    Output output;    Reader LReader, skipReader, minSizeReader, maxSizeReader;    Checkbox randomBox;    int skip;    public void init () {        initial();        add(pile = new Pile());        add(powerLaw = new PowerLaw());        add(output = new Output());        add(LReader = new Reader("L = ", L));        add(skipReader = new Reader("Skip steps", skip));        add(randomBox = new Checkbox("Add random", random));        randomBox.addItemListener(new ItemListener() {            public void itemStateChanged(ItemEvent ie) {                random = randomBox.getState();            }        });        add(minSizeReader = new Reader("Min size = ", minSize));        add(maxSizeReader = new Reader("Max size = ", maxSize));        addControlPanel();    }    public void step () {        for (int s = 0; s <= skip; s++)            updatePile();        pile.repaint();        powerLaw.repaint();        output.repaint();    }    public void reset () {        L = LReader.readInt();        skip = skipReader.readInt();        minSize = minSizeReader.readInt();        maxSize = maxSizeReader.readInt();        initial();        pile.repaint();        powerLaw.repaint();        output.repaint();   }    public static void main (String[] args) {        Sand2D sand2D = new Sand2D();        sand2D.frame("2-D Sandpile Automaton", 630, 600);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -