ITPub博客

首页 > IT职业 > IT图书 > redis源码分析(七):集群--哨兵模式

redis源码分析(七):集群--哨兵模式

IT图书 作者:sealee 时间:2021-09-09 10:05:51 0 删除 编辑

图片描述

题目


矩阵形式

根据递推关系式,对二阶差分方程构造矩阵:

begin{align} left [ begin{array} {cc} F(N)\F(N-1) end{array}right ] & = left [ begin{array} {cc} F(N-1)+F(N-2)\ F(N-1) end{array}right ] \ & =left [ begin{array} {cc} 1&1\1&0 end{array}right ] * left [ begin{array} {cc} F(N-1)\F(N-2) end{array}right ] end{align}

根据 left [ begin{array} {cc} F(N)\F(N-1) end{array}right ] 的递推关系式, 可得:

begin{align} left [ begin{array} {cc} F(N)\F(N-1) end{array}right ] & = left [ begin{array} {cc} 1&1\1&0 end{array}right ]^{N-1} * left [ begin{array} {cc} F(1)\F(0) end{array}right ] end{align}

import numpy as npimport mathdef climbingStairs_matrix(n):
    unit = np.array([[1, 1], [1, 0]])  
    target, result = n - 1, np.identity(2, int)  # target means the total index
    while target > 1:
        index, tmp = 1, unit
        times = int(math.log2(target))  # the iterations times
        while index <= times:
            tmp, index = np.dot(tmp, tmp), index + 1
        result = np.dot(tmp, result)
        target = target - 2 ** times
    result = np.dot(unit, result) if target == 1 else result
    result = np.dot(result, np.array([[1], [1]]))    return result[0][0]
  • 最好情况下

以求 M^N 值为例,若 2^k=N,则有如下分析:

若已知 M^{frac N2},因为 M^N=M^{frac N2} * M^{frac N2},则只需要一次计算即可;

若已知 M^{frac N4},因为 M^{frac N2}=M^{frac N4} * M^{frac N4},则得出 M^N 值需要两次计算,首先计算出 M^{frac N2},然后计算出 M^N;
...
...
...
若已知 M,则计算出 M^N 需要 k 次计算,即计算 M^N 值的时间复杂度为 O(log_2N)

即最好情况下矩阵运算的时间复杂度为 O(log_2N),空间复杂度为 O(1)。

  • 最坏情况下

以求 M^N 值为例,若 2^k-1=N,则有:

M^N=M^{2^{k-1}} * M^{2^{k-1}-1}

由最好情况分析结论知,M^{2^{k-1}} 的计算次数为 k-1。若已知 M^{2^{k-1}-1},则得出 M^N 的值需要 (k-1)+1 次计算。

递推有:

M^{2^{k-1}-1}=M^{2^{k-2}} * M^{2^{k-2}-1}

由最好情况分析结论知,M^{2^{k-2}} 的计算次数为 k-2。若已知 M^{2^{k-2}-1},则得出 M^N 的值需要 (k-1)+1+(k-2)+1 次计算。
...
...
...

M^3=M^2*M

则得出 M^N 的值需要 (k-1)+1+(k-2)+1...+(1)+1=frac {k^2}2+frac k2-1 次计算。

即最坏情况下矩阵运算的时间复杂度为 O((log_2N)^2),空间复杂度为 O(1)。


保留中间状态的矩阵形式

观察以上矩阵形式的代码可知,非最优场景下的计算过程存在重复运算,虽然通过对数形式降低了重复的次数,但依然存在计算能力的浪费。针对该情况,申请空间保留中间计算状态。

def climbingStairs_matrix(n):
    unit = np.array([[1, 1], [1, 0]])  # M represents the unit matrix
    arr, target, result = [unit], n - 1, np.identity(2, int)  # target means the total index
    while target > 1:
        index, tmp = 1, unit        times = int(math.log2(target))  # the iterations times
        if times >= len(arr):            while index <= times:
                tmp, index = np.dot(tmp, tmp), index + 1
                arr.append(tmp)        else:
            tmp = arr[times]
        result = np.dot(tmp, result)
        target = target - 2 ** times
    result = np.dot(unit, result) if target == 1 else result
    result = np.dot(result, np.array([[1], [1]]))    return result[0][0]

代码中增加 arr 数组保存中间的计算状态,其中 arr[i] 表示 unit^{2^i} 的值。该形式的矩阵运算时间复杂度为 O(log_2N),空间复杂度为 O(log_2N)。

拓展形式


递归形式
def climbingStairs(n, m):
    if n == 0:        return 1
    stepSize, result = n if m >= n else m, 0
    for i in range(1, stepSize + 1):
        result += climbingStairs4(n - i, m)    return result


迭代形式
def climbingStairs(n, m):
    if n <= 1 or m == 1:        return 1
    stepSize = n if m >= n else m
    arr = [0] * stepSize
    arr[0], arr[1], index, tmp = 1, 1, 2, 1
    while index <= n:        if index > stepSize:
            tmp, arr[index % stepSize] = arr[index % stepSize], arr[(index - 1) % stepSize] * 2 - tmp        else:
            arr[index % stepSize] = arr[(index - 1) % stepSize] * 2
        index += 1
    return arr[(index - 1) % stepSize]

时间复杂度与步长为 1 ~ 2 时相同,为 。因为需要申请空间存储中间状态数据,所以空间复杂度为 O(M),其中 M 表示最大步长。



作者:zhipingChen
链接:https://www.jianshu.com/p/c93ed24932c2


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3355/viewspace-2816243/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-30

  • 博文量
    82
  • 访问量
    620