python - 在 2D 计划中放置 N 个代理

标签 python python-3.x

对不起,如果我的英语不好(我是法国学生)。

我正在为一个学校项目工作,我想在一个有墙壁、喷泉和路灯的模型化地方创造人群运动。我几乎做了所有事情:创建了 AI 并可以在 2D 计划上移动,我的位置用我之前说过的一些东西建模,我使用雷诺兹的 Boid 规则(对齐、凝聚、分离)在一个过程中处理人类交互人群运动。我仍然需要编写一个函数来模拟人们触摸墙壁或其他结构时的物理现象。

但我正在对人群进行初​​始化(创建),但它不起作用:人群由 N 人(代理人)组成,其中 N 介于 1 和 5518 之间(由于空间限制)。 这是代码:

self.agents = []
x = 50
y = 55
X = 0
while X < N:
    if x <= 100 and x >= 50 and y <= 165 and y >= 55:
        k = 0
        while k < 50 and X < N:
            for a in range(11):
                for b in range(13):
                    if (x, y) != ((70 + a),(104 + b)):
                        x += k
                        agent = UnAgent(x, y)
                        self.agents.append(agent)
                        X += 1
                        k += 1
        x = 50
        y += 1

我认为存在无限循环,但我无法解决它。为了更好地理解我的代码,这是我的绘画计划的图片,然后第二张图片是我的程序,其中所有代理都在该地点中心的唯一图 (x,y) 上生成(这是我不想要的) ,我希望每个人都被放置在一个独特的地 block 上,同时穿过 X 坐标,然后将 1 加到 Y 坐标,然后穿过 X 坐标等,并且人们不能在红色方 block 中产卵,所以喷泉)

First image of my plan on paint with explanation

Second image of my real program without the spawn feature

编辑:

您好@PatrickArtner,感谢您关注我的问题并帮助我!您的回复非常有用,所以我尝试调整您的代码(与我的代码相比真的很容易理解!)这就是我所拥有的:

def addMonumentCentral():
    '''Bloque la place de (70,104) à (80,116) avec des "briques" '''
    L=[]
    for a in range(70,81):
        for b in range(104,117):
            L.append((a,b)) # List of every unique tuple occupied by water
class Foule:
def __init__(self, count, largeur = 150, hauteur = 220):
    self.largeur = largeur
    self.hauteur = hauteur
    self.agents = []
    numAg = 0
    MonumentCentral = addMonumentCentral()
    for y in range(55,166):permise
        for x in range(55,101):
            if (x,y) not in MonumentCentral:
                agent = UnAgent(x, y)
                agent.largeur = largeur
                agent.hauteur = hauteur
                self.agents.append(agent)
                numAg += 1ajoutes
            if numAg == count:
                break
        if numAg == count:
            break

我不习惯字典,所以我调整了你的第一个函数来返回每个水 block 的列表,它返回如下内容:[(.. , ..),(.. , ..) , ... ,(.. , ..)] 其中每对括号是二维平面图上的水图。

然后,我将你的第二个函数应用到我的 Foule 类(在英语中是“人群”的意思),唯一不起作用的是(这会阻止整个代码运行,通常一切正常,除了那个)是if (x,y) not in MonumentCentral: 行。似乎我无法用 Python 中的元组列表测试元组:我是 Python 的初学者,它似乎不起作用,但我不知道如何做一些我以前做过的事情行。

当我执行代码时,出现以下错误行:TypeError: argument of type 'NoneType' is not iterable。你知道如何用类似的方法替换测试行,用元组列表测试元组吗?

您真诚的, 阿克塞尔乔利

编辑 2:

我的代码现在可以运行了,这是结果:

class Foule:
def __init__(self, count, largeur = 150, hauteur = 220):
    self.largeur = largeur
    self.hauteur = hauteur
    self.agents = []
    numAg = 0 # Nombre d'agents ajoutes
    MonumentCentral = []
    for a in range(70,81):
        for b in range(104,117):
            MonumentCentral.append((a,b))
    for y in range(55,166): # On parcourt selon les y la zone de spawn permise
        for x in range(55,101): # On parcourt selon les x la zone de spawn permise
            if (x,y) not in MonumentCentral: # On check si c'est bloqué ou non
                agent = UnAgent(x, y) # Position de depart
                agent.largeur = largeur
                agent.hauteur = hauteur
                self.agents.append(agent)
                numAg += 1 # Iteration pour compter le nombre d'agents ajoutes
            if numAg == count: # On casse si on atteint le nombre d'agents voulu
                break
        if numAg == count: # On casse si on atteint le nombre d'agents voulu
            break

对不起,它主要是法语,但它现在可以完美地工作,从 1 个代理到 5518 个代理!

最佳答案

我很难理解您使用的 while 循环,所以我将它们重写为更简单的 for .. in range(..):循环遍历所需的 x/y范围。

如果可以放置代理,可以使用 set 检查被阻塞的坐标 - 我选择使用 dict - 用于额外存储阻挡磁贴的内容(主要用于显示目的)。

在放置任何代理之前,您可以阻止所有不可用的图 block (将它们放入集合中)。然后开始放置代理,检查瓷砖是否被阻挡,否则放置并计数。迭代直到放置所有代理:

def addFountain(place):
   """Blocks the places (70,104) to (80,116) with water tiles"""
    for a in range(70,81):
        for b in range(104,117):
            place[(a,b)] = "~"  # water    


occupied = dict()               # dict as "playground" - it remembers which places are 
                                # already occupied. You can simply use a set of coords.

addFountain(occupied)           # add all water tiles to the dict (block the spaces)

maxNum = 74                     # place 74 agents
numAg = 0                       # placed 0 agents so far

for y in range(55,166):         # go over all tiles vertically
    for x in range(55,101):         # go over all tiles horizontally
        if (x,y) not in occupied:    # check if blocked, if not 
            occupied[(x,y)] = "A"                    # add UnAgent(x, y), I am adding "A"
            numAg += 1                               # count added agent
        if numAg == maxNum:                          # break if max reached
            break
    if numAg == maxNum:                       # break outer if max reached
        break

# visualizing the dictionary:
print("-" * (101-55+2))       # print plaza

for y in range(166,54,-1):     # print plaza (reversed so 55 is at bottom)
    print("|", end="")
    for x in range(55,101):
        print(occupied.get( (x,y), " "), end="") # print if in dict, else print space
    print("|")

print("-" * (101-55+2))

输出:

------------------------------------------------
|                                              |
|                                              |
      ... removed lots of empty lines ...
|                                              |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|               ~~~~~~~~~~~                    |
|                                              |
      ... removed lots of empty lines ...
|                                              |
|AAAAAAAAAAAAAAAAAAAAAAAAAAAA                  |
|AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|
------------------------------------------------

您可以像这样从字典中获取代理列表:

agents = [occupied[coord] for coord in occupied if occupied[coord] == "A"] (isinstance of your agent class)

您可能应该调整此代码以适应您的类结构。

关于python - 在 2D 计划中放置 N 个代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50700062/

相关文章:

python - 使用 to_csv 时如何保留数据帧的数据类型?

python - dill vs cPickle 速度差异

html - 如何 : Active State During Server Action w/o JavaScript

python - 在python中从键盘读取原始输入

python - Impyla 从 Flask 插入 SQL : Syntax error (Identifier Binding)

python - 在 df 中查找值

python - 如何使用字典替换 Pandas 系列中的多个子字符串?

c++ - 在 C++ 源文件中每个函数定义的开头添加一个宏调用

python - 如何使用索引作为数据帧列来 "merge"多个 pandas 数据帧?

python - Flask streaming 在完成之前不会返回响应