我正在用 MASON 进行模拟。我有一个 SparseGrid2D 对象,我在我的主模拟类中填充如下:
protonLayer = new SparseGrid2D(HEIGHT, WIDTH);
MersenneTwisterFast g = new MersenneTwisterFast();
for(int i = 0; i < NUM_PROTONS; i++) {
// Creating the proton
Proton p = new Proton(new Int2D(g.nextInt(WIDTH), g.nextInt(HEIGHT)), this);
// Adding it to schedule
schedule.scheduleRepeating(p);
}
然后在我的可分步课程中,我调用:
Bag neigh = s.protonLayer.getMooreNeighbors(location.getX(), location.getY(), 1, 1, new Bag(), new IntBag(), new IntBag());
然而,由于某种原因,neight.size() 一直返回一个而不是返回所有相邻的单元格。我认为 getMooreNeighbors 排除了空的相邻单元格,所以我添加了:
// Moore locations doesn't return empty grids .-.
for(int i = 0; i < WIDTH; i++) {
for(int j = 0; j < HEIGHT; j++) {
protonLayer.setObjectLocation(new String("a"), i, j);
}
}
到我的主班尝试解决这个问题,但即使每个单元格现在至少有一个对象填充,它也没有奏效!
有什么想法吗?
完整版代码:
质子测试.java
package protontest;
import ec.util.MersenneTwisterFast;
import sim.engine.SimState;
import sim.field.grid.SparseGrid2D;
import sim.util.Int2D;
public class ProtonTest extends SimState{
public SparseGrid2D protonLayer;
public final int HEIGHT = 100;
public final int WIDTH = 100;
public final int NUM_PROTONS = 1;
public ProtonTest(long seed) {
super(seed);
}
public void start() {
protonLayer = new SparseGrid2D(HEIGHT, WIDTH);
MersenneTwisterFast g = new MersenneTwisterFast();
for(int i = 0; i < NUM_PROTONS; i++) {
// Creating the proton
Proton p = new Proton(new Int2D(g.nextInt(WIDTH), g.nextInt(HEIGHT)), this);
// Adding it to schedule
schedule.scheduleRepeating(p);
}
// Moore locations doesn't return empty grids .-.
for(int i = 0; i < WIDTH; i++) {
for(int j = 0; j < HEIGHT; j++) {
protonLayer.setObjectLocation(new String("a"), i, j);
}
}
}
public static void main(String[] args) {
doLoop(ProtonTest.class, args);
System.exit(0);
}
}
质子.java
package protontest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.lowagie.text.pdf.hyphenation.TernaryTree.Iterator;
import ec.util.MersenneTwisterFast;
import sim.engine.SimState;
import sim.engine.Steppable;
import sim.util.Bag;
import sim.util.Int2D;
import sim.util.IntBag;
public class Proton implements Steppable {
public Int2D location;
// Building the proton and adding it to a random location
public Proton(SimState state) {
ProtonTest s = (ProtonTest) state;
MersenneTwisterFast g = new MersenneTwisterFast();
// Random location
int xloc = g.nextInt(s.WIDTH);
int yloc = g.nextInt(s.HEIGHT);
location = new Int2D(xloc, yloc);
// Add object
s.protonLayer.setObjectLocation(this, location);
}
// Building the proton and setting it at a given location
public Proton(Int2D location, SimState state) {
this.location = location;
ProtonTest s = (ProtonTest) state;
s.protonLayer.setObjectLocation(this, location);
}
// Same as constructor above, but takes two ints instead of an Int2D object
public Proton(int xloc, int yloc, SimState state) {
this(new Int2D(xloc, yloc), state);
}
// Stepping about
public void step(SimState state) {
ProtonTest s = (ProtonTest) state;
MersenneTwisterFast g = new MersenneTwisterFast();
// First thing first, does the proton stabilize independently?
int p = 100; // Proton will stabilize (hence be removed from the simulation) with probability of 1/p
int rand = g.nextInt(p);
// If rand = 0 then it met the 1/p probability fo being removed.
if(rand == 0) {
s.protonLayer.remove(this);
return;
}
// Get moore neighbors
Bag neigh = s.protonLayer.getMooreNeighbors(location.getX(), location.getY(), 1, 1, new Bag(), new IntBag(), new IntBag());
// Now we make a map that maps a location to an int. The int will be increased for every proton found at such location in the neighborhood.
Map<Int2D, Integer> m = new HashMap<Int2D, Integer>();
ArrayList<Int2D> a = new ArrayList<Int2D>();
// Looping through neighbors
for(Object o : neigh) {
// The "Proton Neighbor"
Proton pN = (Proton) o;
// Location of current element
Int2D thisLocation = pN.location;
if(!m.containsKey(location)) {
m.put(location, 1);
// There probably is a better way of iterating through maps
a.add(location);
} else {
// Everybody loves casting
int newCounter = ((int) m.get(location)) + 1;
m.put(location, (Integer) newCounter);
}
}
// Wait, we also want to know how many protons in the current cell
int pAtLocation = s.protonLayer.numObjectsAtLocationOfObject(this);
// Get minimum value from map (ie location where there are fewer protons in neighborhood)
int currentMin = pAtLocation;
Int2D location = this.location;
// For each neighbor
for(Int2D loc : a) {
// Get number of protons
int currentM = (int) m.get(loc);
// If there are fewer then the proton will migrate there, unless a better locationis found
if(currentM <= currentMin) {
currentMin = currentM;
location = loc;
}
}
// Move the proton to the new location aaaaaand done
s.protonLayer.setObjectLocation(this, location);
System.out.println(neigh.size());
}
}