logo资料库

swarm典型例子热虫.doc

第1页 / 共35页
第2页 / 共35页
第3页 / 共35页
第4页 / 共35页
第5页 / 共35页
第6页 / 共35页
第7页 / 共35页
第8页 / 共35页
资料共35页,剩余部分请下载后查看
import swarm.Globals; import swarm.space.Grid2d; import swarm.space.Grid2dImpl; import swarm.gui.Raster; /** * Heatbugs are agents in a 2d world with simple behaviour: if too and * cold, move to warmer spot if too warm, move to cooler spot. * some occasional exceptions if the spot is occupied, try to move to * an unoccupied spot. * random spot */ Heatbugs 是一个简单的二维世界的代理行为:如果太 *冷,移动到温暖的地方,如果太热烈,移动到凉爽的地方。和 *一些地方被占用,如果偶尔的例外,尝试移动到 *一无人居住的地方。 randomMoveProbability 机会移动到 *随机点 public class Heatbug { randomMoveProbability chance of moving to a /** my current unhappiness */ public double unhappiness; /** my spatial coordinates */ public int x, y; /** my ideal temperature */ public int idealTemperature; /** how much heat I put out */ public int outputHeat; /** chance of moving randomly */ public double randomMoveProbability; /** the world I live in */ Grid2d world; /** how big that world is */ public int worldXSize, worldYSize; /** the heat for the world */ HeatSpace heat; /** my colour (display) */ public byte bugColor; /* Scratch cell for extracting return values */ HeatCell scratchHeatCell; /** * these methods are used to initialize the object's state. First, * methods that have to be sent to create an object. */ /** * Constructor for Heatbug
*/ public Heatbug (Grid2d w, HeatSpace h) { // Strictly speaking, this check isn't necessary. But we intend these // parameters to be immutable once set, so to be extrasafe we check: // it could catch an error later. 严格来说,这个检查是没有必要的。但是,我们打算这些 / /参数是不可改变的一次设定的,所以我们要 extrasafe 检查: / /它可以捕获一个错误后 if (world != null || heat != null) System.err.println ("You can only set the world/heat " + "of a heatbug at creation time"); world = w; heat = h; // make sure the user set up world and heat. if (world == null || heat == null) System.err.println ("Heatbug was created without a world or heat"); // Cache the worldSize for speed of later access. Note how we // do this in createEnd - it could also have been done when // setWorld:Heat: was called, but this is a good place to do // it, too. If an object needed to allocate extra memory, this // is the right place to do it. /缓存 worldSize 为后来的访问速度。注意我们 / /做 createEnd 这一点 - 它也已经完成时 / / setWorld:热:叫,但是这是一个好地方做 / /这一点。如果一个对象需要分配额外的内存,这 / /是正确的地方做。 worldXSize = world.getSizeX (); worldYSize = world.getSizeY (); // Someday, it'd be good if the space library to be powerful // enough that the heatbugs never need to be aware how big // their world is. 有一天,这将会是好的,如果有强大的空间库
/ /没有足够的 heatbugs 需要知道有多大 / /他们的世界。 scratchHeatCell = new HeatCell (0, 0); } /** Methods for reading/writing a Heatbug's state during runtime. The probe mechanism is the lowlevel way of getting at an object's state - you're also allowed (but not required) to write methods to access the state as you find it is necessary or convenient. Note the naming convention: for a variable named "fooBar" methods are -(sometype) getFooBar; -setFooBar; this naming convention will be important for a later version of probe. instead of direct access). (probe will preferentially use these methods */ 方法读/写一个 Heatbug 在运行时的状态。 探头机制是在一个越来越方式变异指数 对象的状态 - 你也可以(但不要求),以 写方法来访问的状态,你觉得有必要 或方便。注意命名约定:一个变量 命名为“foobar 的”方法 - (sometype)getFooBar; - setFooBar; 这个命名公约将是重要的一个更高版本 探针。 (探针将优先使用这些方法 而不是直接访问)。 public double getUnhappiness () { return unhappiness; } /** Simple set methods for Heatbug state. Some of these are probably not going to normally change in a heatbugs lifetime, but there's no reason they couldn't change. */ 简单设置 Heatbug 状态的方法。其中有些是 大概不会改变通常在 1 heatbugs 一生, 但我们没有理由,他们也改变不了 public Object setIdealTemperature (int i) { idealTemperature = i;
return this; } public Object setOutputHeat (int o) { outputHeat = o; return this; } public Object setRandomMoveProbability (double p) { randomMoveProbability = p; return this; } /** This method is a bit dangerous: we blindly put ourselves on top of the grid no matter what's underneath us: because Grid2d only allows one object per square, we could be destroying data. This is poor design, but fortunately doesn't kill us in this particular app. If some other object really needed to find all objects based on looking in the grid, it would cause problems. (But note, in heatbug creation, how we tell Grid2d to turn off its warnings about overwrites) */ 这种方法是有点危险的:我们盲目地把自己顶 网格的下面我们无论在什么年代:只因为 Grid2d 每平方米允许一个对象,我们可能会破坏数据。这 不好的设计,但幸运的是并不能杀死我们在这 特别是应用程序。如果确实需要一些其他对象找到所有 在基于网格寻找对象,它会导致 问题。 (但要注意,在 heatbug 创造,我们如何来告诉 Grid2d 关闭它的预警信息覆盖) public Object setX$Y (int inX, int inY) { x = inX; y = inY; world.putObject$atX$Y (this, x, y); return this; // yikes! } /** */ All of the previous code is basic Swarm object programming. The real simulation code follows. Heatbug behaviour is actually implemented here. The notion of a "step" method is a nice simplification for basic simulations.
以前的代码全部是基本的群对象编程。该 真正的模拟程序如下。 Heatbug 行为实际上是 在这里执行。一个“一步”的概念是一个很好的方法 简化基本模拟。 public void heatbugStep () { int heatHere; int newX, newY; int tries; // find out the heat where we are sitting. heatHere = heat.getValueAtX$Y (x, y); // update my current unhappiness value: abs(ideal - here); if (heatHere < idealTemperature) unhappiness = (double) (idealTemperature - heatHere) / HeatSpace.maxHeat; else unhappiness = (double) (heatHere - idealTemperature) / HeatSpace.maxHeat; // now ask the heatspace to tell us where the warmest or // coldest spot is The method call returns values back into // newX and newY. 现在要求 heatspace 告诉我们最热烈的地方或 / /最冷的地方是方法调用返回值回 / / newX 和 newY。 scratchHeatCell.x = x; scratchHeatCell.y = y; heat.findExtremeType$X$Y (((heatHere < idealTemperature) ? HeatSpace.hot : HeatSpace.cold), scratchHeatCell); newX = scratchHeatCell.x; newY = scratchHeatCell.y;
// After choice of ideal spot is made, there's a chance of // random move. // worldSize). The current space library does not enforce // boundary conditions.) (Note the normalization of coordinates to [0, 选择后作出的理想之地,有一个机会 / /随机移动。 (请注意正常化坐标为[0, / / worldSize)。目前图书馆没有执行空间 / /边界条件。) if ((Globals.env.uniformDblRand.getDoubleWithMin$withMax (0.0, 1.0)) < randomMoveProbability) // pick a random spot newX = x + Globals.env.uniformIntRand.getIntegerWithMin$withMax (-1, 1); newY = y + Globals.env.uniformIntRand.getIntegerWithMin$withMax (-1, 1); // normalize coords newX = (newX + worldXSize) % worldXSize; newY = (newY + worldYSize) % worldYSize; { } // Part of the heatbug simulation is that two bugs cannot be // in the same spot. The code to enforce that is done here: if // the site we want is occupied by another heatbug, move // randomly. Note that this code does not parallelize // properly, it requires that each bug be set a "step" method // in sequence. This is a design flaw in heatbugs: proper // conflict resolution is difficult. Also note we only look // for 10 random spots - if we don't find an unoccupied spot // by then, assume it's too crowded and just don't move. / /在 heatbug 模拟部分原因是,两个错误不能 / /在同一个地点。执行的代码是在这里完成:如果 / /的网站,我们要的是另一 heatbug,移动占据 / /随机。请注意,此代码不会并行 / /正确,它要求每一个错误设置“步骤”的方法 / /顺序。这是 heatbugs 设计缺陷:正确
/ /解决冲突是困难的。另外请注意,我们只能看 / /对 10 个随机点 - 如果我们不找到一个无人居住的地方 / /届时,假设它太拥挤,只是不移动。 if (unhappiness == 0) { } // only update heat - don't move at all if no unhappiness heat.addHeat$X$Y (outputHeat, x, y); else { tries = 0; // only search if the current cell is neither the optimum // or randomly chosen location - else don't bother if ( (newX != x || newY != y) ) { while ( (world.getObjectAtX$Y (newX, newY) != null) && (tries < 10) ) { int location, xm1, xp1, ym1, yp1; // choose randomly from the nine possible // random locations to move to location = Globals.env.uniformIntRand.getIntegerWithMin$withMax (1,8); xm1 = (x + worldXSize - 1) % worldXSize; xp1 = (x + 1) % worldXSize; ym1 = (y + worldYSize - 1) % worldYSize; yp1 = (y + 1) % worldYSize; switch (location) { case 1: newX = xm1; newY = ym1; break; // NW case 2: newX = x ; newY = ym1; break; // N case 3: newX = xp1 ; newY = ym1; break; // NE case 4: newX = xm1 ; newY = y; // W
break; case 5: newX = xp1 ; newY = y; break; // E case 6: newX = xm1 ; newY = yp1; break; // SW case 7: newX = x ; newY = yp1; break; // S case 8: newX = xp1 ; newY = yp1; // SE default: break; } tries++; } if (tries == 10) // don't try too hard. // no nearby clear spot, so just don't move. newX = x; newY = y; { } } // Phew - we've finally found a spot to move ourselves, in // (newX, newY). Update heat where we were sitting. heat.addHeat$X$Y (outputHeat, x, y); // Now move ourselves in the grid and update our coordinates. world.putObject$atX$Y (null, x, y); x = newX; y = newY; world.putObject$atX$Y (this, newX, newY); } // all done moving! Return this. } /** Extra bits of display code: setting our colour, drawing on a window. This code works, but it'd be better if there were a
分享到:
收藏