我必须用Java制作模拟器,它将模拟在高速公路上骑车。高速公路上应该有3条车道,每条车道都有恒定速度的车。在这条高速公路上,有一个代理商,必须穿过而不会撞到任何其他车辆。详细说明可在this paper第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 的可选课程的一部分。
答案 0 :(得分:6)
我的建议是设计代理的界面与intelligent agent的正式概念:从模拟的角度来看,它是一个接收感知<的黑盒子/ em>从其环境(例如,传感器数据)然后决定某个动作(例如,向左或向右转向汽车)。
根据此定义和假设一个简单的离散逐步模拟,您的代理类可能如下所示:
public abstract class BaseAgent {
public AgentAction act(HighwayPerception hwyPerception);
}
其中AgentAction
是表示代理可以在一个步骤中决定执行的操作的类型(在最简单的情况下,这将是一个值为STEER_LEFT
,{{1}的枚举对于更复杂的问题,您可以使用STEER_RIGHT
作为超类/接口来定义整个类层次结构。模拟器的工作是解释代理返回的AgentAction
对象,并相应地更改其环境状态(即AgentAction
对象)。
另一方面,参数Highway
代表了代理人在当前时间步骤能够感知的所有内容:例如,汽车的速度(HighwayPerception
)或到达的距离下一辆车(getMySpeed()
)。这避免将代理直接耦合到其环境(即getNearestCarInLane(int laneNumber)
)---这很重要,因为分离了关注点:仅代理感知他们的环境决定行动,而不是直接与之互动。同样,模拟器的工作是在给定当前环境状态的情况下为代理创建感知。
最后,此设计还可以更轻松地控制代理。
必须设计Highway
类,以便它只能用于读取代理应该能够感知的数据,而不会影响周围环境直。相比之下,原始设计中的代理可以访问HighwayPercept
对象,因此可以尝试作弊,例如前往几英里的Highway
车辆并计划相应的路线,或只是改变高速公路上其他车辆的位置。 这绝不可能,即使您不太关心安全性,因为这些事情也可能无意中发生,并且调试起来可能很棘手。
根据您的要求,您的架构当然可能需要更复杂。 更多信息应该很容易从multi-agent simulation systems的文献中获得(这是您的问题的概括,即几个代理可以模拟在您的高速公路上行驶) 。这个领域正在进行大量研究,您可能需要查看多种代理模拟工具(例如Repast)。
答案 1 :(得分:0)
我个人会封装要包含在模拟器中的高速公路。如果每个模拟器有超过1个高速公路,那么我会假设代理将在任何高速公路对象上,因此代理可以由模拟器拥有并与高速公路相关联。但模拟器应该是一个Facade模式,所以你需要做的就是创建模拟器,并且可以选择传递一个配置,这样你就不必处理它们了。每个代理都应该有一个run()方法,模拟器中应该有一个线程在它包含的每个Agent上调用run(),或者你可以在Simulation中有一个手动步骤,为每个Agent调用run()一次(比如一步一步模拟器)。