简体   繁体   中英

How can i store and use values more efficiently for a ant simulation?

I am making a ant simulation and i need to store all the pheromones (int values).

Here is how it works:

  • When a ant go somwhere it deposit 10 pheromone.(already done)
  • Every tick the pheromone value decreases by one and cant get bellow 0.

I need something to do the last thing somewhat efficiently.
Here is my code:

# world is the map on a 1000x1000 array of 0 at the start
def evaporate():
    for x in range(len(world)):
        for y in range(len(world[0])):
            if world[x][y] > 0:
                world[x][y] -= 1

I think there is better ways to store the map values but i cant find one that is efficient.
If you can use no library that would be better as i like to see what my program does but if it's more efficient or easier thats okay!

If there is any typos tell me i'll correct them. (english is not my primary language)
And thank you for your time.

A 1000 by 1000 world has 1.000.000 tiles. One is your base, several are ants, some have pheromones in it.

Instead of storing the complete map, only store where data is present. You can use a dictionary with (x,y) as key.

As a pheromone level of 10 represents an ant, you could do it like so:

class ant():
    import random
    # movement delta in 8 directions
    _delta_move = [(dx,dy) for dx in range(-1,2) for dy in range(-1,2)]

    def __init__(self, x, y, maxage = 5):
        self.__x = x
        self.__y = y
        self.age = maxage

    def getPos(self):
        return (self.__x, self.__y)

    def kill(self):
        self.age = 0

    def random_move(self):
        # every move reduces ants age, when 0 it dies
        self.age -= 1
        if self.age > 0:
            d = random.choice(ant._delta_move)
            self.__x += d[0]
            self.__y += d[1]
            return self.getPos()
        return None # dead

Create a list of ants and a map and propagate movement:

mapsize = 10

# helper 
def print_map(m):
    """prints the map, if a pheromon level is 10 the ant is in this field"""
    for y in range(mapsize):
        print("  #",end="")
        for x in range(mapsize):
            value = m.get( (x,y), " ")
            if value == 10:
                value = "a"
            elif value == 0:
                value = " "
            print(value, end="")
        print()


# list of ants
ants = [ ant(5, 5, 6) for _ in range(5 )]

# initial map, 10 pheromones is max per field
ant_map = { a.getPos():10 for a in ants}

while (ants):
    print_map(ant_map)
    input("Enter for next round")

    # decay pheromones
    done = [] # store keys to delete, avoid changing dict while iterating
    for key,value in ant_map.items():
        if value > 0:
            ant_map[key] -= 1
        else:
            done.append(key)
    for k in done:
         del ant_map[k]

    # remove dead ants
    ants = [a for a in ants if a.age > 0]

    # move ants and add new pheromones
    for a in ants:
        # move ant
        new_pos = a.random_move()
        if new_pos and 0 <= new_pos[0] < mapsize and 0 <= new_pos[1] < mapsize:
            ant_map[new_pos] = 10
        else:
            a.kill()

print_map(ant_map)

Output:

  #          
  #          
  #          
  #          
  #          
  #     a    
  #          
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #          
  #          
  #    a a   
  #     aa   
  #          
  #          
  #          
  #          
Enter for next round
  #          
  #          
  #          
  #    a     
  #    a 9a  
  #     9a   
  #      a   
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #          
  #    9aa   
  #   a9a89  
  #     89   
  #     a9   
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #    a a   
  #    8a9   
  #   a8978  
  #     7a   
  #     98   
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #    9a9   
  #  a 7a8   
  #   97a67  
  #     6a   
  #     87   
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #    898   
  #  9 697   
  #   86956  
  #     59   
  #     76   
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #    787   
  #  8 586   
  #   75845  
  #     48   
  #     65   
  #          
  #          
  #          
Enter for next round
  #          
  #          
  #    676   
  #  7 475   
  #   64734  
  #     37   
  #     54   
  #          
  #          
  #          
Enter for next round
  #          
  #          
  #    565   
  #  6 364   
  #   53623  
  #     26   
  #     43   
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #    454   
  #  5 253   
  #   42512  
  #     15   
  #     32   
  #          
  #          
  #          
Enter for next round  
  #          
  #          
  #    343   
  #  4 142   
  #   314 1  
  #      4   
  #     21   
  #          
  #          
  #          
Enter for next round  
  #          
  #          
  #    232   
  #  3  31   
  #   2 3    
  #      3   
  #     1    
  #          
  #          
  #          
Enter for next round 
  #          
  #          
  #    121   
  #  2  2    
  #   1 2    
  #      2   
  #          
  #          
  #          
  #          
Enter for next round
  #          
  #          
  #     1    
  #  1  1    
  #     1    
  #      1   
  #          
  #          
  #          
  #          
 

Try this:

import numpy as np  # <-- for efficient storage
import matplotlib.pyplot as plt # <-- for visualization

# Initialize a random map with values from 0 to 10.
pheromone_map = np.random.randint(low=0, high=11, size=(1000, 1000))

# Visualize the pheromones disappearing
for i in range(10):
    # clip removes any negative value from the array that had 1 subtracted from it
    pheromone_map = np.clip(pheromone_map - 1, a_min=0, a_max=11)
    # Shows how the pheromones disappear
    fig, ax = plt.subplots()
    ax.imshow(pheromone_map)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM