/* Copyright 2006 by Sean Luke and George Mason University Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package sim.app.schelling; import sim.engine.*; import sim.field.grid.*; import sim.util.*; public /*strictfp*/ class Schelling extends SimState { private static final long serialVersionUID = 1; public int gridHeight; public int gridWidth; public int neighborhood = 1; public int threshold = 3; public double redProbability = 0.3; public double blueProbability = 0.3; public double emptyProbability = 0.3; public double unavailableProbability = 0.1; // we presume that no one relies on these DURING a simulation public int getGridHeight() { return gridHeight; } public void setGridHeight(int val) { if (val > 0) gridHeight = val; } public int getGridWidth() { return gridWidth; } public void setGridWidth(int val) { if (val > 0) gridWidth = val; } public int getNeighborhood() { return neighborhood; } public void setNeighborhood(int val) { if (val > 0) neighborhood = val; } public int getThreshold() { return threshold; } public void setThreshold(int val) { if (val >= 0) threshold = val; } // some cutsie-pie probability sliders. More work than necessary, but it was fun. public Object domRedProbability() { return new Interval(0.0,1.0); } public double getRedProbability() { return redProbability; } public void setRedProbability(double val) { if (val >= 0 && val <= 1.0) { redProbability = val; } } public Object domBlueProbability() { return new Interval(0.0,1.0); } public double getBlueProbability() { return blueProbability; } public void setBlueProbability(double val) { if (val >= 0 && val <= 1.0) { blueProbability = val; } } public Object domEmptyProbability() { return new Interval(0.0,1.0); } public double getEmptyProbability() { return emptyProbability; } public void setEmptyProbability(double val) { if (val >= 0 && val <= 1.0) { emptyProbability = val; } } public Object domUnavailableProbability() { return new Interval(0.0,1.0); } public double getUnavailableProbability() { return unavailableProbability; } public void setUnavailableProbability(double val) { if (val >= 0 && val <= 1.0) { unavailableProbability = val; double total = redProbability + blueProbability + emptyProbability; if (total==0.0) total = 1.0; redProbability *= (1.0 - unavailableProbability)/total; blueProbability *= (1.0 - unavailableProbability)/total; emptyProbability *= (1.0 - unavailableProbability)/total; } } public IntGrid2D neighbors; public Bag emptySpaces = new Bag(); public static final int EMPTY = 0; public static final int UNAVAILABLE = 1; public static final int RED = 2; public static final int BLUE = 3; /** Creates a Schelling simulation with the given random number seed. */ public Schelling(long seed) { this(seed, 100, 100); } public Schelling(long seed, int width, int height) { super(seed); gridWidth = width; gridHeight = height; createGrids(); } protected void createGrids() { emptySpaces.clear(); neighbors = new IntGrid2D(gridWidth, gridHeight,0); int[][] g = neighbors.field; for(int x=0;x<gridWidth;x++) for(int y=0;y<gridHeight;y++) { double d = random.nextDouble(); if (d < redProbability) g[x][y] = RED; else if (d < redProbability + blueProbability) g[x][y] = BLUE; else if (d < redProbability + blueProbability + emptyProbability) { g[x][y] = EMPTY; emptySpaces.add(new Int2D(x,y)); } else g[x][y] = UNAVAILABLE; } } /** Resets and starts a simulation */ public void start() { super.start(); // clear out the schedule // make new grids createGrids(); for(int x=0;x<gridWidth;x++) for(int y=0;y<gridHeight;y++) { schedule.scheduleRepeating(new Agent(x,y)); } } public static void main(String[] args) { doLoop(Schelling.class, args); System.exit(0); } }