Mason 入门例子5 --- 增加学生之间的联系

来源:互联网 发布:linux vi 复制多行 编辑:程序博客网 时间:2024/05/19 17:10

学生现在基本上围绕着操场的中心漫游,看不出很大的区别。

我们现在让学生之间有联系:学生之间可以有讨厌或者喜欢的程度,用权值代表。

在本例中增加一个Field,也就是network.

sim.field.network.Network: 可以定义有向/无向、有权值/无、带/不带标签的联系。

任何的对象都可以作为节点,sim.field.network.Edge连接两个节点。


现在改变Students类,为它增加network:

package com.mason.learn;import sim.engine.*;import sim.util.*;import sim.field.continuous.*;import sim.field.network.*;public class Students extends SimState {private static final long serialVersionUID = 1L;public Continuous2D yard = new Continuous2D(1.0, 100, 100);public int numStudents = 50;double forceToSchoolMultiplier = 0.01;double randomMultiplier = 0.1;public Network buddies = new Network(false);public Students(long seed) {super(seed);}public void start() {super.start();// clear the yardyard.clear();// clear the buddiesbuddies.clear();// add some students to the yardfor (int i = 0; i < numStudents; i++) {Student student = new Student();yard.setObjectLocation(student, new Double2D(yard.getWidth() * 0.5+ random.nextDouble() - 0.5, yard.getHeight() * 0.5+ random.nextDouble() - 0.5));buddies.addNode(student);schedule.scheduleRepeating(student);}// define like/dislike relationships// Bag is faster than ArrayList, and the result of getAllNodes() is// read-only.Bag students = buddies.getAllNodes();for (int i = 0; i < students.size(); i++) {Object student = students.get(i);// who does he like?Object studentB = null;dostudentB = students.get(random.nextInt(students.numObjs));while (student == studentB);double buddiness = random.nextDouble();buddies.addEdge(student, studentB, new Double(buddiness));// who does he dislike?dostudentB = students.get(random.nextInt(students.numObjs));while (student == studentB);buddiness = random.nextDouble();buddies.addEdge(student, studentB, new Double(-buddiness));}}public static void main(String[] args) {doLoop(Students.class, args);System.exit(0);}}


现在仿真中的network已经有了权值,现在我们改变Student让学生依据喜恶程度来进行移动。

package com.mason.learn;import sim.engine.*;import sim.field.continuous.*;import sim.util.*;import sim.field.network.*;public class Student implements Steppable {private static final long serialVersionUID = 1L;public static final double MAX_FORCE = 3.0;public void step(SimState state) {Students students = (Students) state;Continuous2D yard = students.yard;Double2D me = students.yard.getObjectLocation(this);MutableDouble2D sumForces = new MutableDouble2D();// Go through my buddies and determine how much I want to be near themMutableDouble2D forceVector = new MutableDouble2D();Bag out = students.buddies.getEdges(this, null);int len = out.size();for (int buddy = 0; buddy < len; buddy++) {Edge e = (Edge) (out.get(buddy));double buddiness = ((Double) (e.info)).doubleValue();// I could be in the to() end or the from() end. getOtherNode is a// cute function// which grabs the guy at the opposite end from me.Double2D him = students.yard.getObjectLocation(e.getOtherNode(this));if (buddiness >= 0) // the further I am from him the more I want to// go to him{forceVector.setTo((him.x - me.x) * buddiness, (him.y - me.y)* buddiness);if (forceVector.length() > MAX_FORCE) // I’m far enough awayforceVector.resize(MAX_FORCE);} else // the nearer I am to him the more I want to get away from// him, up to a limit{forceVector.setTo((him.x - me.x) * buddiness, (him.y - me.y)* buddiness);if (forceVector.length() > MAX_FORCE) // I’m far enough awayforceVector.resize(0.0);else if (forceVector.length() > 0)forceVector.resize(MAX_FORCE - forceVector.length()); // invert// the// distance}sumForces.addIn(forceVector);}// add in a vector to the "teacher" -- the center of the yard, so we// don’t go too far awaysumForces.addIn(new Double2D((yard.width * 0.5 - me.x)* students.forceToSchoolMultiplier, (yard.height * 0.5 - me.y)* students.forceToSchoolMultiplier));// add a bit of randomnesssumForces.addIn(new Double2D(students.randomMultiplier* (students.random.nextDouble() * 1.0 - 0.5),students.randomMultiplier* (students.random.nextDouble() * 1.0 - 0.5)));sumForces.addIn(me);students.yard.setObjectLocation(this, new Double2D(sumForces));}}

运行结果:




如果想要让联系显示出来,可以增加network portrayal。

NetworkPortrayal2D buddiesPortrayal = new NetworkPortrayal2D();

在setupPortrayals里面增加:

buddiesPortrayal.setField( new SpatialNetwork2D( students.yard, students.buddies ) );
buddiesPortrayal.setPortrayalForAll(new SimpleEdgePortrayal2D());


在init()里面增加:
display.attach( buddiesPortrayal, "Buddies" );


运行结果如图:




0 0