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

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

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

在本例中增加一个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 yard
		yard.clear();

		// clear the buddies
		buddies.clear();

		// add some students to the yard
		for (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;
			do
				studentB = students.get(random.nextInt(students.numObjs));
			while (student == studentB);
			double buddiness = random.nextDouble();
			buddies.addEdge(student, studentB, new Double(buddiness));

			// who does he dislike?
			do
				studentB = 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 them
		MutableDouble2D 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 away
					forceVector.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 away
					forceVector.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 away
		sumForces.addIn(new Double2D((yard.width * 0.5 - me.x)
				* students.forceToSchoolMultiplier, (yard.height * 0.5 - me.y)
				* students.forceToSchoolMultiplier));
		// add a bit of randomness
		sumForces.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" );


运行结果如图:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anyanyamy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值