mapreduce(分治演算法的應用) 是 google 大資料處理的三駕馬車之一,另外兩個是 gfs 和 bigtable。它在倒排索引、pagerank 計算、網頁分析等搜尋引擎相關的技術中都有大量的應用。
儘管開發乙個 mapreduce 看起來很高深,感覺遙不可及。實際上,萬變不離其宗,它的本質就是分治演算法思想,分治演算法。如何理解分治演算法?為什麼說 mapredue 的本質就是分治演算法呢?
分治演算法的主要思想是將原問題遞迴地分成若干個子問題,直到子問題滿足邊界條件,停止遞迴。將子問題逐個擊破(一般是同種方法),將已經解決的子問題合併,最後,演算法會層層合併得到原問題的答案。
.):# 不斷切分的終止條件
if problem is
none
: print_result
return
# 準備資料
data=prepare_data(problem)
# 將大問題拆分為小問題
subproblems=split_problem(problem, data)
# 處理小問題,得到子結果
subresult1=self.divide_conquer(subproblems[0]
,p1,
..…)
subresult2=self.divide_conquer(subproblems[1]
,p1,..
.)subresult3=self.divide_conquer(subproblems[2]
,p1,
.…)# 對子結果進行合併 得到最終結果
result=process_result(subresult1, subresult2, subresult3,..
.) 通過應用舉例分析理解分治演算法的原理其實並不難,但是要想靈活應用並在程式設計中體現這種思想中卻並不容易。所以,這裡這裡用分治演算法應用在排序的時候的乙個栗子,加深對分治演算法的理解。
一般通過計算有序對或者逆序對的個數,來表示資料的有序度或逆序度。
假設我們有n
個資料,我們期望資料從小到大排列,那完全有序的資料的有序度就是 n(n
−1)/
2n(n-1)/2
n(n−1)
/2,逆序度等於 0;相反,倒序排列的資料的有序度就是 0,逆序度是 n(n
−1)/
2n(n-1)/2
n(n−1)
/2。q:如何程式設計求出一組資料的有序對個數或者逆序對個數呢?
因為有序對個數和逆序對個數的求解方式是類似的,所以這裡可以只思考逆序對(常接觸的)個數的求解方法。
方法2
169. 多數元素 **
class
solution
(object):
defmajorityelement2
(self, nums)
:"""
:type nums: list[int]
:rtype: int
"""# 【不斷切分的終止條件】
ifnot nums:
return
none
iflen
(nums)==1
:return nums[0]
# 【準備資料,並將大問題拆分為小問題】
left = self.majorityelement(nums[
:len
(nums)//2
])right = self.majorityelement(nums[
len(nums)//2
:])# 【處理子問題,得到子結果】
# 【對子結果進行合併 得到最終結果】
if left == right:
return left
if nums.count(left)
> nums.count(right)
:return left
else
:return right
53. 最大子序和
由於左右區間計算累加和的方向不一致,因此,左右區間直接合併相加之後就是整個區間的和
最終返回左區間的元素、右區間的元素、以及整個區間(相對子問題)和的最大值
**
class
solution
(object):
defmaxsubarray
(self, nums)
:"""
:type nums: list[int]
:rtype: int
"""# 【確定不斷切分的終止條件】
n =len(nums)
if n ==1:
return nums[0]
# 【準備資料,並將大問題拆分為小的問題】
left = self.maxsubarray(nums[
:len
(nums)//2
])right = self.maxsubarray(nums[
len(nums)//2
:])# 【處理小問題,得到子結果】
# 從右到左計算左邊的最大子序和
max_l = nums[
len(nums)//2
-1]# max_l為該陣列的最右邊的元素
tmp =
0# tmp用來記錄連續子陣列的和
for i in
range
(len
(nums)//2
-1,-
1,-1
):# 從右到左遍歷陣列的元素
tmp += nums[i]
max_l =
max(tmp ,max_l)
# 從左到右計算右邊的最大子序和
max_r = nums[
len(nums)//2
] tmp =
0for i in
range
(len
(nums)//2
,len
(nums)):
tmp += nums[i]
max_r =
max(tmp,max_r)
# 【對子結果進行合併 得到最終結果】
# 返回三個中的最大值
return
max(left,right,max_l+ max_r)
50. pow(x, n)
最終返回p
**
class
solution
(object):
defmypow
(self, x, n)
:"""
:type x: float
:type n: int
:rtype: float
"""# 【確定不斷切分的終止條件】
if n ==0:
return
1# 【準備資料,並將大問題拆分為小的問題】
if n%2==
1:# 【處理小問題,得到子結果】
p = x * self.mypow(x,n-1)
# 【對子結果進行合併 得到最終結果】
return p
return self.mypow(x*x,n/2)
if n >=
0else
1.0/self.mypow(x*x,
-n/2
)
五大常用演算法之一:分治演算法
你不知道的 python 分治演算法
第一次組隊賽
b 你有n個問題,你已經估計了第i個問題的難度為ci,現在你想使用這些問題去構造乙個問題集。比賽的問題集必須包含至少兩個問題,而且比賽的總難度必須至少為l至多為r,此外最簡單的問題和最難的問題之間的差異至少為x請您找出能夠選擇的問題集的數量。第一行有t組輸入 1 t 10接下來一行輸入n,l,r,x...
爬蟲第一次打卡
url data headers response requests.post url,data data,headers headers 發起請求 json data response.json print json data import requests from bs4 import bea...
python第一次打卡
號 表示注釋,作用於整行 多行注釋,用三個雙引號 運算子分為算術運算子 比較運算子 邏輯運算子 位運算子 三元運算子 其他運算子 運算子的優先順序 一元運算子優於二元運算子,先算術運算,後移位運算,最後位運算,邏輯運算最後結合。is,is not 對比的是兩個變數的記憶體位址 對比的是兩個變數的值 ...