6

我正在尝试模拟一个实时网络,其中节点是不同速率的消费者和生产者。我将如何使用 Python 快速实现一个示例?我想象我会为每个节点编写一个简单的程序,但我不确定如何将它们相互连接。

4

8 回答 8

5

至少在开始时坚持传统的模拟结构

您的目标是编写一个异步系统作为练习吗?如果是这样,那么我猜如果不是多进程或网络系统,您至少必须实现多线程。

但是如果它真的是一个模拟,而你想要的是分析结果,那么实现一个实际的分布式模型将是一种非常复杂的方法,它产生的数据可能比抽象模拟要少得多,也就是说,模拟本身并不必须异步参与者通信的网络。那将是使问题变得如此困难以至于无法解决的好方法。

我说,坚持传统的模拟架构。

经典离散事件模拟

它的工作方式是,作为一个中央数据结构,你有一个待处理事件的排序集合。事件自然地按增加的时间排序。

该程序有一个主循环,它从集合中取出下一个(即最低值的)事件,将模拟时钟提前到该事件的时间,然后调用与该事件相关的任何特定于任务的处理。

但是,您会问,如果在模拟器刚刚跳过的时间增量中应该发生某些事情怎么办?好吧,根据定义,什么都没有。如果模拟的单个元素需要在该时间间隔内发生某些事情,它负责分配一个事件并将其插入(排序的)集合中。

虽然有许多适用于模拟的包和程序,但模拟的内容并不难,用你最喜欢的语言从头开始编写它是完全合理的。

玩得开心!

于 2009-09-27T22:59:00.830 回答
2

进程间通信通常是一件很难做到的事情。您可能需要考虑另一种方法是否可以满足您的需求,例如离散事件模拟器。

在 DES 中,您实际上并不执行每个节点的工作,只是模拟每个节点完成工作需要多长时间。您可以使用优先级队列来跟踪传入和传出工作,并检测系统以跟踪全局和每个节点的队列大小。

也许如果您提供有关您要完成的工作的更多详细信息,我们可以提供更具体的建议。

编辑: Python 在模块中有一个内置的优先级队列heapq,参见http://docs.python.org/library/heapq.html

于 2009-09-27T22:45:31.417 回答
2

我喜欢@DigitalRoss 和 dcrosta 对离散偶数仿真的建议,我想指出 Python 标准库中的sched模块正是您在这样一个系统的核心所需要的(无需重建核心在 heapq 之上,或其他)。你只需要初始化一个sched.scheduler实例,而不是通常的time.timeand ,通过传递给它两个模拟time.sleep时间流逝的可调用对象。

例如:

class FakeTime(object):
  def __init__(self, start=0.0):
    self.now = start
  def time(self):
    return self.now
  def sleep(self, delay):
    self.now += delay

mytimer = FakeTime()

并用于s = sched.scheduler(mytimer.time, mytimer.sleep)实例化调度程序。

于 2009-09-27T23:28:34.817 回答
1

查看 NetworkX 一个用于创建和操作网络的 Python 库。编辑:注意,与 NetworkX 附近/相关,也托管在 Los Alamos NL,是 PyGraphviz,一个显示图形的实用程序。感谢 las3jrock 指出我最初的链接错误。

您可以按原样使用 NetworkX,也可以从这个库中获得灵感(我不会打扰这个库真的有网络模拟似乎需要的“万物图”。)无论如何,这种类型的图创建和操纵将允许您代表(并扩大/缩小/发展)网络。

如前所述,使用基于图形库的单个集中式对象/服务,您将需要创建一个(或多个)类来表示网络节点的行为。

然后,根据您的需要,如果网络相对较小,网络节点可以有效地“放松”,并在线程内部运行。或者(这对于模拟来说通常很容易管理),可以有一个集中的方法来遍历节点并在适当的时候调用它们的“do_it”方法。如果这种集中控制器的“刷新率”足够高,则可以使用节点级别的实时时钟来确定何时应该触发节点的特定行为。这种模拟可以是事件驱动的,也可以简单地轮询(同样,如果刷新周期相对于时钟的基本时间单位足够低。)

网络的集中“地图”将提供网络节点执行其“工作”所需的各种与网络相关的原语(无论这可能是什么)。换句话说,节点可以从“地图”中查询它们的直接邻居列表、完整网络的目录、通往任何给定节点的路线(及其成本)等。

或者,网络的结构可以分布在网络本身的节点上,例如Internet。这种去中心化的方法有几个优点,但它意味着向节点添加逻辑和数据,以便它们实现 DNS 和路由的等价物。这种方法还有一个缺点,即要求节点之间的相当数量的流量与网络拓扑的发现和维护有关,而不是与网络要模拟的任何通信/交换语义有关。简而言之,我不建议使用这种分散的方法,除非手头的模拟旨在研究这种分布式网络管理系统的协议。

编辑:

几个答复中建议的 DES 方法肯定解决了问题的模拟部分。如果问题的网络部分很重要,那么实现基于强大图形库的虚拟网络将是解决方案的重要部分。这种方法将更容易地揭示与网络拓扑相关的系统动态。

于 2009-09-27T22:44:18.437 回答
0

以下是制作基本客户端/服务器程序的方法: http ://wdvl.internet.com/Authoring/python/client/watts06152009.html

对于从一个发送到另一个的数据,我推荐JSON,这是有史以来最简单的格式。如果要在 python 上实现它,请检查 simplejson:http: //pypi.python.org/pypi/simplejson/

于 2009-09-27T22:45:28.717 回答
0

想到两件事:

1- 您可以使用 Twisted Python 编写一个或多个守护进程。(请注意,twisted 可能会有点压倒性,因为它是一个事件驱动的异步系统)。每个守护进程都可以绑定到一个端口并使自己对其他守护进程可用。或者,您可以只在一个守护程序中运行所有内容,并让您编写脚本的每个“进程”以不同的时间间隔触发......并通过绑定端口相互通信。

2-您可以使用单个事件驱动的核心——有几个——然后为每个任务分叉一堆进程或线程。

于 2009-09-27T23:27:40.887 回答
0

只需使用 Stackless Python,创建 tasklet,将它们与通道连接,一切都会正常工作。这非常简单。

于 2009-09-28T13:12:07.903 回答
0

这是 Stackless 做得非常好的事情。

此外,您可以使用生成器/协程。

有趣的链接:

http://www.python.org/dev/peps/pep-0342/

新用户只能发布 1 个超链接...所以这是另一个

'/'.join(['http:/', 'us.pycon.org', '2009', 'tutorials', 'schedule', '1PM6/'])
于 2009-09-28T15:17:48.663 回答