SlideShare une entreprise Scribd logo
1  sur  47
Chương 3


   Chiến lược giảm-để-trị
   (Decrease-and-conquer)


                            1
Nội dung

1.   Chiến lược giảm-để-trị
2.   Sắp thứ tự bằng phương pháp chèn
3.   Các giải thuật duyệt đồ thị
4.   Sắp xếp tôpô
5.   Giải thuật sinh các hoán vị từ một tập




                                              2
1. Chiến lược thiết kế giải thuật giảm-để-trị
(Decrease-and-conquer)
   Kỹ thuật thiết kế giải thuật giảm-để-trị lợi dụng
    mối liên hệ giữa lời giải cho một thể hiện của
    một bài toán và lời giải cho một thể hiện nhỏ
    hơn của cùng một bài toán.
   Có ba biến thể của chiến lược này.
       Giảm bởi một hằng số (decrease by a constant)
       Giảm bởi một hệ số (decrease by a factor)
       Giảm kích thước của biến (variable size decrease)
   Sắp thứ tự bằng phương pháp chèn (insertion
    sort) là một thí dụ điển hình của chiến lược
    giảm-để-trị.
                                                            3
Chiến lược thiết kế giải thuật giảm-để-trị (tt.)
   Giải thuật tìm ước số chung lớn nhất của 2 số theo công
    thức gcd(m,n) = gcd(n, m mod n) cũng là thí dụ của chiến
    lược giảm-để-trị theo lối giảm kích thước của biến.


Algorithm Euclid(m,n)        Thí dụ: m = 60 và n = 24
/* m,n : two nonnegative
                             2) m = 60 và n = 24
integers m and n */
while n<>0 do                3) m = 24 và n = 12
   r := m mod n;
                             4) m = 12 và n = 0
   m:= n;
   n:= r                     Vậy 12 là ước số chung lớn nhất
endwhile
return m;



                                                               4
Chiến lược thiết kế giải thuật giảm-để-trị (tt.)

   Tại mỗi bước của giải thuật duyệt đồ thị theo
    chiều sâu trước (DFS) hay duyệt theo bề rộng
    trước (BFS), giải thuật đánh dấu đỉnh đã được
    viếng và tiến sang xét các đỉnh kế cận của đỉnh
    đó.
   Hai giải thuật duyệt đồ thị này đã áp dụng kỹ
    thuật giảm-bớt-một (decrease-by-one), một
    trong 3 dạng chính của chiến lược Giảm-để-trị.




                                                      5
2. Sắp thứ tự bằng phương pháp chèn

Ý tưởng :
• Xét một ứng dụng của kỹ thuật “giảm để trị” vào việc sắp
thứ tự một mảng a[0..n-1]. Theo tinh thần của kỹ thuật, ta
giả sử rằng bài toán nhỏ hơn: sắp thứ tự một mảng a[0..n-2]
đã được thực hiện. Vấn đề là phải chèn phần tử a[n-1] vào
mảng con đã có thứ tự a[0..n-2].
• Có hai cách để thực hiện điều này.
    - Một là ta duyệt mảng con đã có thứ tự từ trái sang phải cho
   đến khi tìm thấy phần tử đầu tiên lớn hơn hay bằng với phần
   tử a[n-1] và chèn phần tử a[n-1] vào bên trái phần tử này.
   - Hai là ta duyệt mảng con đã có thứ tự từ phải sang trái cho
   đến khi tìm thấy phần tử đầu tiên nhỏ hơn hay bằng với phần
   tử a[n-1] và chèn phần tử a[n-1] vào bên phải phần tử này.


                                                                    6
2. Sắp thứ tự bằng phương pháp chèn (tt.)
Cách thứ hai thường được chọn:

a[0] ≤ … ≤ a[j] < a[j+1] ≤ … ≤ a[i-1] | a[i] … a[n-1]



 390    → 205                → 182          → 45
 45
 205       390         205            182          182
 182       182         390            205        → 205
 45         45         45             390          235
 235       235         235            235          390



                                                         7
Giải thuật sắp thứ tự bằng phương pháp chèn

 procedure insertion;
 var i; j; v:integer;
 begin
          for i:=2 to N do
          begin
                  v:=a[i]; j:= i;
                  while a[j-1]> v do
                  begin
                     a[j] := a[j-1]; // pull down
                      j:= j-1 end;
                  a[j]:=v;
          end;
 end;

                                                    8
Những lưư ý về giải thuật insertion sort

 • Chúng ta dùng một trị khóa “cầm canh” (sentinel) tại
   a[0], làm cho nó nhỏ hơn phần tử nhỏ nhất trong mảng.
 2. Vòng lặp ngoài của giải thuật được thực thi N-1 lần.
    Trường hợp xấu nhất xảy ra khi mảng đã có thứ tự đảo
    ngược. Khi đó, vòng lặp trong được thực thi với tổng số
    lần sau đây:
    (N-1) + (N-2) + ... + 1 =N(N-1)/2
                 =O(N2)
 Số bước chuyển = N(N-1)/2        Số so sánh = N(N-1)/2
 3. Trung bình có khoảng chừng (i-1)/2 so sánh được thực
    thi trong vòng lặp trong. Do đó, trong trường hợp trung
    bình, tổng số lần so sánh là:
    (N-1)/2 + (N-2)/2 + ... + 1/2 =N(N-1)/4
                                  =O(N2)
                                                              9
Độ phức tạp của sắp thứ tự bằng phương pháp
chèn

Tính chất 1.2: Sắp thứ tự bằng phương pháp chèn
thực thi khoảng N2/2 so sánh và N2/4 hoán vị trong
trường hợp xấu nhất.
Tính chất 1.3: Sắp thứ tự bằng phương pháp chèn
thực thi khoảng N2/4 so sánh và N2/8 hoán vị trong
trường hợp trung bình.
Tính chất 1.4: Sắp thứ tự bằng phương pháp chèn có
độ phức tạp tuyến tính đối với một mảng đã gần có
thứ tự.
                                                     10
3. Các giải thuật duyệt đồ thị

Có nhiều bài toán được định nghĩa theo đối tượng và các kết nối
giữa các đối tượng ấy.

Một đồ thị là một đối tượng toán học mà mô tả những bài toán
như vậy.
Các ứng dụng trong các lãnh vực:

       Giao thông
       Viễn thông
       Điện lực
       Mạng máy tính
       Cơ sở dữ liệu
       Trình biên dịch
       Các hệ điều hành
       Lý thuyết đồ thị
                                                                  11
Một thí dụ


      A



                                       H   I

             B        C       G




                 D        E        J       K




      F


                                   L           M


     Hình 3.1a Một đồ thị thí dụ

                                                   12
Cách biểu diễn đồ thị

Ta phải ánh xạ các tên đỉnh thành những số nguyên trong
tầm trị giữa 1 và V.

Giả sử có tồn tại hai hàm:
 - hàm index: chuyển đổi từ tên đỉnh thành số nguyên
 - hàm name: chuyển đổi số nguyên thành tên đỉnh.

Có hai cách biểu diễn đồ thị:
 - dùng ma trận kế cận
 - dùng tập danh sách kế cận




                                                          13
Cách biểu diễn ma trận kế cận

  A   B    C    D    E F G    H    I J K    L M
                                                   Một ma trận V
A 1   1    1    0    0 1 1    0     0 0 0   0 0
B 1   1    0    0    0 0 0    0     0 0 0   0 0    hàng V cột chứa
C 1   0    1    0    0 0 0    0     0 0 0   0 0    các giá trị Boolean
D 0   0    0    1    1 1 0    0     0 0 0   0 0    mà a[x, y] là true if
E 0   0    0    1    1 1 1    0    0 0 0    0 0    nếu tồn tại một
F 1   0    0    1    1 1 0    0    0 0 0     0 0
                                                   cạnh từ đỉnh x đến
G 1   0    0    0    1 0 1    0    0 0 0     0 0
H 0   0    0    0    0 0 0    1    1 0 0    0 0    đỉnh y và false nếu
I 0   0    0    0    0 0 0    1    1 0 0     0 0   ngược lại.
J 0    0    0   0    0 0 0     0    0 1 1    1 1
K 0   0    0    0    0 0 0    0     0 1 1   0 0    Hình 3.1b: Ma trận kế
L 0    0    0    0    0 0 0    0    0 1 0   1 1    cận của đồ thị ở hình
M 0    0    0   0    0 0 0     0    0 1 0   1 1    3.1a


                                                                           14
Giải thuật
program adjmatrix (input, output);              Lưu ý: Mỗi cạnh tương
const maxV = 50;                                ứng với 2 bit trong ma
var j, x, y, V, E: integer;                     trận: mỗi cạnh nối giữa
  a: array[1..maxV, 1..maxV] of boolean; x và y được biểu diễn
                                                bằng giá trị true tại cả
begin
                                                a[x, y] và a[y, x].
  readln (V, E);
  for x: = 1 to V do /*initialize the matrix */
      for y: = 1 to V do a[x, y]: = false;
  for x: = 1 to V do a[x, x]: = true;
  for j: = 1 to E do
  begin                                        Để tiện lợi giả định rằng
     readln (v1, v2);                          có tồn tại một cạnh nối
     x := index(v1); y := index(v2);           mỗi đỉnh về chính nó.
     a[x, y] := true; a[y, x] := true
   end;
end.
                                                                      15
Cách biểu diễn bằng tập danh sách kế cận

Trong cách biểu diễn này, mọi đỉnh mà nối tới một
đỉnh được kết thành một danh sách kế cận
(adjacency-list ) cho đỉnh đó.

program adjlist (input, output);
const maxV = 100;
type link = ↑node
     node = record v: integer; next: link end;
var j, x, y, V, E: integer;
    t, x: link;
    adj: array[1..maxV] of link;



                                                    16
begin
  readln(V, E);                         Lưu ý: Mỗi cạnh trong đồ
  new(z); z↑.next: = z;                 thị tương ứng với hai nút
  for j: = 1 to V do adj[j]: = z;       trong tập danh sách kế cận.
  for j: 1 to E do                      Số nút trong tập danh sách
  begin                                 kế cận bằng 2|E|.
     readln(v1, v2);
     x: = index(v1); y: = index(v2);
     new(t); t↑.v: = x; t↑.next: = adj[y];
     adj[y]: = t; /* insert x to the first element of
                                    y’s adjacency list */
     new(t); t↑.v = y; t↑.next: = adj[x];
     adj[x]:= t;    /* insert y to the first element of
                                  x’s adjacency list */
   end;
end.
                                                                  17
a   b c     d   e   f    g       h   i       j       k       l       m

f   a   a   f   g   a    e   i       h   k       j       j       j




c           e   f   e    a               l               m       l




b               d   d                    m




g




            Hình 3.1c: Biểu diễn bằng tập danh
            sách kế cận của đồ thị ở hình 3.1
                                                                         18
So sánh hai cách biểu diễn đồ thị
   Nếu biểu diễn đồ thị bằng tập danh sách kế cận, việc
    kiểm tra xem có tồn tại một cạnh giữa hai đỉnh u và v sẽ
    có độ phức tạp thời gian O(V) vì có thể có O(V) đỉnh tại
    danh sách kế cận của đỉnh u.
   Nếu biểu diễn đồ thị bằng ma trận kế cận, việc kiểm tra
    xem có tồn tại một cạnh giữa hai đỉnh u và v sẽ có độ
    phức tạp thời gian O(1) vì chỉ cần xem xét phần tử tại vị
    trí (u,v) của ma trận.
   Biểu diễn đồ thị bằng ma trận kế cận gây lãng phí chỗ
    bộ nhớ khi đồ thị là một đồ thị thưa (không có nhiều
    cạnh trong đồ thị, do đó số vị trí mang giá trị 1 là rất ít)




                                                                   19
Các phương pháp duyệt đồ thị

Duyệt hay tìm kiếm trên đồ thị: viếng mỗi đỉnh/nút
trong đồ thị một cách có hệ thống.

Có hai cách chính để duyệt đồ thị:
 - duyệt theo chiều sâu trước (depth-first-search )
 - duyệt theo chiều rộng trước (breadth-first-search).




                                                     20
Duyệt theo chiều sâu trước
procedure dfs;
 procedure visit(n:vertex);
 begin
    add n to the ready stack;
    while the ready stack is not empty do
        get a vertex from the stack, process it,
        and add any neighbor vertex that has not been processed
to the stack.
        if a vertex has already appeared in the stack, there is no
need to push it to the stack.
    end;
begin
   Initialize status;
   for each vertex, say n, in the graph do
     if the status of n is “not yet visited” then visit(n)
end;
                                                                     21
Tìm kiếm theo chiều sâu trước – biểu diễn
danh sách kế cận (giải thuật đệ quy)
procedure list-dfs;
var id, k: integer;
     val: array[1..maxV] of integer;
 procedure visit (k: integer);
 var t: link;
 begin
  id: = id + 1; val[k]: = id; /* change the status of k
                                 to “visited” */
  t: = adj[k];           / * find the neighbors of the vertex k */
  while t <> z do
  begin
      if val[t ↑.v] = 0 then visit(t↑.v);
      t: = t↑.next
  end
 end;
                                                                     22
begin
  id: = 0;
  for k: = 1 to V do val[k]: = 0; /initialize
                          the status of all vetices */
  for k: = 1 to V do
     if val[k] = 0 then visit(k)
end;

 Ghi chú: Mảng val[1..V] chứa trạng thái của cácđỉnh.
 val[k] = 0 nếu đỉnh k chưa hề được viếng (“not yet visited”),
 val[k] ≠ 0 nếu đỉnh k đã được viếng.
 val[k]: = j nghĩa là đỉnh jth mà được viếng trong quá trình
 duyệt là đỉnh k.


                                                             23
A               A                        A                    A



                                                                      E

                F                        F                    F


A               A                        A                    A

            G                    G                        G               G

        E                  E                       E                  E

F               F                        F                    F


A               A                        A                    A

            G                    G                        G               G

    D   E           D      E                 D     E              D   E

F               F                        F                    F


A               A                        A                    A

        C   G              C     G           B     C      G       B   C   G

    D   E           D      E                 D     E              D   E

F               F                        F                    F
                                                                              24
                    Hình 3.2 Duyệt theo chiều sâu trước
Độ phức tạp của DFS
Như vậy kết quả của DFS trên   Tính chất 3.1.1 Duyệt theo
  đồ thị cho ở hình 3.1a với   chiều sâu trước một đồ
  tập danh sách kế cận cho ở   thị biểu diễn bằng các
  hình 3.1c là                 danh sách kế cận đòi hỏi
          AFEGDCB              thời gian tỉ lệ V+ E.
Lưu ý: thứ tự của các đỉnh
  trong các danh sách kế cận   Chứng minh: Chúng ta
  có ảnh hưởng đến thứ tự      phải gán trị cho mỗi phần
  duyệt của các đỉnh khi áp    tử của mảng val (do đó tỉ
  dụng DFS.                    lệ với O(V)), và xét mỗi
                               nút trong các danh sách
                               kết cận biểu diễn đồ thị
                               (do đó tỉ lệ với O(E)).


                                                       25
DFS – biểu diễn bằng ma trận kế cận

  Cùng một phương pháp có thể được áp dụng cho đồ thị
  được biểu diễn bằng ma trận kế cận bằng cách dùng thủ tục
  visit sau đây:

procedure visit(k: integer);
var t: integer;                       Tính chất 3.1.2 Duyệt theo
begin                                 chiều sâu trước một đồ thị biểu
  id: = id + 1; val[k]: = id;         diễn bằng ma trận kế cận tỉ lệ
  for t: = 1 to V do                  với V2.
     if a[k, t] then
        if val[t] = 0 then visit(t)   Chứng minh: Bởi vì mỗi bit
end;                                  trong ma trận kế cận của đồ thị
                                      đều phải kiểm tra.


                                                                    26
Duyệt theo chiều rộng trước
Khi duyệt đồ thị nếu ta dùng một queue thay vì một stack, ta sẽ
đi đến một giải thuật duyệt theo chiều rộng trước (breadth-first-
search).
procedure bfs;
  procedure visit(n: vertex);
  begin
    add n to the ready queue;
    while the ready queue is not empty do
    get a vertex from the queue, process it, and add any neighbor
    vertex that has not been processed to the queue and
    change their status to ready.
  end;
  begin
    Initialize status;
    for each vertex, say n, in the graph
      if the status of n is “not yet visited” then visit(n)
  end;
                                                                    27
procedure list-bfs;
var id, k: integer; val: array[1..max V] of integer;
 procedure visit(k: integer);
 var t: link;
 begin
  put(k); /* put a vertex to the queue */
  repeat
    k: = get; /* get a vertex from the queue */
    id: = id + 1; val[k]: = id; /* change the status of k to “visited” */
    t: = adj[k];         /* find the neighbors of the vertex k */
    while t <> z do
    begin
       if val[t ↑.v] = 0 then
       begin
          put(t↑.v); val [t↑.v]: = -1    /* change the vertex t↑.v to “ready” */
       end;
       t: = t↑.next
    end
  until queueempty
 end;
                                                                                   28
begin
  id: = 0; queue-initialze;
  for k: = 1 to V do val[k]: = 0; /initialize the
                            status of all vertices */
  for k: = 1 to V do
     if val[k] = 0 then visit(k)
end;

Duyệt theo chiều sâu trước và duyệt theo chiều rộng trước
chỉ khác nhau ở chỗ giải thuật đầu dùng stack và giải thuật
sau dùng hàng đợi. Do đó, độ phức tạp tính toán của DFS và
BFS là như nhau.




                                                          29
I

                            H

        D   D   D   D   D

        E   E   E   E

    G   G   G   G

    B   B   B                           M   M   M

    C   C                               L   L

    F                                   K

A                                   J



Hình 3.3 Nội dung của hàng đợi khi thực hiện BFS




                                                    30
4. Xếp thứ tự tôpô

Các đồ thị có hướng là các đồ thị trong đó các cạnh nối với
các nút có hướng.

            A


                                               H   I
                   B        C       G




                    D        E             J       K



            F

                                           L           M
 Hình 3.4. Một thí dụ về đồ thị có hướng


                                                              31
Thường thì hướng của các cạnh biểu thị mối liên hệ trước
sau (precedence relationship) trong ứng dụng được mô hình
hóa.

Thí dụ, đồ thị có hướng có thể được dùng để mô hình hóa
một đường dây sản xuất (assembly line).

Trong phần này, chúng ta xem xét giải thuật sắp thứ tự topo
(topological sorting)




                                                            32
Lưu ý về cách biểu diễn đồ thị có hướng

   Nếu ta biểu diễn đồ thị có hướng bằng tập danh
    sách kế cận, mỗi cạnh trong đồ thị tương ứng với
    một nút trong tập danh sách kế cận. (mỗi cạnh nối
    từ x đến y được biểu diễn bằng một nút có nhãn y
    được đưa vào danh sách kế cận của đỉnh x)
       Số nút trong tập danh sách kế cận bằng với số cạnh |E|

   Nếu ta biểu diễn đồ thị có hướng bằng ma trận kế
    cận, mỗi cạnh trong đồ thị tương ứng với một bit 1
    trong ma trận kế cận. (mỗi cạnh nối từ x đến y được
    biểu diễn bằng giá trị true tại a[x, y]).


                                                                 33
Xếp thứ tự tôpô
Đồ thị có hướng không chu trình (Directed Acyclic Graph)
Đồ thị có hướng mà không có chu trình được gọi là các đồ
thị có hướng không chu trình (dags).
Tập thứ tự riêng phần và xếp thứ tự tôpô
Cho G là một đồ thị có hướng không chu trình. Xét quan
hệ thứ tự < được định nghĩa như sau:
 u < v nếu có một lối đi từ u đến v trong G.

Quan hệ này có 3 tính chất:
 (1) Với mỗi đỉnh trong V[G], not (u < u). (không phản xạ)
 (2) nếu u < v, thì not( v < u) .        (không đối xứng)
 (3) nếu u < v và v < w, thì u < w.          (Truyền)
Quan hệ < là một quan hệ thứ tự riêng phần.

                                                             34
Xếp thứ tự tôpô


Cho G là một đồ thị có hướng không chu trình. Một
thứ tự tôpô (topological sort)T của G là một thứ tự
tuyến tính mà bảo toàn thứ tự riêng phần ban đầu
trong tập đỉnh V[G].

Nghĩa là: nếu u < v trong V (tức là nếu có một lối đi
từ u đến v trong G), thì u xuất hiện trước v trong thứ
tự tuyến tính T.



                                                         35
A


                                         H   I
               B      C      G




                D      E             J       K



         F

                                     L           M




Các nút trong đồ thị ở hình trên có thể được sắp thứ tự tôpô
theo thứ tự sau:
                J K L M A G H I F E D B C


                                                               36
Phương pháp 1 sắp xếp tôpô
Phương pháp này thực hiện theo kiểu tìm kiếm theo chiều
sâu trước và thêm một nút vào danh sách mỗi khi cần thiết
lấy một nút ra khỏi stack để tiếp tục. Khi gặp một nút
không có nút đi sau thì ta sẽ lấy ra (pop) một phần tử từ
đỉnh stack. Lặp lại quá trình này cho đến khi stack rỗng.
Đảo ngược danh sách này ta sẽ được thứ tự tôpô.

Algorithm:
Start with nodes with no predecessor, put them in the stack.
while the stack is not empty do
  if the node at top of the stack has some successors
  then
      push all its successors onto the stack
  else pop it from the stack and add it to the list.
                                                               37
1              2

                                                        1
                                                        0

                                 4

                            6

                                                            9
                                               8



                    3                      5



                                                    7

            8                     6
        5   5   5            4    4    4        Hình 3.5 Sắp thứ tự tôpô
    3   3   3   3       3   10   10   10 10
    2   2   2   2       2 2 2     2   2 2 2
1   1   1   1   1       1 1 1    1    1 1 1 1   9
7   7   7   7   7       7 7 7    7    7 7 7 7 7 7 7

                                                                       38
Độ phức tạp của giải thuật sắp xếp tô pô
phương pháp 1
   Tính chất: Độ phức tạp tính toán của giải thuật sắp
    xếp tô pô là O(|E|+|V|) nếu đồ thị được diễn tả bằng
    tập danh sách kế cận.

   Chứng minh: Điều này hiển nhiên vì thân của vòng
    lặp while được thực hiện tối đa 1 lần cho mỗi cạnh.
    Và tác vụ khởi tạo stack thì tỉ lệ với số đỉnh của đồ
    thị




                                                            39
Phương pháp 2 sắp thứ tự tô pô

   Ý tưởng: Liên tiếp nhận diện một nút là nút nguồn
    (nút không có nút đi sau) và tháo gỡ nó ra khỏi đồ
    thị cùng với các cạnh đi ra từ nó. Quá trình lặp sẽ
    dừng lại khi không còn nút trong đồ thị. Thứ tự của
    các nút bị xóa bỏ sẽ tạo thành một lời giải của bài
    toán sắp thứ tự tô pô.
   Giải thuật này thể hiện rất rõ chiến lược giảm (một)-
    để-trị.




                                                            40
a              d                         d                 d
                       gỡ a                  gỡ b
     c                             c
                                                    c


           e                  b          e
b                                                          e



                   d
    gỡ c
                                  gỡ d              gỡ e

                   e                         e


Thứ tự tô pô là a, b, c, d, e

                                                               41
Giải thuật của phương pháp 2
Algorithm:
Start with nodes with no predecessor, put them in the queue.
while the queue is not empty do
  remove the front node N of the queue
  for each neighbor node M of node N do
    delete the edge from N to M
    if the node M has no successor then
        add M to the rear of the queue
  endfor
endwhile

Độ phức tạp của giải thuật này là bao nhiêu?




                                                               42
5. Giải thuật sinh các hoán vị
   Cho một tập n phần tử A= {a1,a2,…,an}. Ta muốn sinh ra
    tất cả n! hoán vị của tập ấy.
   Chiến lược Giảm-để-trị có thể có gợi ý gì về giải thuật
    sinh tất cả các hoán vị của một tập n phần tử?
   Bài toán nhỏ hơn một bậc là sinh ra tất cả (n-1)! hoán vị
    cho một tập con n -1 phần tử của tập A nói trên. Giả sử
    bài toán này đã được giải xong, ta có thể giải bài toán
    nguyên thủy bằng cách chèn phần tử còn lại vào tại mỗi
    vị trí trong n vị trí khả hữu của các phần tử trong từng
    hoán vị của tập n -1 phần tử đã sinh.
   Tất cả các hoán vị đạt được bằng cách này sẽ khác biệt
    nhau.

                                                            43
Thí dụ

khởi đầu     1
thêm 2       12     21
             right to left
thêm 3       123 132 312        213 231 321
             right to left      right to left


Để đơn giản, giả sử tập A là một tập hợp các số nguyên từ
  1 đến n. Chúng có thể được hiểu như là tập các chỉ số
  của tập n phần tử {a1,a2,…,an}.




                                                        44
Giải thuật PERM

1. Set j:= 1 and write down the permutation <1>
2. set j:= j+1
3. for each permutation <a1 a2…aj-1> on j-1 elements do
4.   create and list P:=< a1 a2…aj-1j>
5.    for i:= j-1 downto 1 do
6.      set P:= P with the values assigned to positions i
                   and i+1 switched and list P
   // end for loop at step 3
7. if j < n, then go to step 2 else stop.



                                                            45
Độ phức tạp của giải thuật PERM

Tính chất: Độ phức tạp của giải thuật PERM sinh ra tất cả
  các hoán vị của tập n phần tử là n!
Chứng minh:
 Thao tác căn bản: thao tác chèn phần tử còn lại vào một
  hoán vị đã có.
 Với mỗi hoán vị từ tập con n-1 phần tử (gồm tất cả (n-1)!
  các hoán vị này), ta đưa phần tử còn lại vào n vị trí khả
  hữu. Như vậy tổng cọng có n.(n-1)! thao tác chèn phần
  tử còn lại vào một hoán vị đã có.
 Do đó: C(n) = O(n!)

 Nhận xét: Vì n! tăng rất nhanh nên với n chỉ hơi lớn (10
  trở lên), giải thuật cho ra kết quả cực kỳ chậm.


                                                          46
Công thức Stirling

n! xấp xỉ bằng với hàm


                           2 ∏ n (n/e)n

 với e là cơ số logarit tự nhiên (e = 2.71828)




                                                 47

Contenu connexe

Tendances

Tính toán khoa học - Chương 8: Quy hoạch tuyến tính
Tính toán khoa học - Chương 8: Quy hoạch tuyến tínhTính toán khoa học - Chương 8: Quy hoạch tuyến tính
Tính toán khoa học - Chương 8: Quy hoạch tuyến tính
Chien Dang
 
Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)
lieu_lamlam
 
Các phương pháp đếm nâng cao
Các phương pháp đếm nâng caoCác phương pháp đếm nâng cao
Các phương pháp đếm nâng cao
Thế Giới Tinh Hoa
 
Bài giảng kiến trúc máy tính
Bài giảng kiến trúc máy tínhBài giảng kiến trúc máy tính
Bài giảng kiến trúc máy tính
Cao Toa
 
Bai tap xstk b (cap nhat chuong 6 7)
Bai tap xstk b (cap nhat chuong 6 7)Bai tap xstk b (cap nhat chuong 6 7)
Bai tap xstk b (cap nhat chuong 6 7)
Bích Anna
 
Kiến trúc máy tính và hợp ngữ bài 04
Kiến trúc máy tính và hợp ngữ bài 04Kiến trúc máy tính và hợp ngữ bài 04
Kiến trúc máy tính và hợp ngữ bài 04
Nhóc Nhóc
 
Tong hop cau hoi trac nghiem hdh
Tong hop cau hoi trac nghiem hdhTong hop cau hoi trac nghiem hdh
Tong hop cau hoi trac nghiem hdh
Hoat Thai Van
 
Hệ phương trình vi phân tuyến tính
Hệ phương trình vi phân tuyến tínhHệ phương trình vi phân tuyến tính
Hệ phương trình vi phân tuyến tính
Thế Giới Tinh Hoa
 
Ôn tập an toàn thông tin
Ôn tập an toàn thông tinÔn tập an toàn thông tin
Ôn tập an toàn thông tin
Mozzila Rosa
 

Tendances (20)

Kiến trúc máy tính và hợp ngữ bài 05
Kiến trúc máy tính và hợp ngữ bài 05Kiến trúc máy tính và hợp ngữ bài 05
Kiến trúc máy tính và hợp ngữ bài 05
 
Tính toán khoa học - Chương 8: Quy hoạch tuyến tính
Tính toán khoa học - Chương 8: Quy hoạch tuyến tínhTính toán khoa học - Chương 8: Quy hoạch tuyến tính
Tính toán khoa học - Chương 8: Quy hoạch tuyến tính
 
Chuong 3
Chuong 3Chuong 3
Chuong 3
 
Đệ Quy, Quay Lui, Nhánh Cận
Đệ Quy, Quay Lui, Nhánh CậnĐệ Quy, Quay Lui, Nhánh Cận
Đệ Quy, Quay Lui, Nhánh Cận
 
Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)
 
Các phương pháp đếm nâng cao
Các phương pháp đếm nâng caoCác phương pháp đếm nâng cao
Các phương pháp đếm nâng cao
 
biến đổi ma trận ( Transformation matrix)
biến đổi ma trận ( Transformation matrix)biến đổi ma trận ( Transformation matrix)
biến đổi ma trận ( Transformation matrix)
 
Bài giảng kiến trúc máy tính
Bài giảng kiến trúc máy tínhBài giảng kiến trúc máy tính
Bài giảng kiến trúc máy tính
 
Bai tap xstk b (cap nhat chuong 6 7)
Bai tap xstk b (cap nhat chuong 6 7)Bai tap xstk b (cap nhat chuong 6 7)
Bai tap xstk b (cap nhat chuong 6 7)
 
30 bài toán phương pháp tính
30 bài toán phương pháp tính30 bài toán phương pháp tính
30 bài toán phương pháp tính
 
Chuong 04 mach logic
Chuong 04 mach logicChuong 04 mach logic
Chuong 04 mach logic
 
Chuong04
Chuong04Chuong04
Chuong04
 
Kiến trúc máy tính và hợp ngữ bài 04
Kiến trúc máy tính và hợp ngữ bài 04Kiến trúc máy tính và hợp ngữ bài 04
Kiến trúc máy tính và hợp ngữ bài 04
 
Tong hop cau hoi trac nghiem hdh
Tong hop cau hoi trac nghiem hdhTong hop cau hoi trac nghiem hdh
Tong hop cau hoi trac nghiem hdh
 
phương pháp hình thang,Công thức Simpson
phương pháp hình thang,Công thức Simpson phương pháp hình thang,Công thức Simpson
phương pháp hình thang,Công thức Simpson
 
Chuong03
Chuong03Chuong03
Chuong03
 
Hệ phương trình vi phân tuyến tính
Hệ phương trình vi phân tuyến tínhHệ phương trình vi phân tuyến tính
Hệ phương trình vi phân tuyến tính
 
Hinh hoc-affine
Hinh hoc-affineHinh hoc-affine
Hinh hoc-affine
 
Ôn tập an toàn thông tin
Ôn tập an toàn thông tinÔn tập an toàn thông tin
Ôn tập an toàn thông tin
 
Vận tải thế vị - pp giá trị nhỏ nhất
Vận tải thế vị - pp giá trị nhỏ nhấtVận tải thế vị - pp giá trị nhỏ nhất
Vận tải thế vị - pp giá trị nhỏ nhất
 

En vedette

Matrix mult class-17
Matrix mult class-17Matrix mult class-17
Matrix mult class-17
Kumar
 
Exploring Algorithms
Exploring AlgorithmsExploring Algorithms
Exploring Algorithms
Sri Prasanna
 
Chuyên đề nhị thức newton và ứng dụng
Chuyên đề nhị thức newton và ứng dụngChuyên đề nhị thức newton và ứng dụng
Chuyên đề nhị thức newton và ứng dụng
Thế Giới Tinh Hoa
 

En vedette (20)

Giáo trình Phân tích và thiết kế giải thuật - CHAP 7
Giáo trình Phân tích và thiết kế giải thuật - CHAP 7Giáo trình Phân tích và thiết kế giải thuật - CHAP 7
Giáo trình Phân tích và thiết kế giải thuật - CHAP 7
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 4
Giáo trình Phân tích và thiết kế giải thuật - CHAP 4Giáo trình Phân tích và thiết kế giải thuật - CHAP 4
Giáo trình Phân tích và thiết kế giải thuật - CHAP 4
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 8
Giáo trình Phân tích và thiết kế giải thuật - CHAP 8Giáo trình Phân tích và thiết kế giải thuật - CHAP 8
Giáo trình Phân tích và thiết kế giải thuật - CHAP 8
 
Chg 6 do thi
Chg 6 do thiChg 6 do thi
Chg 6 do thi
 
Matrix mult class-17
Matrix mult class-17Matrix mult class-17
Matrix mult class-17
 
Matrix multiplicationdesign
Matrix multiplicationdesignMatrix multiplicationdesign
Matrix multiplicationdesign
 
2-Approximation Vertex Cover
2-Approximation Vertex Cover2-Approximation Vertex Cover
2-Approximation Vertex Cover
 
Exploring Algorithms
Exploring AlgorithmsExploring Algorithms
Exploring Algorithms
 
Giraph Travelling Salesman Example
Giraph Travelling Salesman ExampleGiraph Travelling Salesman Example
Giraph Travelling Salesman Example
 
Chuong 1
Chuong 1Chuong 1
Chuong 1
 
Analysis of Algorithm
Analysis of AlgorithmAnalysis of Algorithm
Analysis of Algorithm
 
Greedy Knapsack Problem - by Y Achchuthan
Greedy Knapsack Problem  - by Y AchchuthanGreedy Knapsack Problem  - by Y Achchuthan
Greedy Knapsack Problem - by Y Achchuthan
 
Quicksort
QuicksortQuicksort
Quicksort
 
Dynamic Programming - Matrix Chain Multiplication
Dynamic Programming - Matrix Chain MultiplicationDynamic Programming - Matrix Chain Multiplication
Dynamic Programming - Matrix Chain Multiplication
 
Tsp branch and-bound
Tsp branch and-boundTsp branch and-bound
Tsp branch and-bound
 
Vertex cover Problem
Vertex cover ProblemVertex cover Problem
Vertex cover Problem
 
Solving travelling salesman problem using firefly algorithm
Solving travelling salesman problem using firefly algorithmSolving travelling salesman problem using firefly algorithm
Solving travelling salesman problem using firefly algorithm
 
Introduction to Approximation Algorithms
Introduction to Approximation AlgorithmsIntroduction to Approximation Algorithms
Introduction to Approximation Algorithms
 
Dynamic Programming - Part 1
Dynamic Programming - Part 1Dynamic Programming - Part 1
Dynamic Programming - Part 1
 
Chuyên đề nhị thức newton và ứng dụng
Chuyên đề nhị thức newton và ứng dụngChuyên đề nhị thức newton và ứng dụng
Chuyên đề nhị thức newton và ứng dụng
 

Similaire à Giáo trình Phân tích và thiết kế giải thuật - CHAP 3

Chuong 2 co so phan tich do phuc tap cua giai thuat - sinh vien 2
Chuong 2   co so phan tich do phuc tap cua giai thuat - sinh vien 2Chuong 2   co so phan tich do phuc tap cua giai thuat - sinh vien 2
Chuong 2 co so phan tich do phuc tap cua giai thuat - sinh vien 2
Hồ Lợi
 
Chap1 new (tran dai's conflicted copy 2013 04-02)
Chap1 new (tran dai's conflicted copy 2013 04-02)Chap1 new (tran dai's conflicted copy 2013 04-02)
Chap1 new (tran dai's conflicted copy 2013 04-02)
Loc Tran
 
Ứng dụng excel_de_giai_qhtt
Ứng dụng excel_de_giai_qhttỨng dụng excel_de_giai_qhtt
Ứng dụng excel_de_giai_qhtt
luxubu2075
 
ThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáNThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáN
guest717ec2
 
Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433
Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433
Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433
Muoivy Wm
 

Similaire à Giáo trình Phân tích và thiết kế giải thuật - CHAP 3 (20)

Chap3 new
Chap3 newChap3 new
Chap3 new
 
05 mat102-bai 2-v1.0
05 mat102-bai 2-v1.005 mat102-bai 2-v1.0
05 mat102-bai 2-v1.0
 
Phân tích một số thuật toán
Phân tích một số thuật toánPhân tích một số thuật toán
Phân tích một số thuật toán
 
Chuong 2 co so phan tich do phuc tap cua giai thuat - sinh vien 2
Chuong 2   co so phan tich do phuc tap cua giai thuat - sinh vien 2Chuong 2   co so phan tich do phuc tap cua giai thuat - sinh vien 2
Chuong 2 co so phan tich do phuc tap cua giai thuat - sinh vien 2
 
Chap1 new (tran dai's conflicted copy 2013 04-02)
Chap1 new (tran dai's conflicted copy 2013 04-02)Chap1 new (tran dai's conflicted copy 2013 04-02)
Chap1 new (tran dai's conflicted copy 2013 04-02)
 
Ứng dụng excel_de_giai_qhtt
Ứng dụng excel_de_giai_qhttỨng dụng excel_de_giai_qhtt
Ứng dụng excel_de_giai_qhtt
 
Lttt b11
Lttt b11Lttt b11
Lttt b11
 
ThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáNThiếT Kế Và đáNh Giá ThuậT ToáN
ThiếT Kế Và đáNh Giá ThuậT ToáN
 
Dientuso Sld
Dientuso SldDientuso Sld
Dientuso Sld
 
12.ma trận và dịnh thức
12.ma trận và dịnh thức12.ma trận và dịnh thức
12.ma trận và dịnh thức
 
Chuong 1 Matlab co ban.pdf
Chuong 1 Matlab co ban.pdfChuong 1 Matlab co ban.pdf
Chuong 1 Matlab co ban.pdf
 
Chuong 1 Matlab co ban.pdf
Chuong 1 Matlab co ban.pdfChuong 1 Matlab co ban.pdf
Chuong 1 Matlab co ban.pdf
 
10 mat102-bai 7-v1.0
10 mat102-bai 7-v1.010 mat102-bai 7-v1.0
10 mat102-bai 7-v1.0
 
Bài giảng xử lý ảnh phát hiện biên và phân vùng ảnh
Bài giảng xử lý ảnh   phát hiện biên và phân vùng ảnhBài giảng xử lý ảnh   phát hiện biên và phân vùng ảnh
Bài giảng xử lý ảnh phát hiện biên và phân vùng ảnh
 
CHƯƠNG 6.pdf
CHƯƠNG 6.pdfCHƯƠNG 6.pdf
CHƯƠNG 6.pdf
 
[Toán kinh tế ứng dụng] Bài 1: Hàm tuyến tính
[Toán kinh tế ứng dụng] Bài 1: Hàm tuyến tính[Toán kinh tế ứng dụng] Bài 1: Hàm tuyến tính
[Toán kinh tế ứng dụng] Bài 1: Hàm tuyến tính
 
05 mat101 bai1_v2.3013101225
 05 mat101 bai1_v2.3013101225 05 mat101 bai1_v2.3013101225
05 mat101 bai1_v2.3013101225
 
Pp do thi va truc giao cap 2
Pp do thi va truc giao cap 2Pp do thi va truc giao cap 2
Pp do thi va truc giao cap 2
 
Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433
Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433
Tai lieu huong_dan_hoc_matlab_danh_cho_mon_xu_ly_anh_rat_hay_2264_7433
 
Dự đoán liên kết trong đồ thị tri thức
Dự đoán liên kết trong đồ thị tri thứcDự đoán liên kết trong đồ thị tri thức
Dự đoán liên kết trong đồ thị tri thức
 

Plus de Nguyễn Công Hoàng (7)

Dieubatngochoem
DieubatngochoemDieubatngochoem
Dieubatngochoem
 
Kruskal algorithm
Kruskal algorithmKruskal algorithm
Kruskal algorithm
 
Lap trinh huong doi tuong voi java tran dinh que
Lap trinh huong doi tuong voi java   tran dinh queLap trinh huong doi tuong voi java   tran dinh que
Lap trinh huong doi tuong voi java tran dinh que
 
Timkiem&sapxep
Timkiem&sapxepTimkiem&sapxep
Timkiem&sapxep
 
Giao trinh ky thuat lap trinh 2
Giao trinh ky thuat lap trinh 2Giao trinh ky thuat lap trinh 2
Giao trinh ky thuat lap trinh 2
 
Phong cách lập trình - Đặng Bình Phương
Phong cách lập trình - Đặng Bình PhươngPhong cách lập trình - Đặng Bình Phương
Phong cách lập trình - Đặng Bình Phương
 
Lời khuyên
Lời khuyênLời khuyên
Lời khuyên
 

Giáo trình Phân tích và thiết kế giải thuật - CHAP 3

  • 1. Chương 3 Chiến lược giảm-để-trị (Decrease-and-conquer) 1
  • 2. Nội dung 1. Chiến lược giảm-để-trị 2. Sắp thứ tự bằng phương pháp chèn 3. Các giải thuật duyệt đồ thị 4. Sắp xếp tôpô 5. Giải thuật sinh các hoán vị từ một tập 2
  • 3. 1. Chiến lược thiết kế giải thuật giảm-để-trị (Decrease-and-conquer)  Kỹ thuật thiết kế giải thuật giảm-để-trị lợi dụng mối liên hệ giữa lời giải cho một thể hiện của một bài toán và lời giải cho một thể hiện nhỏ hơn của cùng một bài toán.  Có ba biến thể của chiến lược này.  Giảm bởi một hằng số (decrease by a constant)  Giảm bởi một hệ số (decrease by a factor)  Giảm kích thước của biến (variable size decrease)  Sắp thứ tự bằng phương pháp chèn (insertion sort) là một thí dụ điển hình của chiến lược giảm-để-trị. 3
  • 4. Chiến lược thiết kế giải thuật giảm-để-trị (tt.)  Giải thuật tìm ước số chung lớn nhất của 2 số theo công thức gcd(m,n) = gcd(n, m mod n) cũng là thí dụ của chiến lược giảm-để-trị theo lối giảm kích thước của biến. Algorithm Euclid(m,n) Thí dụ: m = 60 và n = 24 /* m,n : two nonnegative 2) m = 60 và n = 24 integers m and n */ while n<>0 do 3) m = 24 và n = 12 r := m mod n; 4) m = 12 và n = 0 m:= n; n:= r Vậy 12 là ước số chung lớn nhất endwhile return m; 4
  • 5. Chiến lược thiết kế giải thuật giảm-để-trị (tt.)  Tại mỗi bước của giải thuật duyệt đồ thị theo chiều sâu trước (DFS) hay duyệt theo bề rộng trước (BFS), giải thuật đánh dấu đỉnh đã được viếng và tiến sang xét các đỉnh kế cận của đỉnh đó.  Hai giải thuật duyệt đồ thị này đã áp dụng kỹ thuật giảm-bớt-một (decrease-by-one), một trong 3 dạng chính của chiến lược Giảm-để-trị. 5
  • 6. 2. Sắp thứ tự bằng phương pháp chèn Ý tưởng : • Xét một ứng dụng của kỹ thuật “giảm để trị” vào việc sắp thứ tự một mảng a[0..n-1]. Theo tinh thần của kỹ thuật, ta giả sử rằng bài toán nhỏ hơn: sắp thứ tự một mảng a[0..n-2] đã được thực hiện. Vấn đề là phải chèn phần tử a[n-1] vào mảng con đã có thứ tự a[0..n-2]. • Có hai cách để thực hiện điều này. - Một là ta duyệt mảng con đã có thứ tự từ trái sang phải cho đến khi tìm thấy phần tử đầu tiên lớn hơn hay bằng với phần tử a[n-1] và chèn phần tử a[n-1] vào bên trái phần tử này. - Hai là ta duyệt mảng con đã có thứ tự từ phải sang trái cho đến khi tìm thấy phần tử đầu tiên nhỏ hơn hay bằng với phần tử a[n-1] và chèn phần tử a[n-1] vào bên phải phần tử này. 6
  • 7. 2. Sắp thứ tự bằng phương pháp chèn (tt.) Cách thứ hai thường được chọn: a[0] ≤ … ≤ a[j] < a[j+1] ≤ … ≤ a[i-1] | a[i] … a[n-1] 390 → 205 → 182 → 45 45 205 390 205 182 182 182 182 390 205 → 205 45 45 45 390 235 235 235 235 235 390 7
  • 8. Giải thuật sắp thứ tự bằng phương pháp chèn procedure insertion; var i; j; v:integer; begin for i:=2 to N do begin v:=a[i]; j:= i; while a[j-1]> v do begin a[j] := a[j-1]; // pull down j:= j-1 end; a[j]:=v; end; end; 8
  • 9. Những lưư ý về giải thuật insertion sort • Chúng ta dùng một trị khóa “cầm canh” (sentinel) tại a[0], làm cho nó nhỏ hơn phần tử nhỏ nhất trong mảng. 2. Vòng lặp ngoài của giải thuật được thực thi N-1 lần. Trường hợp xấu nhất xảy ra khi mảng đã có thứ tự đảo ngược. Khi đó, vòng lặp trong được thực thi với tổng số lần sau đây: (N-1) + (N-2) + ... + 1 =N(N-1)/2 =O(N2) Số bước chuyển = N(N-1)/2 Số so sánh = N(N-1)/2 3. Trung bình có khoảng chừng (i-1)/2 so sánh được thực thi trong vòng lặp trong. Do đó, trong trường hợp trung bình, tổng số lần so sánh là: (N-1)/2 + (N-2)/2 + ... + 1/2 =N(N-1)/4 =O(N2) 9
  • 10. Độ phức tạp của sắp thứ tự bằng phương pháp chèn Tính chất 1.2: Sắp thứ tự bằng phương pháp chèn thực thi khoảng N2/2 so sánh và N2/4 hoán vị trong trường hợp xấu nhất. Tính chất 1.3: Sắp thứ tự bằng phương pháp chèn thực thi khoảng N2/4 so sánh và N2/8 hoán vị trong trường hợp trung bình. Tính chất 1.4: Sắp thứ tự bằng phương pháp chèn có độ phức tạp tuyến tính đối với một mảng đã gần có thứ tự. 10
  • 11. 3. Các giải thuật duyệt đồ thị Có nhiều bài toán được định nghĩa theo đối tượng và các kết nối giữa các đối tượng ấy. Một đồ thị là một đối tượng toán học mà mô tả những bài toán như vậy. Các ứng dụng trong các lãnh vực: Giao thông Viễn thông Điện lực Mạng máy tính Cơ sở dữ liệu Trình biên dịch Các hệ điều hành Lý thuyết đồ thị 11
  • 12. Một thí dụ A H I B C G D E J K F L M Hình 3.1a Một đồ thị thí dụ 12
  • 13. Cách biểu diễn đồ thị Ta phải ánh xạ các tên đỉnh thành những số nguyên trong tầm trị giữa 1 và V. Giả sử có tồn tại hai hàm: - hàm index: chuyển đổi từ tên đỉnh thành số nguyên - hàm name: chuyển đổi số nguyên thành tên đỉnh. Có hai cách biểu diễn đồ thị: - dùng ma trận kế cận - dùng tập danh sách kế cận 13
  • 14. Cách biểu diễn ma trận kế cận A B C D E F G H I J K L M Một ma trận V A 1 1 1 0 0 1 1 0 0 0 0 0 0 B 1 1 0 0 0 0 0 0 0 0 0 0 0 hàng V cột chứa C 1 0 1 0 0 0 0 0 0 0 0 0 0 các giá trị Boolean D 0 0 0 1 1 1 0 0 0 0 0 0 0 mà a[x, y] là true if E 0 0 0 1 1 1 1 0 0 0 0 0 0 nếu tồn tại một F 1 0 0 1 1 1 0 0 0 0 0 0 0 cạnh từ đỉnh x đến G 1 0 0 0 1 0 1 0 0 0 0 0 0 H 0 0 0 0 0 0 0 1 1 0 0 0 0 đỉnh y và false nếu I 0 0 0 0 0 0 0 1 1 0 0 0 0 ngược lại. J 0 0 0 0 0 0 0 0 0 1 1 1 1 K 0 0 0 0 0 0 0 0 0 1 1 0 0 Hình 3.1b: Ma trận kế L 0 0 0 0 0 0 0 0 0 1 0 1 1 cận của đồ thị ở hình M 0 0 0 0 0 0 0 0 0 1 0 1 1 3.1a 14
  • 15. Giải thuật program adjmatrix (input, output); Lưu ý: Mỗi cạnh tương const maxV = 50; ứng với 2 bit trong ma var j, x, y, V, E: integer; trận: mỗi cạnh nối giữa a: array[1..maxV, 1..maxV] of boolean; x và y được biểu diễn bằng giá trị true tại cả begin a[x, y] và a[y, x]. readln (V, E); for x: = 1 to V do /*initialize the matrix */ for y: = 1 to V do a[x, y]: = false; for x: = 1 to V do a[x, x]: = true; for j: = 1 to E do begin Để tiện lợi giả định rằng readln (v1, v2); có tồn tại một cạnh nối x := index(v1); y := index(v2); mỗi đỉnh về chính nó. a[x, y] := true; a[y, x] := true end; end. 15
  • 16. Cách biểu diễn bằng tập danh sách kế cận Trong cách biểu diễn này, mọi đỉnh mà nối tới một đỉnh được kết thành một danh sách kế cận (adjacency-list ) cho đỉnh đó. program adjlist (input, output); const maxV = 100; type link = ↑node node = record v: integer; next: link end; var j, x, y, V, E: integer; t, x: link; adj: array[1..maxV] of link; 16
  • 17. begin readln(V, E); Lưu ý: Mỗi cạnh trong đồ new(z); z↑.next: = z; thị tương ứng với hai nút for j: = 1 to V do adj[j]: = z; trong tập danh sách kế cận. for j: 1 to E do Số nút trong tập danh sách begin kế cận bằng 2|E|. readln(v1, v2); x: = index(v1); y: = index(v2); new(t); t↑.v: = x; t↑.next: = adj[y]; adj[y]: = t; /* insert x to the first element of y’s adjacency list */ new(t); t↑.v = y; t↑.next: = adj[x]; adj[x]:= t; /* insert y to the first element of x’s adjacency list */ end; end. 17
  • 18. a b c d e f g h i j k l m f a a f g a e i h k j j j c e f e a l m l b d d m g Hình 3.1c: Biểu diễn bằng tập danh sách kế cận của đồ thị ở hình 3.1 18
  • 19. So sánh hai cách biểu diễn đồ thị  Nếu biểu diễn đồ thị bằng tập danh sách kế cận, việc kiểm tra xem có tồn tại một cạnh giữa hai đỉnh u và v sẽ có độ phức tạp thời gian O(V) vì có thể có O(V) đỉnh tại danh sách kế cận của đỉnh u.  Nếu biểu diễn đồ thị bằng ma trận kế cận, việc kiểm tra xem có tồn tại một cạnh giữa hai đỉnh u và v sẽ có độ phức tạp thời gian O(1) vì chỉ cần xem xét phần tử tại vị trí (u,v) của ma trận.  Biểu diễn đồ thị bằng ma trận kế cận gây lãng phí chỗ bộ nhớ khi đồ thị là một đồ thị thưa (không có nhiều cạnh trong đồ thị, do đó số vị trí mang giá trị 1 là rất ít) 19
  • 20. Các phương pháp duyệt đồ thị Duyệt hay tìm kiếm trên đồ thị: viếng mỗi đỉnh/nút trong đồ thị một cách có hệ thống. Có hai cách chính để duyệt đồ thị: - duyệt theo chiều sâu trước (depth-first-search ) - duyệt theo chiều rộng trước (breadth-first-search). 20
  • 21. Duyệt theo chiều sâu trước procedure dfs; procedure visit(n:vertex); begin add n to the ready stack; while the ready stack is not empty do get a vertex from the stack, process it, and add any neighbor vertex that has not been processed to the stack. if a vertex has already appeared in the stack, there is no need to push it to the stack. end; begin Initialize status; for each vertex, say n, in the graph do if the status of n is “not yet visited” then visit(n) end; 21
  • 22. Tìm kiếm theo chiều sâu trước – biểu diễn danh sách kế cận (giải thuật đệ quy) procedure list-dfs; var id, k: integer; val: array[1..maxV] of integer; procedure visit (k: integer); var t: link; begin id: = id + 1; val[k]: = id; /* change the status of k to “visited” */ t: = adj[k]; / * find the neighbors of the vertex k */ while t <> z do begin if val[t ↑.v] = 0 then visit(t↑.v); t: = t↑.next end end; 22
  • 23. begin id: = 0; for k: = 1 to V do val[k]: = 0; /initialize the status of all vetices */ for k: = 1 to V do if val[k] = 0 then visit(k) end; Ghi chú: Mảng val[1..V] chứa trạng thái của cácđỉnh. val[k] = 0 nếu đỉnh k chưa hề được viếng (“not yet visited”), val[k] ≠ 0 nếu đỉnh k đã được viếng. val[k]: = j nghĩa là đỉnh jth mà được viếng trong quá trình duyệt là đỉnh k. 23
  • 24. A A A A E F F F A A A A G G G G E E E E F F F F A A A A G G G G D E D E D E D E F F F F A A A A C G C G B C G B C G D E D E D E D E F F F F 24 Hình 3.2 Duyệt theo chiều sâu trước
  • 25. Độ phức tạp của DFS Như vậy kết quả của DFS trên Tính chất 3.1.1 Duyệt theo đồ thị cho ở hình 3.1a với chiều sâu trước một đồ tập danh sách kế cận cho ở thị biểu diễn bằng các hình 3.1c là danh sách kế cận đòi hỏi AFEGDCB thời gian tỉ lệ V+ E. Lưu ý: thứ tự của các đỉnh trong các danh sách kế cận Chứng minh: Chúng ta có ảnh hưởng đến thứ tự phải gán trị cho mỗi phần duyệt của các đỉnh khi áp tử của mảng val (do đó tỉ dụng DFS. lệ với O(V)), và xét mỗi nút trong các danh sách kết cận biểu diễn đồ thị (do đó tỉ lệ với O(E)). 25
  • 26. DFS – biểu diễn bằng ma trận kế cận Cùng một phương pháp có thể được áp dụng cho đồ thị được biểu diễn bằng ma trận kế cận bằng cách dùng thủ tục visit sau đây: procedure visit(k: integer); var t: integer; Tính chất 3.1.2 Duyệt theo begin chiều sâu trước một đồ thị biểu id: = id + 1; val[k]: = id; diễn bằng ma trận kế cận tỉ lệ for t: = 1 to V do với V2. if a[k, t] then if val[t] = 0 then visit(t) Chứng minh: Bởi vì mỗi bit end; trong ma trận kế cận của đồ thị đều phải kiểm tra. 26
  • 27. Duyệt theo chiều rộng trước Khi duyệt đồ thị nếu ta dùng một queue thay vì một stack, ta sẽ đi đến một giải thuật duyệt theo chiều rộng trước (breadth-first- search). procedure bfs; procedure visit(n: vertex); begin add n to the ready queue; while the ready queue is not empty do get a vertex from the queue, process it, and add any neighbor vertex that has not been processed to the queue and change their status to ready. end; begin Initialize status; for each vertex, say n, in the graph if the status of n is “not yet visited” then visit(n) end; 27
  • 28. procedure list-bfs; var id, k: integer; val: array[1..max V] of integer; procedure visit(k: integer); var t: link; begin put(k); /* put a vertex to the queue */ repeat k: = get; /* get a vertex from the queue */ id: = id + 1; val[k]: = id; /* change the status of k to “visited” */ t: = adj[k]; /* find the neighbors of the vertex k */ while t <> z do begin if val[t ↑.v] = 0 then begin put(t↑.v); val [t↑.v]: = -1 /* change the vertex t↑.v to “ready” */ end; t: = t↑.next end until queueempty end; 28
  • 29. begin id: = 0; queue-initialze; for k: = 1 to V do val[k]: = 0; /initialize the status of all vertices */ for k: = 1 to V do if val[k] = 0 then visit(k) end; Duyệt theo chiều sâu trước và duyệt theo chiều rộng trước chỉ khác nhau ở chỗ giải thuật đầu dùng stack và giải thuật sau dùng hàng đợi. Do đó, độ phức tạp tính toán của DFS và BFS là như nhau. 29
  • 30. I H D D D D D E E E E G G G G B B B M M M C C L L F K A J Hình 3.3 Nội dung của hàng đợi khi thực hiện BFS 30
  • 31. 4. Xếp thứ tự tôpô Các đồ thị có hướng là các đồ thị trong đó các cạnh nối với các nút có hướng. A H I B C G D E J K F L M Hình 3.4. Một thí dụ về đồ thị có hướng 31
  • 32. Thường thì hướng của các cạnh biểu thị mối liên hệ trước sau (precedence relationship) trong ứng dụng được mô hình hóa. Thí dụ, đồ thị có hướng có thể được dùng để mô hình hóa một đường dây sản xuất (assembly line). Trong phần này, chúng ta xem xét giải thuật sắp thứ tự topo (topological sorting) 32
  • 33. Lưu ý về cách biểu diễn đồ thị có hướng  Nếu ta biểu diễn đồ thị có hướng bằng tập danh sách kế cận, mỗi cạnh trong đồ thị tương ứng với một nút trong tập danh sách kế cận. (mỗi cạnh nối từ x đến y được biểu diễn bằng một nút có nhãn y được đưa vào danh sách kế cận của đỉnh x)  Số nút trong tập danh sách kế cận bằng với số cạnh |E|  Nếu ta biểu diễn đồ thị có hướng bằng ma trận kế cận, mỗi cạnh trong đồ thị tương ứng với một bit 1 trong ma trận kế cận. (mỗi cạnh nối từ x đến y được biểu diễn bằng giá trị true tại a[x, y]). 33
  • 34. Xếp thứ tự tôpô Đồ thị có hướng không chu trình (Directed Acyclic Graph) Đồ thị có hướng mà không có chu trình được gọi là các đồ thị có hướng không chu trình (dags). Tập thứ tự riêng phần và xếp thứ tự tôpô Cho G là một đồ thị có hướng không chu trình. Xét quan hệ thứ tự < được định nghĩa như sau: u < v nếu có một lối đi từ u đến v trong G. Quan hệ này có 3 tính chất: (1) Với mỗi đỉnh trong V[G], not (u < u). (không phản xạ) (2) nếu u < v, thì not( v < u) . (không đối xứng) (3) nếu u < v và v < w, thì u < w. (Truyền) Quan hệ < là một quan hệ thứ tự riêng phần. 34
  • 35. Xếp thứ tự tôpô Cho G là một đồ thị có hướng không chu trình. Một thứ tự tôpô (topological sort)T của G là một thứ tự tuyến tính mà bảo toàn thứ tự riêng phần ban đầu trong tập đỉnh V[G]. Nghĩa là: nếu u < v trong V (tức là nếu có một lối đi từ u đến v trong G), thì u xuất hiện trước v trong thứ tự tuyến tính T. 35
  • 36. A H I B C G D E J K F L M Các nút trong đồ thị ở hình trên có thể được sắp thứ tự tôpô theo thứ tự sau: J K L M A G H I F E D B C 36
  • 37. Phương pháp 1 sắp xếp tôpô Phương pháp này thực hiện theo kiểu tìm kiếm theo chiều sâu trước và thêm một nút vào danh sách mỗi khi cần thiết lấy một nút ra khỏi stack để tiếp tục. Khi gặp một nút không có nút đi sau thì ta sẽ lấy ra (pop) một phần tử từ đỉnh stack. Lặp lại quá trình này cho đến khi stack rỗng. Đảo ngược danh sách này ta sẽ được thứ tự tôpô. Algorithm: Start with nodes with no predecessor, put them in the stack. while the stack is not empty do if the node at top of the stack has some successors then push all its successors onto the stack else pop it from the stack and add it to the list. 37
  • 38. 1 2 1 0 4 6 9 8 3 5 7 8 6 5 5 5 4 4 4 Hình 3.5 Sắp thứ tự tôpô 3 3 3 3 3 10 10 10 10 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 9 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 38
  • 39. Độ phức tạp của giải thuật sắp xếp tô pô phương pháp 1  Tính chất: Độ phức tạp tính toán của giải thuật sắp xếp tô pô là O(|E|+|V|) nếu đồ thị được diễn tả bằng tập danh sách kế cận.  Chứng minh: Điều này hiển nhiên vì thân của vòng lặp while được thực hiện tối đa 1 lần cho mỗi cạnh. Và tác vụ khởi tạo stack thì tỉ lệ với số đỉnh của đồ thị 39
  • 40. Phương pháp 2 sắp thứ tự tô pô  Ý tưởng: Liên tiếp nhận diện một nút là nút nguồn (nút không có nút đi sau) và tháo gỡ nó ra khỏi đồ thị cùng với các cạnh đi ra từ nó. Quá trình lặp sẽ dừng lại khi không còn nút trong đồ thị. Thứ tự của các nút bị xóa bỏ sẽ tạo thành một lời giải của bài toán sắp thứ tự tô pô.  Giải thuật này thể hiện rất rõ chiến lược giảm (một)- để-trị. 40
  • 41. a d d d gỡ a gỡ b c c c e b e b e d gỡ c gỡ d gỡ e e e Thứ tự tô pô là a, b, c, d, e 41
  • 42. Giải thuật của phương pháp 2 Algorithm: Start with nodes with no predecessor, put them in the queue. while the queue is not empty do remove the front node N of the queue for each neighbor node M of node N do delete the edge from N to M if the node M has no successor then add M to the rear of the queue endfor endwhile Độ phức tạp của giải thuật này là bao nhiêu? 42
  • 43. 5. Giải thuật sinh các hoán vị  Cho một tập n phần tử A= {a1,a2,…,an}. Ta muốn sinh ra tất cả n! hoán vị của tập ấy.  Chiến lược Giảm-để-trị có thể có gợi ý gì về giải thuật sinh tất cả các hoán vị của một tập n phần tử?  Bài toán nhỏ hơn một bậc là sinh ra tất cả (n-1)! hoán vị cho một tập con n -1 phần tử của tập A nói trên. Giả sử bài toán này đã được giải xong, ta có thể giải bài toán nguyên thủy bằng cách chèn phần tử còn lại vào tại mỗi vị trí trong n vị trí khả hữu của các phần tử trong từng hoán vị của tập n -1 phần tử đã sinh.  Tất cả các hoán vị đạt được bằng cách này sẽ khác biệt nhau. 43
  • 44. Thí dụ khởi đầu 1 thêm 2 12 21 right to left thêm 3 123 132 312 213 231 321 right to left right to left Để đơn giản, giả sử tập A là một tập hợp các số nguyên từ 1 đến n. Chúng có thể được hiểu như là tập các chỉ số của tập n phần tử {a1,a2,…,an}. 44
  • 45. Giải thuật PERM 1. Set j:= 1 and write down the permutation <1> 2. set j:= j+1 3. for each permutation <a1 a2…aj-1> on j-1 elements do 4. create and list P:=< a1 a2…aj-1j> 5. for i:= j-1 downto 1 do 6. set P:= P with the values assigned to positions i and i+1 switched and list P // end for loop at step 3 7. if j < n, then go to step 2 else stop. 45
  • 46. Độ phức tạp của giải thuật PERM Tính chất: Độ phức tạp của giải thuật PERM sinh ra tất cả các hoán vị của tập n phần tử là n! Chứng minh:  Thao tác căn bản: thao tác chèn phần tử còn lại vào một hoán vị đã có.  Với mỗi hoán vị từ tập con n-1 phần tử (gồm tất cả (n-1)! các hoán vị này), ta đưa phần tử còn lại vào n vị trí khả hữu. Như vậy tổng cọng có n.(n-1)! thao tác chèn phần tử còn lại vào một hoán vị đã có.  Do đó: C(n) = O(n!)  Nhận xét: Vì n! tăng rất nhanh nên với n chỉ hơi lớn (10 trở lên), giải thuật cho ra kết quả cực kỳ chậm. 46
  • 47. Công thức Stirling n! xấp xỉ bằng với hàm 2 ∏ n (n/e)n với e là cơ số logarit tự nhiên (e = 2.71828) 47