6

我必须用Java制作一个模拟器,它将模拟在高速公路上行驶的汽车。高速公路上应该有3条车道,每条车道都有匀速行驶的汽车。在这条高速公路上,有一个特工,他必须开车通过,不能撞到任何其他汽车。详细说明见本文第 2.5 节和图 5。

这张图片来自上述论文,显示了高速公路的外观:

在此处输入图像描述

我的目标是只编写一个模拟器(和 GUI),而不是代理的逻辑。现在,我想设计这个模拟器的架构,这就是我需要帮助的地方。

我的想法是,代理的 API 的外观是:

public abstract class BaseAgent {
    public abstract void run()
    public abstract void onCrash();
}

高速公路上的代理(汽车)应该是这个类的后代。在每一步中,模拟器调用函数run(),代理逻辑在哪里。在这个函数中,代理可以调用​​如下函数:

goLeft();
goRight();
getNearestCarInLane(int lane_no);
getMySpeed();

因此,在每一步中,代理都可以决定他是否留在当前车道,或者他是左转还是右转。仅此而已,代理可以做什么。

所以这是代理API,但我不知道如何设计模拟器的其余部分。我第一次尝试模拟架构是:

class Agent — descendant of BaseAgent, can ride on highway.
class Highway — stores position of all cars on highway.
class Simulator — creates instance of agent and highway; in every step, call agent’s `run()` and monitors any car crash.

这不是一个好的架构。方法应该在哪个类中goLeft()goRight()以及getNearestCarInLane()?因为这些方法必须在BaseAgent课堂内,但必须知道高速公路上每辆车的位置。所以最后,我有这样的事情:

Simulator s = new Simulator();
Highway h = new Highway();
Agent a = new Agent();

s.setAgent(a);
s.setHighway(h);
a.setHighway(h);
h.setAgent(a);

这是可怕和丑陋的。

所以我需要一些聪明人的帮助。有人可以给我一个关于模拟器/架构的书籍、文章的链接吗?或者解释我做错了什么?

我不是程序员,这个项目是我所在学院的一门名为Software Engineering的选修课程的一部分。

4

2 回答 2

6

我的建议是设计智能代理正式概念的代理界面:从模拟的角度来看,它是一个黑匣子,从其环境(例如传感器数据)接收感知,然后决定某个动作(例如,向左或向右驾驶汽车)。

基于此定义并假设一个简单的离散逐步模拟,您的代理类可能如下所示:

public abstract class BaseAgent {
    public AgentAction act(HighwayPerception hwyPerception);
}

whereAgentAction是代表代理可以在单个步骤中决定执行的操作的类型(在最简单的情况下,这将是一个带有 values STEER_LEFTSTEER_RIGHT等的枚举 --- 对于更复杂的问题,您可以定义一个完整的类具有AgentAction作为超类/接口的层次结构)。模拟器的工作是解释AgentAction代理返回的对象并相应地更改其环境(即Highway对象)的状态。

HighwayPerception另一方面,参数代表代理在当前时间步能够感知的所有信息:例如,汽车有多快( getMySpeed())或到下一辆车的距离(getNearestCarInLane(int laneNumber))。这避免了将代理直接耦合到其环境(即Highway)——这很重要,因为它分离了关注点:代理只感知他们的环境并决定行动,而不是直接与它交互。鉴于其环境的当前状态,再次为代理创建感知是模拟器的工作。

最后,这种设计也使得控制代理更容易。必须设计该类HighwayPercept,使其只能用于读取代理应该能够感知的数据,而不是直接影响周围环境。相反,您的原始设计中的代理可以访问这样的Highway对象,因此可能会尝试欺骗,例如,欺骗see前方几英里的汽车并相应地规划路线,或者只是改变高速公路上其他汽车的位置。即使您不太关心安全性,这也不应该是可能的,因为此类事情也可能无意中发生并且可能难以调试。

根据您的要求,您的架构当然可能需要更加复杂更多信息应该很容易从有关多智能体模拟系统的文献中获得(这是对您的问题的概括,即可以模拟多个智能体在您的高速公路上行驶)该领域正在进行大量研究,并且您可能希望查看多种用于多智能体模拟的工具(例如Repast)。

于 2011-10-11T20:32:40.633 回答
0

就我个人而言,我会将高速公路封装在模拟器中。如果每个模拟器有超过 1 个高速公路,那么我会假设代理将位于任何高速公路对象上,因此代理可以由模拟器拥有并与高速公路相关联。但是 Simulator 应该是一个 Facade 模式,所以您需要做的就是创建 Simulator 并可能有选择地向它传递一个配置,这样您就不必处理它们了。每个代理都应该有一个 run() 方法,并且模拟器中应该有一个线程在它包含的每个代理上调用 run() ,或者您可以在模拟中手动步骤为每个代理调用 run() 一次(如一步一步的模拟器)。

于 2011-10-10T13:17:05.247 回答