【问题标题】:What is the best architecture for this simulator?这个模拟器的最佳架构是什么?
【发布时间】:2011-12-04 12:14:46
【问题描述】:

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

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

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

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

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

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

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);

而且它又可怕又丑陋。

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

我不是程序员,这个项目是我学院的一门名为软件工程的选修课程的一部分。

【问题讨论】:

    标签: java architecture simulation agent


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我宁愿避免使用线程。我想让它尽可能简单,所以我想逐步创建模拟器。我不明白您所说的“与高速公路相关的[代理]”是什么意思?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      相关资源
      最近更新 更多