惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
博客园 - 司徒正美
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog

博客园 - 小林觉

理解软件工程 通过 n 进制整数对称加法,寻找回文串数字 正多边形内点黄金分割冒险游戏 不成熟的想法:计算的粒度 技术债务墙:一种让技术债务可见并可协商的方法 墙裂推荐 shell 脚本通过Webhook 发送消息到微信群 - 小林觉 关于中医的一段对话 [ZZ] -- 思维训练故事 应用深度神经网络预测学生期末成绩 Python中的模块引用机制 - 小林觉 - 博客园 批量修改含空格的文件名「Linux」 Markdown数学公式语法 - 小林觉 - 博客园 批处理修改IP Hadoop 操作常见问题解决 linux 下vim中关于删除某段,某行,或者全部删除的命令 ZZ Hadoop 集群安装(从节点安装配置) Hadoop 集群安装(主节点安装) 少儿编程(2):简单的数学计算 - 小林觉 - 博客园 少儿编程(1):计算思维
兰顿蚂蚁:从无序到有序的伟大征程
小林觉 · 2024-04-21 · via 博客园 - 小林觉

1. 问题

在一个1000*1000格子的棋盘上,有一只蚂蚁(ant),蚂蚁的爬行规则是:(1)如果蚂蚁所在的棋盘是白色的,则蚂蚁将所在格子设置为黑色,并向右边爬行一个格子。(2)如果蚂蚁所在的棋盘是黑色的,则蚂蚁将所在格子设置为白色,并向左边爬行一个格子。问:请显示蚂蚁爬行10000次后,棋盘的样子。

2. 思考

首先,我们需要创建一个棋盘类(Board)和一个蚂蚁类(Ant)。棋盘类包含一个二维数组表示棋盘的状态,以及一个方法用于显示棋盘。蚂蚁类包含蚂蚁当前的位置和爬行方法。

解析:

  1. 创建棋盘类(Board),包含一个二维数组表示棋盘状态,以及一个方法用于显示棋盘。
  2. 创建蚂蚁类(Ant),包含蚂蚁当前的位置.方向,和爬行方法 move。
  3. 在主函数中,创建一个1000*1000的棋盘实例和一个蚂蚁实例。
  4. 让蚂蚁爬行10000次。
  5. 显示爬行后的棋盘状态。

3. 代码

3.1 设计 Board类 和 Ant 类, 代码如下:

import matplotlib.pyplot as plt
import numpy as np

class Board:
    def __init__(self, size):
        self.size = size
        # 创建初始棋盘,设置为全0的格子: 注意: 0 表示 白色,1表示 黑色
        self.board = np.zeros((size, size))
        
    def display(self):
        # Create the figure and axes
        fig, ax = plt.subplots()
        
        # Display the array as an image using imshow
        # cmap='binary' sets the colormap to binary 黑白色
        plt.imshow(self.board, cmap='binary')   # 黑白

        # Set axis labels and title (optional)
        ax.set_xlabel("X-axis")
        ax.set_ylabel("Y-axis")
        ax.set_title("Footprint of Ant on 2D World")
        
        # Display the plot
        plt.show()
		
		
class Ant:
    def __init__(self, board):
        # 假定初始在 棋盘中央
        self.x = board.size // 2
        self.y = board.size // 2
        # 假定初始方向朝上, 90度
        self.direction = 90
        
    def climb_one(self, board):
        if self.direction == 0 :       # right, 向右边爬行一格
            self.x = self.x + 1
        elif self.direction == 270:    # down,  向下爬行一格
            self.y = self.y - 1             
        elif self.direction == 180:    # left,   向左爬行一格
            self.x = self.x - 1
        elif self.direction == 90:     # up,     向上爬行一格
            self.y = self.y + 1  
        # 处理一下跑出边界问题:
        #    如果小于0, 则移动到最大值处, PS: 这样设置是有部分道理的,因为小于0 时候,direction是向左 或 向上的,
        #                                 移动到最大值时候,ant 方向向内
        #    如果大于最大值,则移动到0 处
        if self.x == -1 : 
            self.x = board.size - 1
        if self.y == -1 : 
            self.y = board.size - 1
        if self.x == board.size - 1 : 
            self.x = 0
        if self.y == board.size - 1 : 
            self.y = 0
			
    def move(self, board):
        if board.board[self.x][self.y] == 0:  # 原来是白色0 
            # Step 1: 脚下格子设置为黑色1 
            board.board[self.x][self.y] = 1   
            # Step 2: 右转
            self.direction = (self.direction - 90) % 360
            # Step 3:爬行一格
            self.climb_one(board)
        else:   # 原来是黑色1 
            # Step 1: 脚下格子设置为白色0
            board.board[self.x][self.y] = 0
            # Step 2:左 转
            self.direction = (self.direction + 90) % 360
            # Step 3:爬行一格
            self.climb_one(board)
			
			

3.2 测试代码

# 测试蚂蚁
def run(board_size, ant_step):
    # 设置棋盘,大小为 board_size * board_size 
    board = Board(board_size)
    ant = Ant(board)
    
    # 蚂蚁爬行
    print("moving ......")
    for _ in range(ant_step):  # 设置蚂蚁爬行步数: ant_step
        ant.move(board)
    print("Finished ! ")
    
    # 显示最终棋盘
    board.display()

if __name__ == '__main__':
    # 可以测试多种棋盘大小和蚂蚁移动步数
    run(board_size = 500, ant_step = 15000)
	run(board_size = 250, ant_step = 15000)
	
	

4 结果展示

4.1 蚂蚁初始方向头朝上,棋盘 100* 100 , 爬行 15000次

image

4.2 蚂蚁初始方向头朝上,棋盘 100* 100 , 爬行 1000次

image

4.3 蚂蚁初始方向头朝上,棋盘 1000* 1000 , 爬行 50000次

image

4.4 蚂蚁初始方向头朝,棋盘 250* 250 , 爬行 50000次

image

4.5 蚂蚁初始方向头朝,棋盘 250* 250 , 爬行 100W次

image

5. 代码改进

class Ant:
    def __init__(self, board):
        # 假定初始在 棋盘中央
        self.x = board.size // 2
        self.y = board.size // 2
        self.Dic = {"Up": 90, "Right": 0, "Left": 180, "Down": 270}
        # 假定初始方向朝上, 90度
        self.direction = self.Dic["Up"]
        
    def climb_one(self, board):
        if self.direction   == self.Dic["Right"]:       # right, 向右边爬行一格
            self.x = (self.x + 1) % board.size
        elif self.direction == self.Dic["Down"]:        # down,  向下爬行一格
            self.y = (self.y - 1) % board.size            
        elif self.direction == self.Dic["Left"]:        # left,   向左爬行一格
            self.x = (self.x - 1) % board.size
        elif self.direction == self.Dic["Up"]:          # up,     向上爬行一格
            self.y = (self.y + 1) % board.size          
            

    def move(self, board):
        if board.board[self.x][self.y] == 0:  # 原来是白色0 
            # Step 1: 脚下格子设置为黑色1 
            board.board[self.x][self.y] = 1   
            # Step 2: 右转
            self.direction = (self.direction - 90) % 360    
            # Step 3:爬行一格
            self.climb_one(board)
        else:   # 原来是黑色1 
            # Step 1: 脚下格子设置为白色0
            board.board[self.x][self.y] = 0     
            # Step 2:左 转
            self.direction = (self.direction + 90) % 360 
            # Step 3:爬行一格
            self.climb_one(board)