日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python笔试题奥特曼打怪兽_2019阿里校招测评题,光明小学完全图最短路径问题(python实现)...

發(fā)布時(shí)間:2024/3/24 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python笔试题奥特曼打怪兽_2019阿里校招测评题,光明小学完全图最短路径问题(python实现)... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目:光明小學(xué)的小朋友們要舉行一年一度的接力跑大賽了,但是小朋友們卻遇到了一個(gè)難題:設(shè)計(jì)接力跑大賽的線路,你能幫助他們完成這項(xiàng)工作么?

光明小學(xué)可以抽象成一張有N個(gè)節(jié)點(diǎn)的圖,每?jī)牲c(diǎn)間都有一條道路相連。光明小學(xué)的每個(gè)班都有M個(gè)學(xué)生,所以你要為他們?cè)O(shè)計(jì)出一條恰好經(jīng)過(guò)M條邊的路徑。

光明小學(xué)的小朋友們希望全盤(pán)考慮所有的因素,所以你需要把任意兩點(diǎn)間經(jīng)過(guò)M條邊的最短路徑的距離輸出出來(lái)以供參考。

你需要設(shè)計(jì)這樣一個(gè)函數(shù):

res[][] Solve( N, M, map[][]);

注意:map必然是N * N的二維數(shù)組,且map[i][j] == map[j][i],map[i][i] == 0,-1e8 <= map[i][j] <= 1e8。(道路全部是無(wú)向邊,無(wú)自環(huán))2 <= N <= 100, 2 <= M <= 1e6。要求時(shí)間復(fù)雜度控制在O(N^3*log(M))。

map數(shù)組表示了一張稠密圖,其中任意兩個(gè)不同節(jié)點(diǎn)i,j間都有一條邊,邊的長(zhǎng)度為map[i][j]。N表示其中的節(jié)點(diǎn)數(shù)。

你要返回的數(shù)組也必然是一個(gè)N * N的二維數(shù)組,表示從i出發(fā)走到j(luò),經(jīng)過(guò)M條邊的最短路徑

你的路徑中應(yīng)考慮包含重復(fù)邊的情況。

一 、求解

先來(lái)說(shuō)一下求解這一題的思路,這個(gè)問(wèn)題的本質(zhì)就是M步無(wú)向圖的最短路徑遍歷,一般求解最短路徑問(wèn)題,我們首先想到的就是采用遞歸實(shí)現(xiàn)。

已知有N個(gè)節(jié)點(diǎn),求解從節(jié)點(diǎn)i到節(jié)點(diǎn)j之間的M步的最短路徑問(wèn)題,我們可以把M步分解成1步和M-1步:

1、假設(shè)存在節(jié)點(diǎn)k,且k節(jié)點(diǎn)不同于節(jié)點(diǎn)i,節(jié)點(diǎn)j,第一步求解節(jié)點(diǎn)i到節(jié)點(diǎn)k之間的1步最短路徑

2、剩下M-1步,可以看做求解節(jié)點(diǎn)k到節(jié)點(diǎn)j之間的M-1步最短路徑問(wèn)題

3、當(dāng)k取不同值時(shí),我們會(huì)得到多個(gè)距離值,選取最小的一個(gè)距離值

#-*- coding: utf-8 -*-

"""Created on Fri Aug 3 08:54:35 2018

@author: zy"""

importnumpy as npdefSolve(maps,M):'''由N個(gè)節(jié)點(diǎn)兩兩連接組成路徑,選取從節(jié)點(diǎn)i->節(jié)點(diǎn)j之間的最短M條路徑

param:

maps:二維數(shù)組,由兩兩節(jié)點(diǎn)之間的路徑長(zhǎng)度組成

M:表示所經(jīng)過(guò)的路徑個(gè)數(shù)'''

'''輸入校驗(yàn)'''

if notisinstance(maps,(list,np.ndarray)):raise ValueError('輸入?yún)?shù)maps數(shù)據(jù)類型必須是list或者numpy.array')if len(maps.shape) != 2:raise ValueError('輸入?yún)?shù)maps為二維數(shù)組')if maps.shape[0] != maps.shape[1]:raise ValueError('輸入二維數(shù)組maps行數(shù)和列數(shù)要求一致')#計(jì)算節(jié)點(diǎn)的個(gè)數(shù)

N =maps.shape[0]if N<2 or N>100:raise ValueError('輸入二維數(shù)組maps行數(shù)必須在2~100之間')if M<2 or M>1E6:raise ValueError('輸入?yún)?shù)N的值必須在2~1e6之間')#輸入二維數(shù)組數(shù)值校驗(yàn)

for i inrange(N):for j inrange(i,N):if maps[i][j] !=maps[j][i]:raise ValueError('輸入二維數(shù)組maps必須是對(duì)稱的')if maps[i][j] < -1e8 or maps[i][j] > 1e8:raise ValueError('二維數(shù)組maps的元素值必須在-1e8~1e8之間')if i==j:if maps[i][j] !=0:raise ValueError('二維數(shù)組maps的對(duì)角元素值必須是0')#用于保存i->j的路徑值

res =np.zeros_like(maps)#計(jì)算節(jié)點(diǎn)i->j的最短路徑

for i inrange(N):for j inrange(i,N):

res[i][j]=MinPath(maps,M,i,j)

res[j][i]=res[i][j]returnresdefMinPath(maps,M,i,j):'''計(jì)算i->j的最短路徑'''

#遞歸終止條件

if M == 1:returnmaps[i][j]'''計(jì)算i->j的最短路徑'''N=maps.shape[0]#用于保存i->j的可能路徑長(zhǎng)度

length =np.zeros(N)#遍歷從k->j的最短路徑

for k inrange(N):if k != i and k !=j:#k->j的M-1條最短路徑 + i->k的一條路徑

length[k] = MinPath(maps,M-1,k,j) +maps[i][k]#進(jìn)行排序,過(guò)濾掉為0的值

length =np.sort(length)for i inlength:if i !=0:returniif __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= 3result=Solve(maps,M)print(result)

二、時(shí)間復(fù)雜度分析

我們來(lái)分析一下該算法的時(shí)間復(fù)雜度。

先來(lái)分析一下遞歸函數(shù)MinPath(maps,M,i,j):

1、函數(shù)的規(guī)模為M

2、當(dāng)規(guī)模是1時(shí),函數(shù)結(jié)束

3、假設(shè)T(M)表示規(guī)模為M的問(wèn)題所需要的步驟數(shù)

算法的遞歸方程為:T(M) = (N-2)T(M - 1) +3N+6

注釋:3N+6表示規(guī)模毎減少一次,所做的步驟數(shù)

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] 當(dāng)i==j時(shí) N-1次,否則N-2次 我們?nèi)-2次

length =np.sort(length) 1次

最后的for循環(huán) 2次或者4次 我們?nèi)?次

迭代展開(kāi):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函數(shù)中遞歸函數(shù)循環(huán)的次數(shù)為N(1+N)/2,所以算法的復(fù)雜度為O(N2(N-2)(M-1))。并沒(méi)有滿足題目的要求,更好的求解方法我還沒(méi)有想到,有了解的大佬可以告訴小弟。

參考文章:

總結(jié)

以上是生活随笔為你收集整理的python笔试题奥特曼打怪兽_2019阿里校招测评题,光明小学完全图最短路径问题(python实现)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。