《计算机程序设计艺术》第一卷 1.1 读书笔记

形式化定义算法(Algorithm)

\quad 算法是“一系列规则的集合”,这些规则产生求解问题所需的一系列操作。若要形式化定义算法,需先形式化定义计算方法(Computational method)。

计算方法(Computational method)的形式化定义

\quad 计算方法可以定义成四元组 ( Q , I , Ω , f ) (Q, I, \Omega, f) (Q,I,Ω,f)。其中 Q ,   I ,   Ω Q, \, I, \, \Omega Q,I,Ω 为集合, f f f 为函数,且 f : Q → Q f:Q\to Q f:QQ

\quad 此外 f f f是在输出状态集合 Ω \Omega Ω 上逐点不动(Pointwise fixed)的,表示对输出状态集合中的每一个状态 q q q,都有 f ( q ) = q f(q)=q f(q)=q

  1. 限定词 pointwise ,指的是“考虑函数 f f f 的每一个值 f ( x ) f(x) f(x) 的性质”。
  2. 这是定义,即对输出集合内的状态 q q q 应用计算规则 f f f 得到的还是它本身。这是因为把 f f f 看成一种能计算答案的机器,在 q q q 已经构成答案的情况下,在其上无论怎么重复应用规则 f f f,得到的仍然是答案 q q q
  3. 这个定义非常重要,表示如果能连续应用计算规则 f f f ,从输入状态 x x x 产生输出状态 x k x_k xk,那么 x k x_k xk 是稳定的。这种情况下 f f f 对于输入状态集 x x x 是收敛的,最终会得到一个“稳定的”结果。

\quad Q Q Q 是计算过程中的所有状态集合, I I I是计算所需的输入集合, Ω \Omega Ω是计算产生的输出集合。 f f f是计算规则。 I ⊆ Q ,   Ω ⊆ Q I \subseteq Q,\,\Omega \subseteq Q IQ,ΩQ

\quad 这里的 f f f 不可以简单理解为程序设计语言里的“函数”,例如 int f(int x) { return x + 1;} I I I 不可以简单理解为“函数输入”, Ω \Omega Ω 同理。
\quad 因为这里的 Q , I , Ω Q, I, \Omega Q,I,Ω 都是“状态”的集合,而 f f f是对这些状态作转换。

\quad 在输入集合 I I I 中的每一个输入 x x x 都会经过计算规则 f f f,产生一串计算序列: x 0 , x 1 , x 2 , x 3 , … x_0, x_1, x_2, x_3, \dots x0,x1,x2,x3,,其中

x 0 = x and ∀ i ≥ 0 , x i + 1 = f ( x i ) x_0 = x\quad \text{and}\quad \forall i \ge 0, x_{i+1}=f(x_i) x0=xandi0,xi+1=f(xi)

\quad 如果在反复运用规则 f f f 的情况下,能够在第 k k k 步找到属于输出集合的状态 x k x_k xk,那就说这个计算序列在 k k k 步停止。或者说计算规则 f f f 以状态 x x x 为输入, x k x_k xk为输出。这里的 k k k 是使得 x k ∈ Ω x_k\in \Omega xkΩ 的最小的正整数。

\quad (假设计算规则能停止)如果 x k ∈ Ω x_k \in \Omega xkΩ,那么 x k + 1 ∈ Ω x_{k+1}\in \Omega xk+1Ω。即, x k + 1 = f ( x k ) = x k x_{k+1}=f(x_k)=x_k xk+1=f(xk)=xk

\quad 只有对输入集合 I I I 中的每一个输入都能停止的计算方法才能叫算法(Algorithm)。


例子:在已知自然数加减法的基础之上定义乘法 f ( ( m , n ) ) = ( m ⋅ n ) f((m, n))=(m\cdot n) f((m,n))=(mn)

  1. Q Q Q 为三元组 ( m , n , a ) (m, n, a) (m,n,a) 所构成的集合,其中 m , n , a ∈ N ∪ ∅ m, n, a\in \mathbb{N}\cup\emptyset m,n,aN

    • ( m , n , ∅ ) (m, n, \emptyset) (m,n,) 称为初始状态,简记为 ( m , n ) (m, n) (m,n)
    • ( ∅ , ∅ , a ) (\emptyset, \emptyset, a) (,,a) 称为输出状态,简记为 ( a ) (a) (a)
  2. I = { ( m , n ) ∣   m , n ∈ N } ⊂ Q I=\{(m, n)|\,m, n \in \mathbb{N}\} \subset Q I={(m,n)m,nN}Q ,

  3. Ω = { ( a ) ∣   a ∈ N } ⊂ Q \Omega=\{(a)|\, a\in\mathbb{N}\} \subset Q Ω={(a)aN}Q

  4. f f f 定义为如下:

    • 对初始状态作转换: f ( ( m , n ) ) = f ( ( m , n , 0 ) ) ; f((m, n))=f((m, n, 0)); f((m,n))=f((m,n,0));
    • 对输出状态作转换: f ( ( a ) ) = ( a ) ; f((a))=(a); f((a))=(a);
    • f ( ( m , n , a ) ) = { ( a ) , if  m = 0 ( m − 1 , n , a + n ) , otherwise f((m, n, a)) = \begin{cases} (a), & \text{if } m=0 \\ (m-1, n, a+n),& \text{otherwise}\end{cases} f((m,n,a))={(a),(m1,n,a+n),if m=0otherwise

可以使用 Python3 编写一个对上面过程的模拟程序:

class State:
    def __init__(self, m, n, ans = None) -> None:
        self.m = m
        self.n = n
        self.ans = ans

    def isInitialState(self) -> bool:
        return self.m is not None and \
               self.n is not None and \
               self.ans is None
    def isFinalState(self) -> bool:
        return self.m is None and \
               self.n is None and \
               self.ans is not None
    def __str__(self) -> str:
        return f"({self.ans})"

def f(state: State):
    if state.isInitialState():
        return f(State(state.m, state.n, 0))
    elif state.isFinalState():
        return state
    else:
        if state.m == 0:
            return f(State(None, None, state.ans))
        else:
            return f(State(state.m-1, state.n, state.ans + state.n))

print(f(State(100, 100))) # 100 * 100


f f f Q Q Q 的约束

\quad 为满足算法的可行性(Effectiveness),需对 f f f Q Q Q 作约束。 f f f 不能是无法实现的计算规则; Q Q Q 不能包含无穷个状态,使得这种计算方法无法在物理层面实现。

…👷…

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值