前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python进阶:丢失的一笔订单

Python进阶:丢失的一笔订单

作者头像
披头
发布2019-12-26 09:42:39
4840
发布2019-12-26 09:42:39
举报
文章被收录于专栏:datartisandatartisan

2018年某天曾接到一个需求,要求给10个监考老师监考的10个科目来分配考场,要求每个老师的监考考场不能重复。见下图,不知道你感觉怎么样,我当时搞了几天没有找出随机生成的方法,丢失了一笔订单。

既然咱们已经学习了python,不妨用python试试。

需求分析:

1、生成一个10*1的数组;使用numpy.arange

2、随机排序;使用random.shuffle

3、如果一个10*1的数组到这里就完事了,可是题目要求的是10*10,没有现成的函数可以生成10*10,且行和列各不相等的矩阵。

4、考虑使用递归,下一次赋值时将已存在值去除(使用set集合)

5、每次赋值时要求随机取一个元素,使用random.sample

代码语言:javascript
复制
import numpy as npimport random
# 生成一个10*1 数组arr = np.arange(1, 11, 1)# 将该数组随机排序np.random.shuffle(arr)# 生成一个全部0值的10*10矩阵m = np.zeros((10, 10), int)# 将数组赋值给矩阵的第一行m[0, :] = arr
至此,第一行已经按照要求生成了,现在从m[1,0]开始给剩余的0赋值。定义一个计算函数calc(i, j) #i, j分别表示行列编号
代码语言:javascript
复制
def calc(i, j):    # 设置变量t,存储未出现过的数字,初始值为1~10的集合,第一次要填充    # m[1][0]位置,去除首行首列值就可以了,也就是此时i = 1, j = 0     t = set(np.arange(1, 11)) - set(m[0:1, 0])
代码语言:javascript
复制
# 从集合t中随机取一个元素赋值给m[1][0]x = random.sample(t, 1)
代码语言:javascript
复制
# 刚才赋值时用到的元素需要在集合t中剔除,否则会重复出现t.remove(int(x[0]))# 至此,第一次赋值就结束了,考虑继续赋值m[1][1],将列编号变量j+1,步骤相同# 数字1~10的集合,去除首行1列的值也就是去除m[0][1]t = set(np.arange(1, 11)) - set(m[0:1, 1])  # i=1,j=1# 同时,还需要去除1行0列的值,也就是m[1][0]t = t - set(m[1, 0:1]) # i=1,j=1
代码语言:javascript
复制
# 从集合t中随机取一个元素赋值给m[1][1]x = random.sample(t, 1)
代码语言:javascript
复制
# 同理,此时需要将刚才赋值时用到的元素在集合t中剔除t.remove(int(x[0]))# 至此,第二次赋值就结束了,考虑继续赋值m[1][2],将列编号变量j+1,步骤相同# 第二行赋值完了,赋值第三行。。。# 直到赋值到第9行第9列,否则一直循环运行。......

分析两次赋值的规律,抽象出calc函数如下:

代码语言:javascript
复制
def calc(i, j):    t = set(np.arange(1, 11)) - set(m[0:i, j])  # t是未出现数字的集合:数字1~10,去除首行至i-1 行,j列的已出现值    t = t - set(m[i, 0:j])  # 去除i行,j-1列的已出现值,经过行列去重,t是未出现数字的集合    while True:        if len(t) == 0:            return False        x = random.sample(t, 1)  # 集合t中随机截取一个长度为1的切片        m[i][j] = x[0]  # 将切片的元素值赋值给i行j列        t.remove(int(x[0]))  # 集合t去除刚才的赋值        if j < 9:            if calc(i, j + 1):                return True        elif i < 9:            if calc(i + 1, 0):                return True        else:            return True

我们来看看某次代码运行结果吧。(每运行一次结果不同)

小伙伴们可以试试,你是否可以得出10*10的矩阵,要求是行和列都不能相同。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 乐享数据8090 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档