数组搜索+python课后小作业

数组搜索+python课后小作业,第1张

 创建一个5*5网格世界,遵守以下规则:对不同行为进行奖励和乘法,选出最优的方案。

题目: 

思路:

编写程序解决问题的步骤:

        首先理解问题,将问题拆分,表达出每个部分的意思。

        联系各个部分,考虑特殊情况, 编写代码。

        不断修改,直到自己觉得np就OK。

代码:
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 25 10:43:07 2022
创建5*5的矩阵
    四种可能行为1234,每次行为都会得分减1
    初始位置[2,1]
    到达终点[5,5],得分加10,
    到达得分点[2,4],得分加5,同时跳到[4,4]
    障碍物[3,3],[3,4],[3,5],[4,3]
@author: lx
"""
import random
import numpy as np

'''
#生成5*5数组函数
#用numpy模块,先创建矩阵5行5列
#更改初始值为1,障碍也为1
[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 1 1 1]
 [0 0 1 0 0]
 [0 0 0 0 0]]
'''
def array():
    arr = np.zeros((5, 5), dtype=np.int32)
    #障碍
    arr[2][2] = 1
    arr[2][3] = 1
    arr[2][4] = 1
    arr[3][2] = 1
    # print(arr)
    return arr
# array()
'''
#移动一次函数
#使用random模块生成数字模拟随机移动,移动方向用1,2,3,4代表上下左右。
#向上移动,则不能在第一行(即i!=0),类似向下(i!=4),向左(j!=0),向右(j!=4);否则为撞向边界,将次数加1,表示不计入移动。
#判断没有经过(即下一个点为0),移到这个位置并且将位置改为1用于表示已经走过;否则为1表示已经走过。
#如果移动到下一个位置那么,得分减1;否则没有移动,将次数加1,表示该次不计入移动。
(函数内优先使用参数+返回值,还是全局变量)?
'''
def move(i,j):
    '''
    i,j:表示数组下标,即当前位置
    count:表示移动次数
    score:表示得分
    '''
    global count,score
    action = random.randint(1, 4)#随机移动
    # print('方向:',action)
    if action == 1 and i != 0:#向上
        if arr[i-1][j]==0:
            arr[i-1][j]=1
            i -= 1
            score-=1
        else:
            count+=1
            #print('返回')
    elif action == 2 and i != 4:#向下
        if arr[i+1][j]==0:
            arr[i+1][j]=1
            i += 1
            score-=1
        else:
            count+=1
            #print('返回')
    elif action == 3 and j != 0:#向左
        if arr[i][j-1]==0:
            arr[i][j-1]=1
            j -= 1
            score-=1
        else:
            count+=1
            #print('返回')
    elif action == 4 and j != 4:#向右
        if arr[i][j+1]==0:
            arr[i][j+1]=1
            j += 1
            score-=1
        else:
            count+=1
            #print('返回')
    else:
        count+=1
        #print('边界')
    # print(arr)
    return i,j

'''
#搜索目标函数
#从初始位置[1,0],重复调用移动一次函数,实现多次移动。
#每次移动都要使用数组下标判断,是否为结束位置[4,4],是否为跳跃位置[1,3]
#and表示两真才真;or表示两假才假。双变量控制循环,and和or的选择。(亮点)
    可能依然没有到达终点,但一定不是最优解。
    circle存在,是为了当移动次数count大于5次,依然可以移动搜索终点。
    count存在,是为了防止循环20次,都是撞墙或者返回,依然可以移动5次搜索终点。
    这时存在一个漏洞bug,circle已经为false,count依然为true(即->[1,1]->[0,1]->[0,0])
    需要做特殊判断解决if count==2 and circle<0:
    不能忽略了count存在的意义附加条件if count==2 and circle<0 and i==0 and j==0:
(函数内优先使用默认参数,还是局部变量)?
'''
def sousuo(arr,i=1,j=0):
    '''
    arr:表示初始的数组(5*5网格世界)
    i,j:表示初始位置的下标(默认为1,0)
    count:表示移动次数
    score:表示的得分
    '''
    global count,score
    arr[i][j] = 1#起点
    count = 5#最少移动次数(不计返回和障碍)
    circle = 20#控制最大循环次数(有限次循环终止)
    score = 0
    while count>0 or circle>0:
        #特殊判断
        if count==2 and circle<0 and i==0 and j==0:
            #print('特殊情况')
            score = -10
            break
        count -= 1
        circle -= 1
        #调用一次移动
        i,j = move(i,j)
        if i==4 and j==4:
            #print('终点')
            score += 11
            break
        if i==1 and j==3:
            #print('跳跃')
            score += 6
            i=3
            j=3
            arr[i][j]=1
    else:
        #print('没有方向')
        score = -10
    # print()
    # print(arr)
    # print(score)
    return score,arr
# sousuo(arr)

'''
#用计算机重复思维,不断尝试,直到找到最大的分值,并输出arr
#字典,键重复会覆盖
'''
di = {}
for cir in range(100):
    arr = array()
    score,arr = sousuo(arr)
    di[score] = arr

a = max(list(di.keys()))
print(f'得分:{a}'+'\n',di[a])

#重复一百次,依然可能出现误差
#解决一:进一步循环1000次
#解决二:将上边封装函数,重复十次函数,取众数就ok了
结果:

得分:12
 [[0 0 0 0 0]
 [1 1 1 1 0]
 [0 0 1 1 1]
 [0 0 1 1 0]
 [0 0 0 1 1]]

出现的问题:

UnboundLocalError: local variable 'score' referenced before assignment

UnboundLocalError:局部变量xxx在赋值前被引用

解决:用了两次global声明变量,一个函数内用一次。

按道理我在sousuo()函数内声明了全局变量,函数内的函数move()应该能使用变量,但是报错了。还和一般的变量报错(NameError: name 'score' is not defined)不一样。

TypeError: 'numpy.ndarray' object is not callable

TypeError: 'numpy.ndarray'对象不可调用

解决:更改函数名或变量名

函数名和函数内的局部变量命名冲突导致。


 如果你也学习python的话,相互关注,共同进步!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/790014.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存