BÀI TẬP BÀI 2: GIẢI THUẬT THAM LAM

Bài 71. Một nông dân đang muốn trồng hoa vào khu vườn của mình. Để cho khu vườn trở nên thật màu sắc ông quyết định trồng nhiều loài hoa khác nhau vào khu vườn. Mỗi loài hoa có mội cách trồng khác nhau do đó ông sẽ trồng từng loài hoa vào các ngày liên tiếp nhau. Cháu của ông rất mong chờ được thấy tất cả loài hoa trong khu vườn đều nở hoa trông sẽ tuyệt vời như thế nào. Tuy nhiên mỗi loài hoa lại có thời gian phát triển từ lúc trồng tới lúc nở hoa khác nhau.

Lựa chọn tham lam là trồng cây có thời gian phát triển lâu nhất trước.

Code python

def date_all_flowers_bloom(a):# a is a list of the development time of the flowers
  a.sort(reverse=True)
  k,result,n=1,0,len(a)
  while k<=n:
    if a[k-1]+k>result:
      result=a[k-1]+k
    k+=1
  return result

Bài 72. Anh Lộc làm nghề phụ hồ cho một công ty xây dựng, Anh nhận thấy rằng mỗi loại gạch đều có độ cứng khác nhau. Giả sử rằng viên gạch có độ cứng k chỉ có thể chịu được tối đa k viên gạch khác chồng lên nó, nếu nhiều hơn thì nó sẽ bị vỡ. Anh Lộc muốn lấy gạch và xếp chúng chồng lên nhau thành một chồng gạch cao nhất có thể mà không để vỡ viên gạch nào. Hãy tìm và in ra màn hình xem anh Lộc có thể xếp chồng gạch có độ cao lớn nhất là bao nhiêu.

Lựa chọn tham lam là xếp viên gạch có độ cứng lớn nhất trước.

Code python

def stack_bricks(a):
    a.sort(reverse=True)
    stiffness,k,n=a[0],1,len(a)
    for i in range(1,n):
        stiffness,k=stiffness-1,k+1
        if stiffness>a[i]:
            stiffness=a[i]
        if stiffness==0:
            return k
    return n

Phần bài tập này mình làm trong khóa học của funix dịch từ phần bài tập trong khóa học Data structures and algorithms của coursera. Chú ý phần bài tập này của coursera trả phí mua khóa học thì mới có. Hoặc bạn có thể mua khóa học của funix có dịch sẵn rất tiện lợi và có mentor giúp đỡ.

Link chi tiết bài tập của cousera https://drive.google.com/file/d/1sVmxysl6m9TSlr-ZWX-ifRwVyaPM8M-S/view?usp=sharing

Lab 2.1. Đổi tiền bằng thuật toán tham lam.

Tìm số lượng đồng xu tối thiểu cần thiết để đổi giá trị input (một số nguyên) thành tiền xu với mệnh giá 1, 5 và 10

Lựa chọn tham lam là đổi tờ tiền cần đổi sang các tờ tiền có mệnh giá lớn nhất có thể và nhỏ hơn hoặc bằng tờ tiền cần đổi.

Code python:

def MONEY_CHANGE(m):
    M,R=[10,5,1],[]
    for i in M:
        while m>=i:
            R.append(i)
            m=m-i
        if m==0:
            return (R,len(R))

Ngoài ra ta có thể tối ưu code trên bằng một số phân tích số học như sau.

$m=10.q_1+r_1,r_1=5.q_2+r_2,m=10.q_1+5.q_2+r_2=5(2.q_1+q_2)+r_2$ 

Suy ra số lượng xu đổi ít nhất là $m//10+r_1//5+r_2=m//10+(m\%10)//5+m\%5$

Lab 2.3. Tối đa doanh thu từ vị trí đặt quảng cáo trực tuyến

Bạn có n quảng cáo cần bố trí trên một trang mạng nổi tiếng. Với từng quảng cáo, bạn biết người quảng cáo sẽ sẵn sàng chi trả bao nhiêu tiền cho một cú nhấp chuột vào quảng cáo. Bạn đã thiết lập n vị trí trên trang mạng và ước tính số lượng cú nhấp chuột mỗi ngày vào từng quảng cáo ở mỗi vị trí. Mục tiêu của bạn là phân bổ các quảng cáo ở các vị trí khác nhau để tối đa doanh thu.

Lựa chon tham lam là đưa quảng cáo có số tiền lớn nhất cho một cú nhấp chuột vào vào vị trí có số lượng cú nhấp chuột nhiều nhất.

Code python:

def Maximum_Scalar_Product(A,B):
    result=0
    while len(A)>0:
        am,bm=max(A),max(B)
        result+=am*bm
        A.remove(am)
        B.remove(bm)
    return result

Gọi cặp $(a_i,b_i), i=1,...,n$ lần lượt là giá trị lớn nhất của A và B 

$S=a_i.b_q+a_q.b_j, S'=a_i.b_i+a_q.b_q,S'-S=(a_i-a_q).(b_i-b_q) \geq 0$

Thời gian chạy của thuật toán là $O(n^2)$

Ngoài ra ta có thể quy bài toán trên về bài toán sắp xếp hai dãy.

Lab 2.4. Bạn có trách nhiệm thu thập chữ ký của tất cả những người thuê nhà trong một tòa nhà nào đó. Với mỗi người thuê nhà, bạn biết thời gian họ có mặt ở nhà. Bạn muốn thu thập toàn bộ chữ ký sao cho bạn chỉ cần đến tòa nhà ít lần nhất có thể. Mô hình toán học cho bài toán này như sau: Cho một tập hợp các đoạn trên một đường và mục tiêu của bạn là đánh dấu ít điểm nhất có thể trên một đường sao cho mỗi đoạn chứa ít nhất một điểm.

Mô tả bài toán 

Cho một tập hợp n đoạn $\left \{[𝑎_0, 𝑏_0], [𝑎_1, 𝑏_1], . . . , [𝑎_{𝑛−1}, 𝑏_{𝑛−1}]\right \}$ với các tọa độ số nguyên trên một đường, hãy tìm số điểm m tối thiểu sao cho mỗi đoạn chứa ít nhất 1 điểm. Hay, tìm tập hợp các số nguyên $X$ nhỏ nhất sao cho trên mỗi đoạn $[𝑎_𝑖, 𝑏_𝑖]$ có một điểm $x \in X$ thỏa mãn $a_i  \leq  x \leq b_i.$

Code python

import sys
from collections import namedtuple
Segment=namedtuple('segment','start end')#Segment là đoạn
def optimal_points(Segments):
    points=[]
    Segments.sort(key=lambda x: x[1])
    point=Segments[0].end
    points.append(point)
    for s in Segments:
        if s.start>point:
            point=s.end
            points.append(point) 
    return points
if __name__=='__main__':
    input=sys.stdin.read()
    n,*data=map(int,input.split())
    Segments=list(map(lambda x: Segment(x[0],x[1]),zip(data[::2],data[1::2])))
    points=optimal_points(Segments)
    print(len(points))
    for p in points:
        print(p,end=' ')

Lab 2.5. Tối đa số lượng giải thưởng trong một cuộc thi

Giới thiệu bài toán

Bạn sắp tổ chức một cuộc thi thú vị cho trẻ em. Quỹ giải thưởng bạn có là n chiếc kẹo. Bạn muốn dùng những chiếc kẹo này để trao cho 𝑘 vị trí dẫn đầu trong cuộc thi với điều kiện là vị trí cao hơn sẽ nhận được nhiều kẹo hơn. Để khiến nhiều đứa trẻ vui vẻ nhất có thể, bạn sẽ phải tìm ra giá trị k lớn nhất.

Code python

import sys
def optimal_summands(n):
    summands = []
    l=1
    while n>2*l:
        summands.append(l)
        n,l=n-l,l+1
    summands.append(n)
    return summands
if __name__=='__main__':
    input=sys.stdin.read()
    n=int(input)
    summands=optimal_summands(n)
    print(len(summands))
    for i in summands:
        print(i,end=' ')


Xem tiếp >>

Bài 2: GiẢI THUẬT THAM LAM

$\bullet$ Video coursera.org

1. Định nghĩa (vietjack.com)

 Giải thuật tham lam là giải thuật tìm kiếm, lựa chọn giải pháp tối ưu  địa phương ở mỗi bước hi vọng tìm được giải pháp tối ưu toàn cục.
Tức là lựa chọn giải pháp tốt nhất ở thời điểm hiện tại và sau đó giải quyết bài toán con sinh ra từ lựa chọn đó. Điều này có thể không tối ưu toàn cục vì không xem xét lại các quyết định cũ.

Bài toán con là một bài toán tương tự và có kích thước nhỏ hơn bài toán ban đầu. 

Các thành phần chính của giải thuật tham lam.

+ Rút gọn thành các bài toán con

  • Thực hiện một số bước ban đầu 
  • Rút gọn thành bài toán tương tự nhưng ở dạng nhỏ hơn
  • Ta gọi là bài toán con
+ Nước đi an toàn
  • Một nước đi gọi là an toàn nếu nó phù hợp với một số giải pháp tối ưu
  • Không phải tất cả các bước đi đầu tiên đều là an toàn
  • Thường thì lựa chọn tham lam không an toàn

Một lựa chọn tham lam được gọi là nước đi an toàn nếu có một giải pháp tối ưu phù hợp với lựa chọn này.

Phương pháp tổng quát của giải thuật tham lam.
Bài toánchọn tham lamNước đi an toànBài toán con
  1. Ban đầu lựa chọn một tham lam
  2. Chứng minh nó là một nước đi an toàn
  3. Rút gọn thành một bài toán con
  4. Giải bài toán con 
  5. Lặp lại cho đến khi giải được bài toán
Ưu điểm của giải thuật tham lam (noron.vn)
  • Dễ triển khai giải thuật tham lam cho một bài toán nào đó
  • Dễ phân tích Big-O hơn các giải thuật khác
Nhược điểm của giải thuật tham lam
  • Khó chọn nước đi tham lam
  • Khó chứng minh nước đi tham lam là đúng
  • Hầu như giải thuật tham lam đều không chính xác

2. Ví dụ

Một chiếc ôtô khi đổ đầy bình xăng có thể đi được xa nhất là $L(km).$ Hãy tìm số lần đổ xăng ít nhất để đi từ điểm $A$ đến điểm $B$ biết rằng có $n$ trạm xăng $x_1\leq x_2\leq ...\leq x_n$ dọc theo đường đi từ $A$ đến $B$. Lưu ý không tính số lần đổ xăng ở điểm xuất phát.

Phân tích một số lựa chọn tham lam như sau:

  • Đổ xăng tại trạm xăng gần nhất
  • Đổ xăng tại trạm xăng xa nhất có thể đến được
  • Đi cho tới khi hết xăng và hy vọng có cây xăng để đổ

Theo đề bài yêu cầu tìm số lần đổ xăng ít nhất nên lựa chọn tham lam đổ xăng tại trạm xăng xa nhất có thể đến được là tối ưu.

Giải thuật tham lam cho bài toán đổ xăng
  1. Bắt đầu tại A
  2. Đổ xăng tại trạm xăng xa nhất có thể đến được G
  3. Biến G thành A mới
  4. Đi từ A mới tới B với số lần đổ xăng ít nhất
      $A=x_0 \leq x_1 \leq ... \leq x_n \leq x_{n+1}=B$
$\text{MinReffils}(x,n,L)$
$\text{numReffil } \leftarrow 0, \text{ currentReffil } \leftarrow 0$
$\text{while currentReffil } \leq n:$
    $\text{lastReffil } \leftarrow \text{ currenReffil }$
    $\text{while currenReffil } \leq n \text{ and } x[currenReffil+1]-x[lastReffil] \leq L:$
        $\text{currenReffil } \leftarrow \text{ currenReffil }+1$
        $\text{if currentReffil }== \text{ lastReffil}:$
            $\text{return IMPOSSIBLE}$
        $\text{if currentReffil } \leq n:$
            $\text{numReffil } \leftarrow \text{ numReffil }+1$
$\text{return numReffil}$

Trường hợp cụ thể của bài toán đổ xăng
Một chiếc ôtô khi đổ đầy bình xăng có thể đi được xa nhất là 400km. Hãy tìm số lần đổ xăng ít nhất để đi từ điểm $A$ đến điểm $B$ biết rằng có 4 trạm xăng $x_1<x_2<x_3<x_4$ dọc theo đường đi từ $A$ đến $B$, khoảng cách từ điểm xuất phát tới các trạm xăng và đích lần lượt là 200km,375km,550km,750km,950km. Lưu ý không tính số lần đổ xăng ở điểm xuất phát. 
Code python
Giả sử $A=x_0 \leq x_1 \leq x_2 \leq ... \leq x_n \leq x_{n+1}=B$
def MinRefills(x,n,L):
    numRefills,currentRefill=0,0
    while currentRefill<=n:
        lastRefill=currentRefill
        while currentRefill<=n and x[currentRefill+1]-x[lastRefill]<=L:
            currentRefill+=1
        if lastRefill==currentRefill:
            return IMPOSSIBLE
        if currentRefill<=n:
            numRefills+=1
    return numRefills
x,L=[0,200,375,550,750,950],400
n=len(x)-2
print(MinRefills(x,n,L))

Thời gian chạy của thuật toán trên là O(n). Vì biến currentRefill chạy từ 0 đến n, biến này luôn tăng từ một đơn vị và biến numRefills thay đổi từ 0 đến  lớn nhất là n.

Bài toán phân nhóm

Cho một tập hợp $n$ điểm đã xắp thứ tự $x_1,x_2,...,x_n \in \mathbb{R}$. Hãy tìm cách phân nhóm ít nhất cho $n$ điểm trên với điều kiện bất kỳ 2 điểm nào trong cùng một nhóm có khoảng cách nhỏ hơn hoặc bằng 1.

Giải thuật tham lam cho bài toán phân nhóm

  1. Bắt đầu tại điểm ở ngoài cùng bên trái
  2. Loại bỏ tất cả các điểm nằm trên đường thẳng đơn vị khỏi tập hợp $n$ điểm
  3. Lặp lại quá trình trên điến khi không còn điểm nào trong tập hợp.
      $\text{Giả sử }x_1 \leq x_2 \leq ... \leq x_n$
$\text{PointsCoverSorted }(x_1,x_2,...,x_n)$
$R \leftarrow \left\{ \right\}, i \leftarrow 1$
$\text{while }i \leq n:$
    $[l,r] \leftarrow [x_i,x_i+1]$
    $R \leftarrow R \cup {[l,r]}$
    $i \leftarrow i+1$
    $\text{while } i \leq n \text{ and } x_i \leq r:$
        $i \leftarrow i+1$
$\text{return } R$

Code python

def PointsCoverSorted(x):
    R,i=[],0
    n=len(x)-1
    while i<=n:
        [l,r]=[x[i],x[i]+1]
        R.append([l,r])
        i+=1
        while i<=n and x[i]<=r:
            i+=1
    return len(R)

Thời gian chạy của thuật toán là O(n). 

Bài toán xếp ba lô

Bạn có một chuyến đi bộ đường dài và bạn không biết bao lâu thì tới đích. Vì vậy, để an toàn, bạn cần mang theo đủ thức ăn. Giả sử bạn có một chiếc ba lô có thể đựng được $W(kg)$ thực phẩm và $n$ vật phẩm nặng $w_1,w_2,...,w_n$ với giá trị lần lượt là $v_1,v_2,...,v_n$. Bạn hãy chọn thực phẩm bỏ vào ba lô để mang đi sao cho giá trị là cao nhất.

Giải thuật tham lam cho bài toán xếp ba lô

  1. Chọn i sao cho $\frac{v_i}{w_i}$ lớn nhất
  2. Nếu ba lô đựng được hết vật phẩm này thì lấy hết vật phẩm và quay lại bước 1
  3. Ngược lại thì lấy đủ số kg mà ba lô còn thiếu.
$\text{Knapsack}(W,w_1,v_1,...,w_n,v_n)$
$A \leftarrow [0,0,...,0], V \leftarrow 0$
$\text{Lặp lại n lần:}$
    $\text{Nếu } W=0:$
        $\text{return } (V,A)$
    $\text{Chọn i sao cho } w_i>0 \text{ và } \frac{v_i}{w_i} \text{ lớn nhất}$
    $a \leftarrow min(w_i,W)$
    $V \leftarrow V+a.\frac{v_i}{w_i}$
    $W_i \leftarrow W_i-a,A[i] \leftarrow A[i]+a,W \leftarrow W-a$
$\text{return } (V,A)$

Code python

def knapsack(W,w,v):
    V,n=0,len(w)
    A=[0]*n
    i=1
    while i<=n:
        if W==0:
            return (V,A)
        i_max=0
        for j in range(1,n):
            if v[i_max]*w[j]<=v[j]*w[i_max] and w[j]>0:
                i_max=j
        a=min(w[i_max],W)
        V=V+a*(v[i_max]/w[i_max])
        w[i_max],A[i_max],W=w[i_max]-a,A[i_max]+a,W-a 
        i+=1
    return (V,A)

Thời gian chạy của thuật toán là $O(n^2)$

Xem tiếp >>

BÀI TẬP BÀI 1 TỔNG QUAN VỀ GIẢI THUẬT

$\bullet$ Mình làm bài tập trên codelearn.io 

Bài 1: Viết một hàm xác định xem một số nguyên dương đã cho có phải là số nguyên tố hay không.

Định nghĩa: Số nguyên tố là số tự nhiên lớn hơn 1 không phải là tích của hai số tự nhiên nhỏ hơn.

Phân tích: Giả sử số tự nhiên $n>1$ không phải là số nguyên tố và $n=x.y$ với $x,y$ là hai số tự nhiên lớn hơn 1 và bé hơn n, không mất tính tổng quát ta giả sử $x \leq y$ suy ra $x^2 \leq n$ tức là $x \leq \sqrt{n}$

Từ phân tích trên ta rút ra được nếu $n$ không chia hết cho các số nguyên từ 2 đến $\left \lfloor \sqrt{n} \right \rfloor$ thì $n$ là số nguyên tố.

import sys
def prime_number(n):
    if n<2:
        return 'không phải là số nguyên tố'
    i=2
    while i*i<=n:
        if n%i==0:
            return 'không phải là số nguyên tố'
        i+=1
    return 'là số nguyên tố'
while True:
    try:
        n=int(input('nhập số tự nhiên: '))
        break
    except:
        print(sys.exc_info()[0])
print('{}'.format(n),prime_number(n))

$T(n)=\begin{cases} 2 & \text{ nếu } n<2 \\ 2i & \text{ nếu } n\text{ mod }i=0\\ 2\left\lfloor\sqrt{n}\right\rfloor & \text{ nếu } n\text{ mod }i\neq 0 \end{cases},i=2,3,...,\left \lfloor \sqrt{n} \right \rfloor$

$T(n) \leq 2\sqrt{n} \text{ khi } n\text{ mod }i\neq 0 , \forall i=2,3,...,\left \lfloor \sqrt{n} \right \rfloor$

Suy ra $\frac{T(n)}{\sqrt{n}}$ bị chặn ta viết $T(n)=O(\sqrt{n})$

Chúng ta có thể cải thiện phương pháp này nhanh gấp 2 lần bằng phân tích số học sau, mọi số tự nhiên có thể biểu diễn thành $2k+i,i=0,1,k \in \mathbb{N}$,như vậy để kiểm tra $n$ có phải là số nguyên tố không ta chỉ cần kiểm tra $n$ có chia hết cho 2 hay không sau đó kiểm tra $n$ có chia hết cho tất cả các số có dạng $2k+1 \leq \left \lfloor \sqrt{N} \right \rfloor,k \in \mathbb{Z}^+$.

def is_prime(n):
    if n<=2:
        return n>1
    if n%2==0:
        return False
    i=3
    while i**2<=n:
        if n%i==0:
            return False
        i+=2
    return True

Ta tiếp tục cải tiến phương pháp trên với phân tích như sau, mọi số tự nhiên có thể phân tích thành  $6k+i,i=-1,0,1,2,3,4,$ mà $6k,6k+2,6k+4$ chia hết cho 2 và $6k+3$ chia hết cho 3 nên các số còn lại có dạng $6k \pm 1.$ 

Vậy để kiểm tra $n$ có là số nguyên tố hay không ta chỉ cần kiểm tra $n$ có chia hết cho 2 và 3 hay không sau đó kiểm tra $n$  có chia hết cho tất cả các số có dạng $3 < 6k\pm 1\leq \left \lfloor \sqrt{N} \right \rfloor.$ 

Phương pháp này nhanh hơn gấp 3 lần phương pháp đầu. Mình ước lượng nó bằng cách thực hiện phép tính $\frac{\left \lfloor \sqrt{N} \right \rfloor-5}{3}+1$

import sys
def prime_number(n):
    if n<=3:
        return n>1
    if n%2==0 or n%3==0:
        return False
    i=5
    while i*i<=n:
        if n%i==0 or n%(i+2)==0:
            return False
        i+=6
    return True
while True:
    try:
        n=int(input('nhập vào số tự nhiên n: '))
        break
    except:
        print(sys.exc_info()[0])
print(prime_number(n))

Bài 2: In ra $n$ số nguyên tố đầu tiên.

Bằng cách tổng quát hóa các phân tích số học ở bài trên ta được phương pháp gọi là  sàng Eratosthenes.(wikipedia.org)

def SieveOfEratosthenes(n):
    p=[True]*(n+1)
    i=2
    while i*i<=n:
        if p[i]==True:
            for j in range(i*i,n+1,i):
                p[j]=False
        i+=1
    p[0],p[1]=False,False
    prime=list()
    for i in range(n+1):
        if p[i]==True:
            prime.append(i)
    return prime

Độ phức tạp của thuật toán.

  • Khi $i=2$ vòng lặp trong lặp chạy $\frac{n}{2}$ lần.
  • Khi $i=3$ vòng lặp trong lặp chạy $\frac{n}{3}$ lần.
  • Khi $i=5$ vòng lặp trong lặp chạy $\frac{n}{5}$ lần.
  • Khi $i=p \leq \left \lfloor \sqrt{n} \right \rfloor$ vòng lặp trong vòng lặp chạy $\frac{n}{p}$ lần.
Ta có tổng $n\sum_{p_i\leq \left \lfloor \sqrt{n} \right \rfloor}\frac{1}{p_i},$ một cách phức tạp nào đó mà chebyshev và cộng sự đã xấp xỉ tổng nghịch đảo các số nguyên tố hữu hạn là $\ln\ln(n)$ do đó vòng lặp trên có độ phức tạp là $O(n\ln\ln(n)).$

Bài 3: Phân tích n ra thừa số nguyên tố.

Thuật toán đơn giản nhất mình nghĩ ra là duyệt qua dãy số nguyên tố đã tạo ra ở trên.

def SieveOfEratosthenes(n):
    p,i=[True]*(n+1),2
    while i*i<=n:
        if p[i]==True:
            for j in range(i*i,n+1,i):
                p[j]=False
        i+=1
    p[0],p[1],prime=False,False,list()
    for i in range(n+1):
        if p[i]==True:
            prime.append(i)
    string,i='',0
    while prime[i]<=n:
        if n%prime[i]==0:
            string=string+str(prime[i])+'x'
            n=n/prime[i]
        else:
            i+=1
    if len(string)==0:
        return str(n)
    return string[:-1]

Bài 4: GCPD (Greatest Common Prime Divisor) được định nghĩa là số nguyên tố lớn nhất là ước của các số nguyên dương cho trước. Tìm GCPD của a và b nếu không tồn tại thì return -1

def Greatest_Common_Prime_Divisor(a,b):
    n=min(a,b)
    p,i=[True]*(n+1),2
    while i*i<=n:
        if p[i]==True:
            for j in range(i*i,n+1,i):
                p[j]=False
        i+=1
    p[0],p[1],prime=False,False,list()
    for i in range(n+1):
        if p[i]==True:
            prime.append(i)
    for i in reversed(prime):
        if a%i==0 and b%i==0:
            return i
    return -1
Xem tiếp >>

BÀI 1: TỔNG QUAN VỀ GIẢI THUẬT

PHẦN 1: Giải thuật cơ bản

Bài 1: tổng quan về giải thuật

1. Tổng quan môn học

Trước khi đi vào nội dung chính, chúng ta cần hiểu rõ các khái niệm cơ bản trong cấu trúc dữ liệu và giải thuật và vai trò của nó.
$\bullet$ Video: Giới thiệu môn học cấu trúc dữ liệu và giải thuật (các bạn chọn audit để học miễn phí chứ không mấy bài sau nó không cho học)

Giải thuật(Algorithms) hay thuật toán là một tập hợp hữu hạn các hướng dẫn được xác định rõ ràng, có thể thực hiện bằng máy tính, thường để giải quyết một lớp vấn đề hoặc thực hiện một phép tính.

Đặc điểm của thuật toán

Tính xác định: Thuật toán phải rõ ràng và không mơ hồ. Mỗi một bước phải rõ ràng và chỉ mang một mục đích nhất đinh.

Dữ liệu đầu vào: Một thuật toán phải có 0 hoặc nhiều dữ liệu đầu vào được xác định

Kết quả đầu ra: Một thuật toán phải có 1 hoặc nhiều dữ liệu đầu ra rõ ràng và phù hợp với đầu ra mong muốn.

Tính hữu hạn: Thuật toán phải kết thúc sau một số bước hữu hạn.

Tính khả thi: Một thuật toán phải khả thi với các nguồn lực có sẵn (tài nguyên, thiết bị hiện có)

Độc lập: Một thuật toán nên có hướng dẫn từng bước độc lập với bất kỳ code lập trình nào

Độ phức tạp của thuật toán (wiki, toidicodedao.com)

$\bullet$ Video: Khái niệm Big-O

$\bullet$ Video: Sử dụng Big-O

Độ phức tạp của một thuật toán là 1 hàm phụ thuộc vào độ lớn của dữ liệu đầu vào.
Để ước lượng độ phức tạp của một thuật toán ta thường dùng khái niệm Big-O hoặc Big-Θ.

Big O Notation có thể dùng cho cả thời gian chạy – số lượng câu lệnh chạy, cũng như lượng bộ nhớ mà thuật toán cần sử dụng. Để dễ phân biệt, người ta phân ra thành:

  • Time Complexity: Số lượng câu lệnh phải chạy – thời gian chạy của thuật toán dựa theo lượng phần tử đầu vào
  • Space Complexity: Số lượng bộ nhớ thêm mà thuật toán cần, dựa theo số lượng phần tử đầu vào

Định nghĩa Big-O: Cho $f$ và $g$ là các hàm số dương không giảm trên tập số tự nhiên, tức là $f,g: \mathbb{N} \rightarrow \mathbb{R}^+$ và $c \in \overline{\mathbb{R}^+}$ là điểm giới hạn của $\overline{\mathbb{R}^+}.$ Nếu $\frac{f(x)}{g(x)}$ bị chặn trong lân cận của $c$ thì ta viết $f(x)=O(g(x))$ khi $x \rightarrow c.$
- Ví dụ: Xét $f,g: \mathbb{N} \rightarrow \mathbb{R}^+$ sao cho $f(x)=3x^2+5x+2, g(x)=x^2$, $f(x)=O(g(x))$ khi $x \geq 1$ vì $3x^2+5x+2 \leq 3x^2+5x^2+2x^2=10x^2 \Rightarrow \frac{f(x)}{g(x)} \leq 10.$ 

Định nghĩa. Hàm số $f,g$ xác định trên $\mathbb{N}$ thỏa mãn điều kiện $\lim_{x \rightarrow c}\frac{f(x)}{g(x)}=1$ thì chúng được gọi là những hàm tương đương nhau khi $x \rightarrow c,$ và ký hiệu $f \approx  g$ khi $x \rightarrow c.$
Từ định nghĩa và ví dụ ta có thể coi $x$ như là dữ liệu đầu vào của thuật toán.

Cấu trúc dữ liệu
$\bullet$  Bài đọc: cấu trúc dữ liệu vietjack.com
$\bullet$ Video: Tại sao cần phải học cấu trúc dữ liệu
Cấu trúc dữ liệu là một cách lưu dữ liệu trong máy tính sao cho nó có thể được sử dụng một cách hiệu quả.

 2. Một số bài toán về giải thuật cơ bản

$\bullet$ Định nghĩa: Đệ quy
Trong toán học và khoa học máy tính, một lớp đối tượng hoặc phương thức thể hiện hành vi đệ quy khi nó có thể xác định được bởi hai thuộc tính:
  • Trường hợp cơ sở (hoặc các trường hợp) đơn giản - một kịch bản kết thúc không sử dụng đệ quy để đưa ra câu trả lời
  • Bước đệ quy - một bộ quy tắc giảm tất cả các trường hợp khác đối với trường hợp cơ sở
Trong tin học, đệ quy là phương pháp dùng trong các chương trình máy tính trong đó có một hàm tự gọi chính nó.

$\bullet$ Ví dụ về đệ quy
- Tìm số fibonacci thứ n.
dãy fibonacci có công thức truy hồi là 
$F(n)=\begin{cases}0& \text{ khi } n=0 \\ 1& \text{ khi } n=1 \\F(n-1)+F(n-2)& \text{ khi } x \geq  2 \end{cases}$

import sys
def fibonacci(n):
    if n<=1:
        return n
    else:
        return fibonacci(n-1)+fibonacci(n-2)
while True:
    try:
        n=int(input('nhập vào số tự nhiên n: '))
        if n>=0:
            break
    except:
        print(sys.exc_info()[0])
print('số fibonacci thứ {} là: F({}) ='.format(n,n),fibonacci(n))

Mô phỏng cây đệ quy của hàm fibonacci

Gọi $T(n)$ là số dòng code của hàm fibonacci(n), ta có 

$T(n)=\begin{cases}2 & \text{nếu } n \leq 1 \\ T(n-1)+T(n-2)+3 & \text{nếu } n>1 \end{cases}$

$T(n)=T(n-1)+T(n-2) +3 < 2T(n-1)+3 <...< 2^n+3<2.2^n, \forall n >1$

Suy ra $\frac{T(n)}{2^n}$ bị chặn tức là $T(n)=O(2^n)$ khi $n>1$ 
Ngoài ra ta có thể tính chính xác số dòng code của hàm fibonacci bằng cách đặt  $T(n)=T'(n)-3,$ suy ra $T'(n)=\frac{5}{\sqrt{5}}\left[ \left(\frac{1+\sqrt{5}}{2}\right)^{n+1}-\left(\frac{1-\sqrt{5}}{2}\right)^{n+1}\right]$
Hay là $T(n)=\frac{5}{\sqrt{5}}\left[ \left(\frac{1+\sqrt{5}}{2}\right)^{n+1}-\left(\frac{1-\sqrt{5}}{2}\right)^{n+1}\right]-3$
Ta có thể thấy Big-O là hàm mũ do đó với đầu vào lớn thì thuật toán chạy rất lâu, nên ta cần giảm độ phức tạp của thuật toán xuống.
import sys
def fibonacci(n):
    F=[0]*(n+1)
    F[0]=0
    F[1]=1
    for i in range(2,n+1):
        F[i]=F[i-1]+F[i-2]
    return F[n]
while True:
    try:
        n=int(input('nhập vào số tự nhiên n: '))
        if n>=0:
            break
    except:
        print(sys.exc_info()[0])
print('số fibonacci thứ {} là: F({}) ='.format(n,n),fibonacci(n))
Hàm fibonacci(n) mới này có $T(n)=2n+2$ dòng code nên  $T(n)=O(n)$
Để hình dung $O(2^n)$ lớn hơn $O(n)$ như thế nào ta vẽ đồ thị của chúng 
Bài này còn nhiều khái niệm chưa nhắc đến như ký hiệu $\Omega,\Theta,o$ các bạn có thể tìm hiểu thêm về nó trên giaithuatlaptrinh.github.io


Xem tiếp >>

KHÔNG GIAN BANACH

1. Lịch sử (Banach space)

Không gian Banach được đặt theo tên nhà toán học người  Ba Lan Stefan Banach. Ông cùng với  Hans Hahn và Eduard Helly nghiên cứu và đưa ra khái niệm năm 1920-1922, không gian Banach được phát triển từ nghiên cứu về không gian Hàm của Hilbert, Fréchet và Riesz. Không gian Banach là một trong những đối tượng trung tâm của nghiên cứu về giải tích hàm. 

2. Định nghĩa 

Không gian Banach là không gian định chuẩn đầy đủ (đầy đủ tức là mọi dãy cauchy đều hội tụ)

3. Ví dụ

$\bullet$ các không gian $l_p^n$ là không gian Banach.($l_p^n$ là ký hiệu không gian $\mathbb{R}^n$)
Chứng minh. Giả sử $\{x_n\},x_n=(x_1^{(n)},...,x_n^{(n)})$ là một dãy Cauchy trong $l_p^n$ khi đó
$\forall \varepsilon > 0, \exists n_o \in \mathbb{N},\forall m,n \in \mathbb{N},m,n>n_o$ ta có $\left\|x_n-x_m \right\|< \varepsilon (1) $ 
Vì chuẩn trong không gian $l_p^n$ là tương đương nên ta chỉ xét chuẩn "sup" cho đơn giản
Trong $l_p^n$ ta chọn chuẩn $ \left \| x \right \|_p=sup_{i=1,...,n}(|x_i^{(n)}-x_i^{(m)}|)$
từ (1) suy ra $|x_i^{(n)}-x_i^{(m)}| < \varepsilon,\forall i=1,...,n.$ 
tức là $\lim_{n\rightarrow \infty} x_i^{(n)}=x_i^{(m)},\forall i=1,...,n.$
điều này tương đương với $\lim_{n\rightarrow \infty}x_n=x_m.$
tức là dãy Cauchy ${x_n}$ hội tụ tới $x_m$


 

Xem tiếp >>

KHÔNG GIAN ĐỊNH CHUẨN

 

1. Lịch sử

2. Định nghĩa

Cho $E$ là một không gian vectơ trên trường $F$. Một chuẩn trên $E$ là một hàm $\left \|. \right \|:E \rightarrow \mathbb{R}$ thỏa mãn các điều kiện sau: với mọi $x,y \in E, \lambda  \in F$
    $(N_1)$    $\left \|x \right \| \geq 0,\left \|x \right \|=0 \Leftrightarrow x=0$
    $(N_2)$    $\left \|\lambda x \right \|=\left|\lambda\right|\left \|x \right \|$
    $(N_3)$    $\left \|x+y \right \| \leq \left \|x \right \|+\left \|y \right \|$

3. Một số ví dụ về chuẩn

$\bullet $ Không gian $\mathbb{R}^{n}$. Xét không gian tuyến tính $\mathbb{R}^{n}.$Với mọi $x=(x_1,x_2,...,x_n) \in \mathbb{R}^{n}$ ta định nghĩa
    $\left \|x \right \|_p=\left(\sum_{i=1}^{n}\left|x_i \right|^p\right)^\frac{1}{p}$, là một chuẩn với p không nhỏ hơn 1. và được gọi là chuẩn $l_p^n.$
$\bullet $ Không gian $C[a,b].$ (https://www.youtube.com/watch?v=lChYgNGFZUU&t=129s)
$C[a,b]=\left\{f :[a,b] \rightarrow F:f  \text{ liên tục trên } [a,b]\right\}$ Với mọi $f,g \in C[a.b] \text{ và  mọi }\alpha \in F$ ta định nghĩa
    $(f+g)(t)=f(t)+g(t),   (\alpha f)(t)=\alpha f(t),  \text{với mọi } t \in [a,b]$
Thế thì có  $f+g,\alpha f \in C[a,b]$
Ta nói $f=g \text{ nếu } f(t)=g(t) \forall t \in [a,b]$
Ta kiểm tra $C[a,b]$ có là không gian tuyến tính hay không
Chú ý: việc kiểm tra các tiên đề là đơn giản tuy nhiên nó không tầm thường rất dễ hiểu nhầm.
Với mọi $f,g,k \in C[a.b] \text{ và  mọi }\alpha ,\beta \in F$
Kiểm tra tiên đề 1: $(f+g)(t)\overset{\underset{\mathrm{def}}{}}{=}f(t)+g(t)\overset{\underset{\mathrm{2}}{}}{=}g(t)+f(t)\overset{\underset{\mathrm{def}}{}}{=}(g+f)(t), \forall t \in [a,b]$
(dấu bằng thứ nhất là do định nghĩa của C[a,b], dấu bằng thứ hai là do định nghĩa của trường.
Suy ra $f+g=g+f$.
Kiểm tra tiên đề 2: $f(t)+(g+k)(t)\overset{\underset{\mathrm{def}}{}}{=}f(t)+g(t)+k(t)\overset{\underset{\mathrm{def}}{}}{=}(f+g)(t)+k(t)$
Suy ra $[f+(g+k)](t)=[(f+g)+k](t)$ hay $f+(g+k)=(f+g)+k$
Kiểm tra tiên đề 3: Xét hàm $g(t)=0,\forall t \in [a,b],g \in C[a,b]$
$(f+g)(t)=f(t)+g(t)=g(t)+f(t)=f(t)$
Suy ra $f+g=g+f=f$   
Kiểm tra tiên đề 4: Xét hàm $k(t)=0,\forall t \in [a,b],g(t)=-f(t),\forall t\in [a,b],g,k \in C[a,b]$
(chú ý: giả sử hàm f liên tục trên [a,b] ta cần chứng minh g liên tục trên [a,b],có thể gọi trực tiếp hàm -f thay vì gọi hàm $g=-f$)
$(f+g)(t)=f(t)+g(t)=f(t)+(-f(t))=0=k(t)$
Suy ra $f+g=f+(-f)=k$ (hàm k gọi là hàm đồng nhất không)
Kiểm tra tiên đề 5: $[(\alpha \beta)f](t)=(\alpha \beta)f(t)=\alpha(\beta f(t))=\alpha(\beta f)(t)=[\alpha(\beta f)](t)$
Suy ra $(\alpha \beta)f=\alpha(\beta f)$
Kiểm tra tiên đề 6: $[(\alpha+\beta)f](t)=(\alpha+\beta)f(t)=\alpha f(t)+\beta f(t)=(\alpha f)(t)+(\beta f)(t)=(\alpha f+\beta f)(t)$
Suy ra $(\alpha+\beta)f=(\alpha f+\beta f)$
Kiểm tra tiên đề 7: $[\alpha (f+g)](t)=\alpha (f+g)(t)=\alpha [f(t)+g(t)]=\alpha f(t)+\alpha g(t)=(\alpha f)(t)+(\alpha g)(t)=(\alpha f+\alpha g)(t)$
Suy ra $\alpha (f+g)=\alpha f+\alpha g$
Kiểm tra tiên đề 8: $(1.f)(t)=1.f(t)=f(t)$
Suy ra $1.f=f$ (chú ý phần tử đơn vị của trường các số thì là số 1, còn các trường khác có thể không phải là số 1)
Vậy $C[a,b]$ là một không gian tuyến tính trên trường F.
Ta định nghĩa $\left \| f \right \|_p=\left ( \int_{a}^{b}\left | f(t) \right|^p dt \right )^{\frac{1}{p}},p \geq 1$. Là một chuẩn.
Với $p=1, \left \| f \right \|_1= \int_{a}^{b}\left | f(t) \right| dt $
Kiểm tra $(N_1)$: Ta có $-\left | f(t) \right | \leq f(t) \leq \left | f(t) \right |, \forall t \in [a,b],f \in C[a,b]$
Suy ra $\int_{a}^{b}-\left | f(t) \right |dt \leq \int_{a}^{b}f(t)dt \leq \int_{a}^{b}\left | f(t) \right |dt$
Hay $-\int_{a}^{b}\left | f(t) \right |dt \leq \int_{a}^{b}f(t)dt \leq \int_{a}^{b}\left | f(t) \right |dt$
Vì $\left |a \right| \leq b \Leftrightarrow -b\leq a \leq b.$ Nên   $\left|\int_{a}^{b}f(t)dt \right| \leq \int_{a}^{b}\left | f(t) \right |dt$
Suy ra $\int_{a}^{b}\left | f(t) \right |dt \geq 0,\forall t \in[a,b]$ Hay $\left \| f \right \|_1 \geq 0$
$(\Leftarrow )$ giả sử $f(t)=0,\forall t \in [a,b]$. Khi đó $\left \| f \right \|_1= \int_{a}^{b}\left | f(t) \right| dt = \int_{a}^{b}\left | 0 \right| dt =0 \int_{a}^{b}1dt =0(b-a)=0 $
$(\Rightarrow )$ giả sử $\left \| f \right \|_1=0$. Ta chia $[a,b]$ thành n khoảng $ x_0 \equiv a < x_1<...<x_n\equiv b$ 
đặt $\Delta x_i=x_i-x_{i-1}(i=1,...,n)$, trong mỗi khoảng nhỏ $[x_{i-1},x_i]$ lấy một điểm $t_i$ tùy ý: $x_{i-1} \leq t_i \leq x_i,i=1,...,n$. Khi đó  $\left \| f \right \|_1=\int_{a}^{b}\left | f(t) \right| dt=\lim_{n\rightarrow \infty}\sum_{i=1}^{n}\left | f(t_i) \right |\Delta x_i=\lim_{n\rightarrow \infty }0=0$
Suy ra $\sum_{i=1}^{n}\left | f(t_i) \right |\Delta x_i=0$. Mà $\Delta x_i > 0,$ do đó $\sum_{i=1}^{n}\left | f(t_i) \right| \Delta x_i=0 \Leftrightarrow \sum_{i=1}^{n} \left| f(t_i) \right| =0\Leftrightarrow f(t_i)=0 (t_i \in [a,b],\forall i=1,...,n)$
Do vậy $\left \| f \right \|_1 = 0 \Leftrightarrow f=0 $
Kiểm tra $(N_2)$: $\left \| \alpha f \right \|_1=\int_{a}^{b}\left|(\alpha f)(t)\right|dt=\int_{a}^{b}\left|\alpha f(t)\right|dt=\left|\alpha\right|\int_{a}^{b}\left|f(t)\right|dt=\left|\alpha\right| \left \| f \right \|_1$
Kiểm tra $(N_3)$: $\left \| f+g \right \|_1=\int_{a}^{b}\left | (f+g)(t) \right |dt=\int_{a}^{b}\left | f(t)+g(t) \right |dt \leq \int_{a}^{b}\left | f(t) \right |dt+\int_{a}^{b}\left | g(t) \right |dt$ (theo bất đẳng thức Minkowski dưới dạng tích phân)
Với $p=2,\left \| f \right \|_2=\sqrt{\int_{a}^{b}\left | f(t) \right |^2dt}$
Kiểm tra tương tự trường hợp $p=1$
Với $p\rightarrow \infty$ đặt $t_i = argsup_{t \in [a,b]} \left |f(t)\right|,(t_i \text{ là chỉ số để f(t) là cận trên tức là }f(t_i) \text{ là cận trên )}. $ Khi đó $\left \| f \right \|_p =\left( \int_{a}^{b}\left | f(t) \right |^p dt \right)^\frac{1}{p}=\left ( \lim_{n\rightarrow \infty } \sum_{i=1}^{n} \left | f(t_i) \right |^p \Delta x_i \right )^\frac{1}{p}= \left | f(t_i) \right |\left [ \left ( 1+\left | \frac{f(t_1)}{f(t_i)} \right |^p +...+ \left | \frac{f(t_n)}{f(t_i)}\right |^p+... \right )\Delta x_i \right ]^\frac{1}{p}$  
Ta thấy $\lim_{p\rightarrow \infty}\left [ \left ( 1+\left | \frac{f(t_1)}{f(t_i)} \right |^p +...+ \left | \frac{f(t_n)}{f(t_i)}\right |^p+... \right )\Delta x_i \right ]^\frac{1}{p}=1$
$\left \| f \right \|_\infty = \left|f(t_i)\right |=sup_{t \in [a,b]}\left|f(t)\right |$
$(N_1),(N_2)$ kiểm tra tương tự, 
$\bullet $ Các không gian dãy bị chặn $c_o,l_{\infty},l_p(p\geq 1).$ Ta ký hiệu $\mathbb{K}^\mathbb{N}$ là tập hợp tất cả dãy số thực hay phức. (https://en.wikipedia.org/wiki/Sequence_space#c,_c0_and_c00)
$c_o = \left\{ (x_1,x_2,...) \in \mathbb{K}^\mathbb{N} : \lim_{n\rightarrow \infty}x_n=0  \right\}.$ (tập hợp các dãy số hội tụ tới không)  
$l_\infty=\left\{(x_1,x_2,...) \in \mathbb{K}^{\mathbb{N}}: sup_n \left| x_n \right| < \infty \right\}.$ 
 $l_p = \left\{ (x_1,x_2,...) \in \mathbb{K}^\mathbb{N} : \lim_{n\rightarrow \infty}x_n < \infty  \right\}.$
Với $x = (x_1,x_2,...),y = (y_1,y_2,...) \in c_o$ (hoặc $l_\infty, l_p$) và $\alpha \in F$ ta định nghĩa $x+y = (x_1+y_1,x_2+y_2,...)$ và $\alpha x=(\alpha x_1,\alpha x_2,...).$
Từ định nghĩa ta thấy ngay nếu $x,y \in c_o$ (hoặc $l_\infty$) và $\alpha \in F$ thì $x+y \in c_o$ (hoặc $l_\infty$). Dễ ràng nhưng không tầm thường, kiểm tra được với 2 phép toán này $c_o$ và $l_\infty$ là các không gian tuyến tính.
Nếu $x,y \in l_p$ và $\alpha \in F$ thì rõ ràng $\alpha x \in l_p.$ Với mọi $n \in \mathbb{N}$ ta có
$\left|x_n+y_n \right| \leq \left|x_n \right|+\left|y_n\right| \leq 2 max \left\{ \left|x_n \right|,\left|y_n\right| \right\}.$
Cho nên
$\left|x_n+y_n \right|^p \leq 2^p [max \{ |x_n|,|y_n|\}]^p \leq 2^p(|x_n|^p+|y_n|^p).$
Vì vậy
$\sum_{n=1}^\infty|x_n+y_n|^p \leq 2^p (\sum_{n=1}^\infty |x_n|^p + \sum_{n=1}^\infty |y_n|^p) <\infty .$
Tức là $x+y \in l_p.$ Với hai phép toán trên, dễ kiểm tra $l_p$ là một không gian tuyến tính.
Dễ ràng kiểm tra $c_o,l_{\infty},l_p(p\geq 1).$ là các không gian định chuẩn. $c_o,l_{\infty}$ có chuẩn là $\|x\|=sup_n |x_n|$. $l_p,p \geq 1$ có chuẩn là $\|x\|=(\sum_{n=1}^\infty |x_n|^p)^\frac{1}{p}.$

4. Sự hội tụ trong không gian định chuẩn


Xem tiếp >>

KHÔNG GIAN MÊTRIC

 

1. Lịch sử

Năm 1906 Maurice Fréchet giới thiệu về không gian mêtric trong cuốn Sur quelques points du calcul fonctionnel

2. Định nghĩa

Không gian mêtric ký hiệu là (M,d) trong đó M là một tập hợp và d là một mêtric trên M, tức là một hàm 
    $d:M\times M\rightarrow\mathbb{R}$
sao cho với mọi $x,y,z\in M$ thỏa mãn:
    1. $d(x,y) \geq 0$
    2. $d(x,y) = 0 \Leftrightarrow  x=y$
    3. $d(x,y)=d(y,x)$
    4. $d(x,z) \leq d(x,y)+d(y,z)$

3. Một số mêtric thường dùng

cho $x=(x_1,x_2,...,x_n),y=(y_1,y_2,...,y_n)\in \mathbb{R}^{n}$
ta định nghĩa $d_p(x,y)=(\sum_{i=1}^{n}(\left|x_i-y_i \right|)^p)^\frac{1}{p}$
Với  $p=1$ chúng ta có $d_1(x,y)=\left|x_1-y_1\right|+....+\left|x_n-y_n\right|$
khi đó $d_1(x,y)=\left|x_1-y_1\right|+....+\left|x_n-y_n\right|$ là một mêtric vì thỏa mãn 4 điều kiện của mêtric và còn gọi là mêtric Taxicab
với mọi $x,y,z \in \mathbb{R}^n$
kiểm tra điều kiện 1, $\left|x_1-y_1\right|+....+\left|x_n-y_n\right| \geq 0$ (theo định nghĩa trị tuyệt đối) 
                               $\Leftrightarrow d_1(x,y) \geq 0$
kiểm tra điều kiện 2, $d_1(x,y)=0$ 
                               $\Leftrightarrow  \left|x_1-y_1\right|+....+\left|x_n-y_n\right| = 0$
                               $\Leftrightarrow  \begin{cases}\left|x_1-y_1\right|=0\\ \vdots \\ \left|x_n-y_n\right|=0 \end{cases} $
                               $\Leftrightarrow  \begin{cases}x_1=y_1\\ \vdots \\x_n=y_n \end{cases} $
                               $\Leftrightarrow x=y $
kiểm tra điều kiện 3, $d_1(x,y)=\sum_{i=1}^{n}\left|x_i-y_i \right|=\sum_{i=1}^{n}\left|-(x_i-y_i \right)|=\sum_{i=1}^{n}\left|y_i-x_i \right|=d_1(y_i,x_i)$
kiểm tra điều kiện 4, $d_1(x,z)=\sum_{i=1}^{n}\left|x_i-z_i \right|=\sum_{i=1}^{n}\left|x_i-y_i+y_i-z_i \right| \leq \sum_{i=1}^n \left|x_i-y_i \right|+ \sum_{i=1}^{n} \left|y_i-z_i \right|$
                                $\Leftrightarrow d_1(x,z) \leq d_1(x,y)+d_1(y,z)$
Với $p=2$ chúng ta có $d_2(x,y)=\sqrt{\sum_{i=1}^n \left|x_i-y_i \right|^2}$
khi đó $d_2(x,y)=\sqrt{\sum_{i=1}^n \left|x_i-y_i \right|^2}$ là một mêtric vì thỏa mãn 4 điều kiện của mêtric và được gọi là mêtric Euclidean hay khoảng cách Euclidean.
với mọi $x,y,z \in \mathbb{R}^n$
kiểm tra điều kiện 1, $\left|x_i-y_i \right|^2 \geq 0,\forall x_i,y_y \in \mathbb{R},i=1,...,n$
                                 $\Leftrightarrow \sqrt{\sum_{i=1}^n \left|x_i-y_i \right|^2} \geq 0$
kiểm tra điều kiện 2, $d_2(x,y)=0$
                                 $\Leftrightarrow\sqrt{\sum_{i=1}^n \left|x_i-y_i \right|^2}=0$
                                 $\Leftrightarrow \sum_{i=1}^n \left|x_i-y_i \right|^2=0$
                                 $\Leftrightarrow \begin{cases}\left|x_1-y_1\right|^2=0\\ \vdots \\ \left|x_n-y_n\right|^2=0 \end{cases}$
                                 $\Leftrightarrow \begin{cases}x_1=y_1\\ \vdots \\ x_n=y_n \end{cases}$
                                 $\Leftrightarrow x=y$
kiểm tra điều kiện 3, $d_2(x,y)=\sqrt{\sum_{i=1}^n \left|x_i-y_i \right|^2}=\sqrt{\sum_{i=1}^n \left|-(x_i-y_i)\right|^2}=\sqrt{\sum_{i=1}^n \left|y_i-x_i \right|^2}=d_2(y,x)$
kiểm tra điều kiện 4, $\sqrt{\sum_{i=1}^n \left|x_i-z_i \right|^2}=\sqrt{\sum_{i=1}^n \left|x_i-y_i+y_i-z_i \right|^2} \leq \sqrt{\sum_{i=1}^n \left|x_i-y_i \right|^2}+\sqrt{\sum_{i=1}^n \left|y_i-z_i \right|^2}$ (áp dụng bất đẳng thức Minkowski)
Với $p \rightarrow \infty$, giả sử $i=arg max_{j=1,...,n} \left|x_j-y_j \right|$. Khi đó:
$d_p(x,y)=\left| x_i-y_i \right|\left(1+\left|\frac{x_1-y_1}{x_i-y_i} \right|^p+...+\left|\frac{x_{i-1}-y_{i-1}}{x_i-y_i} \right|^p+\left|\frac{x_{i+1}-y_{i+1}}{x_i-y_i} \right|^p+...+\left|\frac{x_n-y_n}{x_i-y_i} \right|^p\right)^{\frac{1}{p}}$
Ta thấy $\lim_{p \rightarrow \infty}\left(1+\left|\frac{x_1-y_1}{x_i-y_i} \right|^p+...+\left|\frac{x_{i-1}-y_{i-1}}{x_i-y_i} \right|^p+\left|\frac{x_{i+1}-y_{i+1}}{x_i-y_i} \right|^p+...+\left|\frac{x_n-y_n}{x_i-y_i} \right|^p\right)=1$
Nên $d_{\infty}(x,y)=\lim_{p \rightarrow \infty}d_p(x,y)=\left| x_i-y_i \right|=max_{j=1,...,n}\left| x_j-y_j\right|$

Xem tiếp >>

Bài 6: NGĂN XẾP VÀ HÀNG ĐỢI

 1. Ngăn xếp. Định nghĩa Ngăn xếp: Là một loại dữ liệu trừu tượng và các thao tác có thể dùng: Push(data): Thêm data vào ngăn xếp Top(): Tìm...