2019阿里校招测评题,光明小学完全图最短路径问题(python实现)
题目:光明小学的小朋友们要举行一年一度的接力跑大赛了,但是小朋友们却遇到了一个难题:设计接力跑大赛的线路,你能帮助他们完成这项工作么?
光明小学可以抽象成一张有N个节点的图,每两点间都有一条道路相连。光明小学的每个班都有M个学生,所以你要为他们设计出一条恰好经过M条边的路径。
光明小学的小朋友们希望全盘考虑所有的因素,所以你需要把任意两点间经过M条边的最短路径的距离输出出来以供参考。
你需要设计这样一个函数:
res[][] Solve( N, M, map[][]);
注意:map必然是N * N的二维数组,且map[i][j] == map[j][i],map[i][i] == 0,-1e8 <= map[i][j] <= 1e8。(道路全部是无向边,无自环)2 <= N <= 100, 2 <= M <= 1e6。要求时间复杂度控制在O(N^3*log(M))。
map数组表示了一张稠密图,其中任意两个不同节点i,j间都有一条边,边的长度为map[i][j]。N表示其中的节点数。
你要返回的数组也必然是一个N * N的二维数组,表示从i出发走到j,经过M条边的最短路径
你的路径中应考虑包含重复边的情况。

一 、求解
先来说一下求解这一题的思路,这个问题的本质就是M步无向图的最短路径遍历,一般求解最短路径问题,我们首先想到的就是采用递归实现。
已知有N个节点,求解从节点i到节点j之间的M步的最短路径问题,我们可以把M步分解成1步和M-1步:
1、假设存在节点k,且k节点不同于节点i,节点j,第一步求解节点i到节点k之间的1步最短路径
2、剩下M-1步,可以看做求解节点k到节点j之间的M-1步最短路径问题
3、当k取不同值时,我们会得到多个距离值,选取最小的一个距离值
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 3 08:54:35 2018 @author: zy
""" import numpy as np def Solve(maps,M):
'''
由N个节点两两连接组成路径,选取从节点i->节点j之间的最短M条路径 param:
maps:二维数组,由两两节点之间的路径长度组成
M:表示所经过的路径个数
'''
'''
输入校验
'''
if not isinstance(maps,(list,np.ndarray)):
raise ValueError('输入参数maps数据类型必须是list或者numpy.array') if len(maps.shape) != 2:
raise ValueError('输入参数maps为二维数组') if maps.shape[0] != maps.shape[1]:
raise ValueError('输入二维数组maps行数和列数要求一致') #计算节点的个数
N = maps.shape[0] if N<2 or N>100:
raise ValueError('输入二维数组maps行数必须在2~100之间') if M<2 or M>1E6:
raise ValueError('输入参数N的值必须在2~1e6之间') #输入二维数组数值校验
for i in range(N):
for j in range(i,N):
if maps[i][j] != maps[j][i]:
raise ValueError('输入二维数组maps必须是对称的')
if maps[i][j] < -1e8 or maps[i][j] > 1e8:
raise ValueError('二维数组maps的元素值必须在-1e8~1e8之间')
if i==j:
if maps[i][j] != 0:
raise ValueError('二维数组maps的对角元素值必须是0') #用于保存i->j的路径值
res = np.zeros_like(maps) #计算节点i->j的最短路径
for i in range(N):
for j in range(i,N):
res[i][j] = MinPath(maps,M,i,j)
res[j][i] = res[i][j]
return res def MinPath(maps,M,i,j):
'''
计算i->j的最短路径
'''
#递归终止条件
if M == 1:
return maps[i][j]
'''计算i->j的最短路径'''
N = maps.shape[0]
#用于保存i->j的可能路径长度
length = np.zeros(N)
#遍历从k->j的最短路径
for k in range(N):
if k != i and k != j:
#k->j的M-1条最短路径 + i->k的一条路径
length[k] = MinPath(maps,M-1,k,j) + maps[i][k] #进行排序,过滤掉为0的值
length = np.sort(length)
for i in length:
if i != 0:
return i if __name__ == '__main__':
#maps = np.array([[0,2,3],[2,0,1],[3,1,0]])
maps = np.array([[0,2,3,4],
[2,0,1,3],
[3,1,0,2],
[4,3,2,0]
])
M = 3
result = Solve(maps,M)
print(result)

二、时间复杂度分析
我们来分析一下该算法的时间复杂度。
先来分析一下递归函数MinPath(maps,M,i,j):
1、函数的规模为M
2、当规模是1时,函数结束
3、假设T(M)表示规模为M的问题所需要的步骤数
算法的递归方程为:T(M) = (N-2)T(M - 1) +3N+6
注释:3N+6表示规模毎减少一次,所做的步骤数
- if M==1: 1次
- N=maps.shape[0] 1次
- length = np.zeros(N) 1次
for k in range(N): N次
- if k != i and k != j: N次
- + maps[i][k] 当i==j时 N-1次,否则N-2次 我们取N-2次
- length = np.sort(length) 1次
- 最后的for循环 2次或者4次 我们取4次
迭代展开:T(M) = (N-2)T(M - 1) + 3N+6
=(N-2)[(N-2)T(M-2) + 3N + 6] + 3N+6
=(N-2)2T(M-2) + (N-2)(3N+6) + 3N+6
=(N-2)3T(M-3) + (N-2)2(3N+6) + (N-2)(3N+6) + 3N+6
=....
=(N-2)(M-1) + (N-2)(M-2)(3N+6)+...+3N+6
=(N-2)(M-1) + [(N-2)(M-1)(3N+6) - 3N-6]/(N-3)
= O((N-2)(M-1))
Solve函数中递归函数循环的次数为N(1+N)/2,所以算法的复杂度为O(N2(N-2)(M-1))。并没有满足题目的要求,更好的求解方法我还没有想到,有了解的大佬可以告诉小弟。
参考文章:
[2]2019阿里校招测评题,光明小学完全图最短路径问题(c版本)
2019阿里校招测评题,光明小学完全图最短路径问题(python实现)的更多相关文章
- 2019阿里天猫团队Java高级工程师面试题之第二面
2019阿里天猫团队Java高级工程师面试题之第一面 2019阿里天猫团队Java高级工程师面试题之第三面 1.Tomcat的基本架构是什么? https://blog.csdn.net/xlgen1 ...
- 2019阿里天猫团队Java高级工程师面试题之第三面
2019阿里天猫团队Java高级工程师面试题之第一面 2019阿里天猫团队Java高级工程师面试题之第二面 1.说说MySQL的锁并发?加锁的机制是什么? https://www.cnblogs.co ...
- 2019阿里天猫团队Java高级工程师面试题之第一面
2019阿里天猫团队Java高级工程师面试题之第二面 2019阿里天猫团队Java高级工程师面试题之第三面 1.五分钟自我介绍,说说自己的擅长及拿手的技术 自我介绍是为了考察面试者的语言表达和总结概括 ...
- Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解
Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解 题目地址:https://codingcompetitions.withgoogle.com/kickstar ...
- 2019届校招前端面试题整理——HTML、CSS篇
前言 2019届校招陆陆续续开始了,整理了一些高频的面试题. HTML部分 1. 什么是<!DOCTYPE>? DOCTYPE是html5标准网页声明,且必须声明在HTML文档的第一行.来 ...
- hdu6578 2019湖南省赛D题Modulo Nine 经典dp
目录 题目 解析 AC_Code @ 题目 第一题题意是一共有{0,1,2,3}四种数字供选择,问有多少个长度为n的序列满足所有m个条件,每个条件是说区间[L,R]内必须有恰好x个不同的数字. 第二题 ...
- 2019阿里云开年Hi购季大促主会场全攻略!
2019阿里云云上采购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: 2月25日-3月04日的活动报名阶段.3月04日-3月16日的新购满返+5折抢购阶段.3月16日-3月 ...
- 2019阿里云开年Hi购季满返活动火热报名中!
摘要: 在每年开年的这个大幅度优惠促销月,怎样才能花最少的钱配置最特惠的云服务?请看本文! 2019阿里云云上采购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: 2月25日 ...
- 2019阿里云开年Hi购季新用户分会场全攻略!
2019阿里云云上Hi购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: 2月25日-3月04日的活动报名阶段.3月04日-3月16日的新购满返+5折抢购阶段.3月16日-3 ...
随机推荐
- elasticsearch介绍,安装,安装错误解决及相应插件安装
一.elasticsearch介绍 1.简介(使用的是nosql,更新比mongodb慢): ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎, ...
- 利用Python实现“指尖陀螺”,让你释放压力
前言 利用Python实现“指尖陀螺”,让你释放压力 基本环境配置 版本:Python3 系统:Windows 相关模块:turtle 实现效果 不停点击键盘空格键,这个陀螺会慢慢加速,从而达到一个减 ...
- timestamp 与 nonce 防止重放攻击
重放攻击是计算机世界黑客常用的攻击方式之一,所谓重放攻击就是攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程. 首先要明确一个事情,重放攻击是二次请求,黑客通过抓包获取到 ...
- 三、Docker网络
一.查看8001端口是否开启处监听状态 netstat -apnl | grep 8001 二.使用brctl show可以看到虚拟机的网络关系 brctl show docker每新建一个conta ...
- python基础数据类型--list列表
列表: 列表是python中的基础数据类型之一,其他语言中也有类似于列表的数据类型,比如js中叫数组,他是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如: li = [‘alex ...
- Codeforces1023F Mobile Phone Network 【并查集】【最小生成树】
题目大意: 给一些没安排权值的边和安排了权值的边,没被安排的边全要被选入最小生成树,问你最大能把它们的权值和安排成多少.题目分析:假设建好了树,那么树边与剩下的每一条边都能构成一个环,并且非树边的权值 ...
- 安卓Android基础—第一天
1.1G-4G的介绍 1G 大哥大 2G 小灵通 采用gsm标准(美国军方标准民用化) 发短信 3G 沃 72M/s 4G lte 100M/s 5G 华为 10G/s 小公司卖茶品大公司卖版权(标准 ...
- [SDOI2015] 寻宝游戏
传送门:>Here< 题意:给出一棵树(有边权),刚开始键值全部为0.每次对其中一个键值进行异或,问每一次修改之后:选择任意一个点出发走到所有为1的点再走回来的最短路 解题思路 由于N,M ...
- python的if not用法
python里的if not的用法: None,False,0,空列表[],空字典{},空元祖(),都相当于false print('not x 打印出来的结果',not x) x =[1] prin ...
- bzoj 2733 : [HNOI2012]永无乡 (线段树合并)
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...