1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Chương trình đối xứng và thuận thế thu gọn

12 1,3K 5
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Chương trình đối xứng và thuận thế thu gọn
Tác giả Nguyễn Xuân Huy
Trường học Trường Đại Học
Thể loại bài viết
Định dạng
Số trang 12
Dung lượng 65,5 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Chương trình đối xứng và thuận thế thu gọn

Trang 1

Chương trình đối xứng và thuận thế thu gọn

Nguyễn Xuân Huy

Giả sử ta có chương trình P xử lýdữ liệu theo một trật tự T nào đó Giả sử với một trật tự

T nói trên, chươngtrình P biến đổi dữ liệu vào X thành dữ liệu ra Y Thử hỏi, liệu ta có thể xâydựng một chương trình P thực hiện theo trật tự T để biến đổi Y thành x

đượckhông Trong một số trường hợp, điều này là có thể và chương trình P xây dựngtheo phương pháp trên được gọi là chương trình đối xứng với chương trình P

Bài 1 Cho a= (a1,a2, ,aN) là một hoán vị của dãy số tựnhiên 1 N Ta xây dựng dãy

b=(b1,b2, ,bN)và gọi là thuận thế của hoán vị a như sau:

Với mọi i=1 N, bi là số lượngcác phần tử nhỏ thua ai và đứng trước ai

Thí dụ, với N= 7;a=(6,1,3,5,7,4,2) ta có thuận thế của a là b= (0,0,1,2,4,2,1)

a) ChoN và một hoán vị a Hãy tìm thuận thế của a

b) ChoN và một thuận thế b Hãy tìm hoán vị sinh ra thuận thế b

Bài giải

a) Giảsử ta có một hoán vị a[1 N] của 1 N Dễ thấy rằng với mọi i=1 N, để tínhb[i] ta chỉ việc đếm số lượng các phần tử đứng trước a[i] và nhỏ thua a[i]

{Cho hoan vi (HV) tim thuan the(TT) Phuong an 1}

Procedure HVTT (var a, b: mang);

var i: word;

begin

for i:= 1 to N do

begin

b[i] := 0;

for j:= 1 to i-1 do

if a[j] < then>

Trang 2

inc (b[i]);

end;

end;

Tuy nhiên theo cách này chúng tasẽ gặp đôi chút khó khăn trong việc giải câu b) Ta thử tìm lời giải khác

Xét dãy n số tự nhiên 1, 2, ,n Ta gọi dãy này là hoán vị đơn vị Ta để ýrằng với mỗi số i trong dãy trên sẽ có i - 1 phần tử đứng trước i và nhỏ hơn i.Nói cách khác, thuận thế của hoán vị đơn vị chính là dãy 0,1, ,(n-1) Bây giờ ta xét một hoán vị tuỳ ý a[1 n].Để ý rằng với mỗi j=1 n, a[i] cho biết trong hoán vị đơn vị sẽ có a[j] -1 phầntử nhỏ hơn và đứng trước nó Thế thì mỗi khi có a[i] trong hoán vị trên nhỏ hơna[j] và đứng bên phải a[j] thì a[j] chỉ còn a[j] - 2 phần tử nhỏ hơn nó và đứngtrước nó Nhận xét này dẫn đến thuật toán xác định thuận thế của một hoán vị nhưsau:

Lần lượt duyệt ngược từ i=n đến1

Với mỗi j từ 1 đến i xét: nếua[j] ≥ a[i] thì giảm a[j] đi 1 đơn vị

Thuật toán này sửa hoán vị a[1 n]thành thuận thế a[1 n] nên được gọi là thuật toán xử lý tại chỗ Nó không đòihỏi mảng phụ

(* Cho hoan vi a [1 n], sinhthuan the a[1 n] *)

Procedure HVTT;

var i,j: word;

begin

for i:= n downto 1 do

for j:= 1 to i do

if a[j] >= a[i] then

dec (a[j]); end;

Điểm lợi của thuật toán này làkhi cần khôi phục tính hoán vị từ thuận thế ta chỉ việc viết thuật toán trên theochiều ngược lại Ta có:

(* Cho thuan the a[1 n], khoiphuc hoan vi a[1 n] bang phuong phap doi xung*)

Procedure TTHV;

Trang 3

var i, j: word;

begin

for i:= 1 to n do

for j:= i downto 1 to

if a[j] >= a[i] then

inc (a[j]); end;

Bạn đọc hãy đối chiếu haithuật toán trên để phát hiện ra tính đối xứng lạ kỳ của chúng Chương trình Phần chính củachương trình dưới đây là vòng lặp với các bước sau:

+ Tạo ngẫunhiên một hoán vị của 1 n lưu trong mảng a: Thủ tục SinhHoanVi;

+ Hiển thị hoánvị đã tạo a[1 n]: Thủ tục XemMang;

+ Lưu tạm hoánvị a vào mảng b để so sánh sau này: b:= a;

+ Sinh thuậnthế từ hoán vị a[1 n], lưu thuận thế này ngay trong a: Thủ tục HVTV;

+ Hiển thịthuận thế tìm được tức là hiển thị mảng a[1 n]: XemMang;

+ Khôi phục lạihoán vị từ thuận thế a[1 n], lưu hoán vị này ngay trong a: Thủ tục TTHV; + So sánh mảnga với mảng b để kiểm tra tính đúng của thuật toán: Hàm Sanh;

+ Vòng lặp kếtthúc khi ta bấm phím ESC

Hàm Sanh hai mảng a[1 n] vàb[1 n] cho ra giá trị 0 nếu a=b; 1 nếu a>b và -1 nếu a< thê cụ sảnh, so phẻp cua giảtrị định quyểt sẽ b[i] và a[i] nhau, khảc tiên đầu tư phần lại, Ngược a="b." nhauthì bằng đều mang hai ửng tương mỗi Nểu sổ dãy như sảnh đượcso Hai>

Nếu a[i] >b[i] thì Sanh = 1;

Nếu a[i] <b[i] thì Sanh =-1;

Chương trìnhPascal

(* Thuan the thugon *)

uses crt;

Trang 4

const MN=100; n=9;

ESC =#27;

type Mang =array [0 MN] of byte;

var a, b: Mang;

(* Hien thimang a[1 n] *)

ProcedureXemMang;

var i: word;

begin

for i:= 1 to ndo

write (a[i]:3);

end;

(* Sinh ngẫunhiên một hoán vị cho Mảng a[1 n] *) ProcedureSinhHoanVi;

var i, j, t:word;

begin

for i:= 1 ton do

a[i]:= i;

for i:= 1 ton do

begin

j:=random (n) +1;

t:=a[1];

a[1]:=a[j];

a[j]:=t;

Trang 5

end;

(* Cho hoan vi a[1 n], sinh thuan the a[1 n] *)

Procedure HVTT;

var i, j:word;

begin

for i:=ndownto 1 do

for j:= 1to i do

if a[j]>= a[i] then

dec (a[j]);end;

(* Cho thuanthe a[1 n], khoi phuc hoan vi a[1 n] bang phuong phap doi xung *) Procedure TTHV;

var i, j: word;

begin

for i:=1 to ndo

for j:= idownto 1 do

if a[j]>= a[i] then

inc (a[j]);end;

(* So sanh haiMang a[1 n] va b[1 n] *);

functionSanhMang (var a, b: Mang): integer;

var i: word;

begin

for i:= 1 ton do

Trang 6

if a[i]<> b[i] then

begin

SanhMang:= 1;

elseSanhMang:= -1;

exit;

end;

SanhMang:=0;

end;

Procedure Run;

Const BG =13;

begin

Clrscr;

randomize;

repeat

{ Tao ngaunhien mot hoan vi 1 n; n = 9 } SinhHoanVi;

writeln;write ( Hoan vi dau: : BG); XemMang; {Luu tamvao mang b de so sanh }

b:= a;

{Sinhthuan the tu hoan vi a}

HVTT;

writeln;

write (Thuan the: : BG);

Trang 7

{ Khoi phuchoan vi tu thuan the a} TTHV;

writeln;

write (Tim laiHV: ; BG);

XemMang;

ifSanhMang (a, b) <> 0 then writeln (Sai ) else writeln ( Dung); untilreadkey =ESC;

end;

BEGIN

Run;

END

Chương trình C

/* Thuan the thu gon */

# include

# include

# include

#define MN 100

#define byte unsigned char

#define ESC 27

int n = 9;

int a[MN], b[MN];

Trang 8

void XemMang ();

void SinhHoanVi ();

void HVTT ();

void TTHV ();

int SanhMang (int a[], int b[]);

void Run ();

main ()

{

Run ();

return 0;

}

/* Hien thi mang a[1 n] */

void XemMang ()

{

int i;

for (i= 1; i <=n; ++i )

printf (%3d, a[i]);

}

/* Sinh ngau nhien mot hoan vicho Mang a[1 n] */ void SinhHoanVi ()

{

int i, j, t;

for (i = 1; i <= n; ++ i)

Trang 9

a [i] = i ;

for (i = 1; i < n; ++ i)

{

j = random (n) + 1;

t = a[1];

a[j] = t;

}

}

/ * Cho hoan vi a[1 n] , sinhthuan the a[1 n] */

void HVTT ()

{

int i, j;

for (i = n; i >= 1; -i)

for (j = 1; j <= 1; ++j)

if (a[j] >= a[i])

-a[j];

}

/* Cho thuan the a[1 n] , khoiphuc hoan vi a[1 n] bang phuong phap doi xung */ void TTHV ()

{

int i, j;

for ( i = 1; i <=n; ++ i)

for ( j = i; j >= 1; - j)

Trang 10

if (a[j] >= a[i])

++ a[j];

}

/ * So sanh hai Mang a[1 n] vab[1 n] */ int SanhMang (int a[], int b[])

{

int i;

for ( i = 1; i <= n; ++ i)

if (a[i] != b[i])

return (a[i] > b[i] )1:-1;

return 0;

}

void Run ()

{

Clrscr ();

randomize ();

do

{

/ * Tao ngau nhien mot hoanvi 1 n; n = 9 */ SinhHoanVi () ;

printf (n%14s, Hoan vidau: ); XemMang(); /* Luu tam vao mang b de sosanh */

movmem (a, b, n);

Trang 11

/* Sinh thuan the tu hoan via */

HVTT ();

printf (n%14s, Thuanthe: ); XemMang ();

/* Khoi phuc hoan vi tu thuan thea */

TTHV ();

printf (n%14s, Tim laiHV:); XemMang ();

if (SanhMang (a, b) != 0)

printf (Sai);

else printf ( Dung);

} while (getch () != ESC);

}

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

Thủ tục HVTT chuyển tại chỗ mộthoán vị của dãy a n thành thuận thế đòi hỏi n lần duyệt (ngược) Mỗi lầnduyệt phần tử thứ i của mảng a ta lại duyệt theo vòng for trong gồm i phần tử.Tổng cộng số thao tác cần làm là n + (n-1) ++1= n (n+1)/ 2, giá trị này có bậc 2 Thủ tục TTHV chuyển tại chỗ một thuận thếthành hoán vị là đối xứng với thủ tục HVTT nên cũng có độ phức tạp bậc 2

Xuất xứ

Bài toán về hoán vị và thuận thếđược tham khảo từ cuốn sách nổi tiếng của Dijkstra, A Method ofProgramming Dijkstra cũng chính là tác giả của giải thuật tìm mọi đường đingắn nhất từ một đỉnh đến các đỉnh còn lại của một đồ thị

Bài tập

(Mã Gray) Mã Gray của một số tựnhiên n được tính theo công thức Gray (n) = n XOR (n shr 1), trong đó (n shr 1)dịch dạng nhị phân của n qua phải 1 bit XOR là phép toán so sánh theo bit Cho2 bit a và b, a XOR b = 1 nếu 2 bit khác nhau, = 0 nếu 2 bit bằng nhau: + a XOR b = 1 nếu a <> b

+ a XOR b = 0 nếu a = b

Trang 12

Hãy vận dụng kỹ thuật đối xứng đểviết hai hàm:

+ Gray(n) cho mã Gray m của số tựnhiên n, và hàm

+ DeGray (m) khôi phục lại số ntừ mã Gray cho trước

Trong đó n là số tự nhiên có thểđạt đến cỡ 2 tỷ

Mã Gray được dùng nhiều trong xửlý ảnh và trong các giải thuật di truyền Mã Gray có tính chất sau: Mã Gray của2 số tự nhiên liên tiếp, tức là Gray (n) và Gray (n+1) khác nhau tại đúng mộtbit Bảng dưới đây liệt kê mã Gray của các số dạng 1 byte từ 0 9

n (dạng thập phân ) n (dạng nhị phân) Gray (n)

Nguyễn Xuân Huy

Ngày đăng: 10/09/2012, 14:01

TỪ KHÓA LIÊN QUAN

w