阿里巴巴2018校园招聘运筹优化算法工程师编程题
对于考试向来都是后知后觉,过后留下一堆不甘与遗憾——然而不行就是不行,再接再厉。
声明:涉及阿里校招笔试,如有侵权,请联系我删除。
一、带信号灯的最短路问题
1. 题目描述
现在城市有N个路口,每个路口有自己的编号,从0到N-1,每个路口还有自己的交通控制信号,例如0,3表示0号路口的交通信号每3个时刻变化一次,即0到3时刻0号路口允许通过,3到6时刻不允许通过,而6到9时刻又允许通过;以此类推,所有路口的允许通行都从时刻0开始。同时城市中存在M条道路将这N个路口相连接起来,确保从一个路口到另一个路口都可达,每条路由两个端点加上通行所需要的时间表示。现在给定起始路口和目的路口,从0时刻出发,请问最快能在什么时刻到达?
2. 分析思路
如果没有信号灯。
要在网络中找到从 一点到另外一点的最短路径,我们可以使用现有的最短路算法,可参考http://blog.csdn.net/murmured/article/details/19281031。
在加入信号灯约束之后,要考虑到达中间某个路口后的等待时间,而等待时间与到达路口的时刻和路口信号灯变化周期有关。如果是按照Floyd算法来看,需要遍历每一个节点k,如果d[i, j] > d[i, k] + d[k, j]则更新d[i, j]。但是每一个d[i, j]都是考虑以i为起点j为终点计算的通行时间,所以应比较d[i, j]与d[i, k]+w[k, j]+从通过k路口后时刻算起到达j路口的时间。由此看来Floyd算法在本题行不通。
再考虑Dijkstra算法。题目要求计算的是从给定起点到终点的最短时间,这与Dijkstra算法计算其实节点到终节点的特性类似。现在回顾一下Dijkstra算法:
给定一个网络有节点集V,有向边集E,权重矩阵W,起点和终点分别为s和t。
初始化:标记节点集合为M,仅包含s;M中节点到V-M中节点的距离设为无穷大,初始节点到各标记节点的最短路径记为T,T[s]=0;
step1:检查标记节点中是否包含t,如果是则终止,否则进入step2;
step2:计算从M中各节点到V-M中各节点距离的最小值,找到V-M中对应最小值的节点并将其添加为标记节点,对应的最短距离为找到的最小值。用i遍历M中各节点,j遍历V-M中各节点,min = min{T[i] + W[i, j]}。
由于Dijkstra算法每一步计算的都是从初始点到达各标记几点之间的最短距离,这使得我们能够很容易计算在有信号灯的情况下通过路口需要在路口等待信号灯的时间,因此加入信号灯约束之后可对Dijkstra算法做如下改动即可:
给定一个网络有节点集V,有向边集E,权重矩阵W,起点和终点分别为s和t,各路口信号灯变化周期为C。
初始化:标记节点集合为M,仅包含s;M中节点到V-M中节点的距离设为无穷大,初始节点到各标记节点的最短时间径记为T,T[s]=0;
step1:检查标记节点中是否包含t,如果是则终止,否则进入step2;
step2:计算从M中各节点到V-M中各节点通行时间最小值,找到V-M中对应最短通行时间的节点并将其添加为标记节点,对应的最短通行时间为找到的最小值。用i遍历M中各节点,j遍历V-M中各节点,min = min{T[i] + W[i, j] + waittime[i, j]},其中waittime为从i路口到通过j路口需要等待信号灯时间,计算方法为:如果j为终节点则等待时间为0,否则计算m = (T[i] + W[i, j])%2*C[j],如果m小于C[j]则无需等待直接通过,否则需等待2C[j]-m。
3. 代码实现
# -*- coding: UTF-8 -*-.
#!/bin/python
import numpy as npdef minTravelTime(N, intersections, M,roads, s, t):# 初始化# 初始点到各点的最短时间以及通过该路口需要等待的时间dist = [float("inf") for i in range(N)] # 初始点s到自己的距离为0 dist[s] = 0 # 最开始标记节点为初始节点 markNodes = [s] wt = lambda x, y: 0 if divmod(x, 2*y)[1] < y else 2*y - divmod(x, 2*y)[1]while t not in markNodes:tmp_min = float("inf")tmp_node = -1for i in markNodes:for j in range(N):if j not in markNodes:if j == t:wait_time = 0else:wait_time = wt(dist[i] + roads[i, j], intersections[j])if dist[i] + roads[i, j] + wait_time <= tmp_min:tmp_node = jtmp_min = dist[i] + roads[i, j] + wait_timemarkNodes.append(tmp_node)dist[tmp_node] = tmp_minreturn dist[t]_N = int(input()) # 路口总数
_intersections = {} # 路口信号灯时间间隔
for i in range(0, _N):x, y = input().split(',')_intersections[int(x)-1] = int(y)_M = int(input())
_roads = np.zeros((_N, _N))
for j in range(0, _M):u, v, w = input().split(',')_roads[int(v), int(u)] = int(w)_roads[int(u), int(v)] = int(w)for i in range(_N):for j in range(_N):if(_roads[i, j]) == 0:_roads[i, j] = float("inf")
print(_roads)
# 输出任意起点到终点的最短到达时间
for i in range(_N):for j in range(_N):if i != j:print(i+1, j+1, minTravelTime(_N, _intersections, _M, _roads, i, j))# 以下为题目要求输出
# _s, _t = input().split(',')
# _s, _t = int(_s), int(_t)
# print(str(minTime)+"\n")
4. 算例演示
(1)输入
6
0,16
1,17
2,15
3,17
4,18
5,14
9
0,1,66
0,2,80
0,3,50
1,4,78
1,5,90
1,2,30
2,3,45
2,5,81
4,5,76
(2)输出
1 2 66.0
1 3 80.0
1 4 50.0
1 5 146.0
1 6 158.0
2 1 66.0
2 3 30.0
2 4 75.0
2 5 78.0
2 6 90.0
3 1 80.0
3 2 30.0
3 4 45.0
3 5 112.0
3 6 81.0
4 1 50.0
4 2 90.0
4 3 45.0
4 5 180.0
4 6 141.0
5 1 144.0
5 2 78.0
5 3 108.0
5 4 165.0
5 6 76.0
6 1 168.0
6 2 90.0
6 3 81.0
6 4 135.0
6 5 76.0
二、仓库货架储位编号
1. 题目描述
菜鸟仓库的货架格子编号满足如下规律:第1个格子编号为1,第2-3个12,第4-6个格子编号为123……以此类推每个格子由一个0-9之间的整数编号,n个格子的编号连起来有如下规律1|12|123|……|123456789101112131415|……|12345678910111213141516…k,仓库中的储位一共有一千多万个。如何快速找到第K个格子对应的编号。
2. 分析思路
乍一看,以为第n行第k个格子的编号为k,然后求和S=1+2+3+…+n的和,即为前n行的格子数,再用K-S即为k的编码。其实然并卵,注意题目描述,“每个格子由一个0-9之间的整数编号”,例如12345678910这个序列中,第10个格子的编号为1,第11个格子的编号为0,所以乍一看的思路不对。
再细想,为了确定第K个格子的编号,有以下几点至关重要:一是格子的行号n,二是1+2+3+…+k共有多少个格子f(k),四是前n-1行一共有多少个格子snp。如果能找出f(k)的通项公式,然后对f(k)求前n项和,再看K位与那个区间内得到snp,再计算比K-snp小的f(k)和比K-snp大或相等的f(k+1),得到k,则K的编号即为k+1从左边数第K-snp-f(k)位对应的数。所以现在问题的关键变成计算一个给定的数有多少位。这个问题经过一番苦思冥想终究没想到怎么样用一个方便求和的通项公式表达,但是在程序里面用函数来时先却是非常的简单,在Python里面可以表达成len(str(k))。所以在这里思路一转,变成牺牲计算时间用迭代的方式进行求解,过程如下:
G(n):前n行格子的总数,f(n):第n行格子的总数
step1:n = 1, G(n) = 0;
step2:G(n) = G(n) + f(n),比较G(n)和K的大小,如果G(n)小于K,则n = n + 1,重复step2;否则返回n和snp = G(n)-f(n),分别是K位于的行号n和前n-1行格子数,k = 1;
step3:比较f(k)与K-snp的大小,如果f(k)小于K-snp则k = k + 1继续step3,否则返回k;
step4:K位于第n行的第k个数中的第K-snp-f(k-1)位数。
f(n)的计算方式如下:
def f(n):if n == 0:return 0else:return reduce(lambda x, y: x+y, list(map(lambda x: len(str(x)), range(1, n+1))))
3. 代码实现
# -*- coding: UTF-8 -*-.
#!/bin/python
from functools import reduce# 第n行格子数
def f(n):if n == 0:return 0else:return reduce(lambda x, y: x+y, list(map(lambda x: len(str(x)), range(1, n+1))))def P(K):n = 1gn = f(n)while gn < K:n += 1gn = gn + f(n)# print(gn)snp = gn - f(n)k = 1while f(k) < K-snp:k += 1return [n, list(str(k))[K-snp-f(k-1)-1]]ts = ''
tn = 1
for i in range(1, 1000):[n, p] = P(i)if n == tn:ts += str(p)else:print(ts)tn = nts = str(p)
print(ts)
4. 算例演示
(1)输入:1-1000
(2)输出
1
12
123
1234
12345
123456
1234567
12345678
123456789
12345678910
1234567891011
123456789101112
12345678910111213
1234567891011121314
123456789101112131415
12345678910111213141516
1234567891011121314151617
123456789101112131415161718
12345678910111213141516171819
1234567891011121314151617181920
123456789101112131415161718192021
12345678910111213141516171819202122
1234567891011121314151617181920212223
123456789101112131415161718192021222324
12345678910111213141516171819202122232425
1234567891011121314151617181920212223242526
123456789101112131415161718192021222324252627
12345678910111213141516171819202122232425262728
1234567891011121314151617181920212223242526272829
123456789101112131415161718192021222324252627282930
12345678910111213141516171819202122232425262728293031
1234567891011121314151617181920212223242526272829303132
123456789101112131415161718192021222324252627282930313233
12345678910111213141516171819202122232425262728293031323334
1234567891011121314151617181920212223242526272829303132333435
123456789101112131
阿里巴巴2018校园招聘运筹优化算法工程师编程题相关推荐
- 杭州/北京内推 | 蚂蚁集团智能决策团队招聘运筹优化算法工程师/实习生
合适的工作难找?最新的招聘信息也不知道? AI 求职为大家精选人工智能领域最新鲜的招聘信息,助你先人一步投递,快人一步入职! 蚂蚁集团 蚂蚁集团-CTO 线-智能决策团队,有来自国内外 top 互联网 ...
- 差分进化算法_特邀嘉宾 | 科普差分进化算法(创新奇智运筹优化算法工程师朱小龙博士)...
文案:段克邪 排版:随心390 hello,大家好.各位可点击此处,访问公众号官方店铺.谨防上当受骗,感谢各位支持! 今天我们有幸请到创新奇智运筹优化算法工程师朱小龙博士为大家科普差分进化算法,本次推 ...
- 如何成为一名合格的运筹优化算法工程师?
作为算法工程师里的一小撮,相比机器学习.人工智能.视觉等算法工程师,运筹优化算法工程师在国内算是又小众又新鲜.作为近几年才慢慢进入大众视野的岗位,人们对其的认知和了解相对其他AI领域,还是较少的.比如 ...
- 招募 | 大马鹿物流运筹优化算法工程师
岗位描述 负责公司智能配送算法的开发.基于先进运筹优化理论结合实际场景和一线业务需求,联接信息系统,开发适合本公司的智能分单和路径规划算法. 负责智能配送算法的落地并不断迭代,保证实际应用的有效性与高 ...
- 带信号灯的最短路dijkstra问题(阿里巴巴2018校园招聘算法题)
题目描述 现在城市有N个路口,每个路口有自己的编号,从0到N-1,每个路口还有自己的交通控制信号,例如0,3表示0号路口的交通信号每3个时刻变化一次,即0到3时刻0号路口允许通过,3到6时刻不允许通过 ...
- 美团小哥用计算机,美团2020算法工程师编程题--外卖小哥的保温箱
题目描述: 众所周知,美团外卖的口号是:"美团外卖,送啥都快".身着黄色工作服的骑手作为外卖业务中商家和客户的重要纽带,在工作中,以快速送餐突出业务能力:工作之余,他们会通过玩智力 ...
- 美团点评2020校招算法工程师编程题--工作安排--动态规划
题目描述: 小美是团队的负责人,需要为团队制定工作的计划,以帮助团队产出最大的价值. 每周团队都会有两项候选的任务,其中一项为简单任务,一项为复杂任务,两项任务都能在一周内完成.第i周,团队完成简单任 ...
- 今日头条2018校园招聘后端开发工程师(第二批)编程题 - 题解
以前做过第三批的题目,今日头条2018校园招聘后端开发工程师(第三批)编程题 - 题解.这一场的题目偏技巧和算法,而第三批的题偏编码.这一场涉及的算法有二分查找.区间动态规划. 原题链接:点这儿. 第 ...
- 今日头条2018校园招聘后端开发工程师(第四批)编程题 - 题解
做过第三批的题目,今日头条2018校园招聘后端开发工程师(第三批)编程题 - 题解和第二批的题目,今日头条2018校园招聘后端开发工程师(第二批)编程题 - 题解. 这一场题目还是挺好玩的,也挺有技巧 ...
最新文章
- 一顿火锅钱+一台旧手机 = 自主导航机器人?
- 【MM配置】 MM组织架构的配置
- 来电掉队,共享充电宝或许只是外表光鲜
- php5.4 zend安装教程,linux下php5.4安装Zend Guard Loader扩展
- linux下挂载windows上的共享目录,并设置所有者为非root用户
- 31省份开学时间一览表
- Docker 安装zookeeper
- weka特征选择源码阅读
- 电商数字化色彩系统的探索
- yolov5 烟雾和火焰检测
- 专升本公共英语常考词组搭配和固定用法
- 教你如何看headers
- ios-swift-环信集成
- 静水流深2010年版系列教程[转]
- 【计量经济学】SPSS——一元线性回归【方差分析、残差分析】
- 撸一个聊天室(vue+koa2+websokect+mongodb)
- iPad pro能运行c语言吗,办公实战 iPad Pro还是洗洗睡吧_平板电脑评测-中关村在线...
- 坎坎坷坷的深度学习之路(三)-Hello world(2)-------MNIST数据集1-MNIST格式
- csp 2022 总结
- win7怎么连接不上宽带连接服务器未响应,宽带连接不上,教您怎么解决宽带连接不上...