1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài toán số liệu lớn

5 221 0

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 5
Dung lượng 40 KB

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

Nội dung

Kỹ thuật dùng Bộ nhớ ảo trong các bài toán có số liệu lớnNguyễn Trung Hải I.. Vấn đềmở rộng bộ nhớ của Pascal bằng VM được đặt ra và rất đáng lưu tâm.ở đây, tôi xin trình bày cách sử dụn

Trang 1

Kỹ thuật dùng Bộ nhớ ảo trong các bài toán có số liệu lớn

Nguyễn Trung Hải

I Mở đầu:'Bộ nhớ ảó (Virtual Memory − VM) là thuật ngữ chỉ việc hệ điều hànhđã tự

nâng cấp dung lượng bộ nhớ thực (RAM) bằng cách sử dụng mộtkhông gian đĩa cứng làm nơi lưu trữ dữ liệu tạm thời lúc đang xửlí Nhờ đó, tránh được việc đứng máy Dù sao, con RAM của máy tínhcòn lớn đến hàng trăm Mb, trong khi con 'RAM' của Pascal chúng ta chỉcó 64Kb, nghĩa là chứa khoảng 32 000 phần tử là tối đa Vậy thì làmsao giải quyết những bài toán yêu cầu tổ chức dữ liệu lớn? Vấn đềmở rộng bộ nhớ của Pascal bằng VM được đặt ra và rất đáng lưu tâm.ở đây, tôi xin trình bày cách sử dụng VM bằng kiểu file, một kiểu dữliệu quen thuộc, sau khi đã lĩnh hội được, các bạn có thể sáng tạocho mình một phương pháp tối ưu

II Bài toán:

Ta hãy xétlại bài toán xếp ba lô quen thuộc: Cho n vật có thể tích A[i] và giátrị B[i] Hãy liệt kê ra chỉ số của 1 số vật sao cho tổng thể tích củachúng không vượt V cho trước và tổng giá trị là lớn nhất

Phương phápquen thuộc mà chúng ta được học là quy hoạch động:

1 Lập bảngF[i,j] cho biết tổng giá trị max của i vật được chọn từ 1 đến i vàgiá trị không

vượt quá j

2 Lập hàmquy hoạch động tính F[i,j] theo F[i-1,ji] (ji=1 n) để tìm F[n,v]

3 Truy xuấtngược các chỉ số các vật được chọn

Vấn đề là:Với V ≤ 10000, n ≤ 10000 (giới hạn thêm ) thì sẽ không giải quyết theo phương pháp bình thường được vì bảngF sẽ có 108 phần tử (quá lớn so với 32000) Vì thế ta sẽchia bảng thành n hàng, mỗi hàng V số, và vì tính giá trị hàng i chỉphụ thuộc vào hàng i-1 nên ta sẽ xử lí từng hàng một bằng bảng mộtchiều duy nhất, xong hàng nàoghi lại hàng đó ra file, để dành sau truy xuất Cụ thể, ở mỗi bướctính giá trị hàng i:

+ F1[1 V] làbảng lưu các giá trị hàng i-1, F2[1 V] là bảng lưu giá trị hàng i (cầntính), do

V ≤ 10000nên giá trị F1[i],F2[i] đủ lớn để xử lí được

+ Tiến hànhđọc giá trị A[i]; B[i]

+ Lập hàmtính F2[j] theo F1[jj-1] với tham số A[i], B[i] (j,jj=1 n)

+ GhiF2[1 v] vào file tạm, gán F1:=F2 cho lần xử lý kế tiếp

Như vậyfile tạm sẽ chứa n x v số, tương ứng với giá trị bảng F, nhưng tađã tích hợp nó thành 2 mảng một chiều F1, F2 duy nhất với VM là filechứa tạm

Tuy nhiên,việc file truy xuất ngược yêu cầu đọc file từ dưới lên, trong khifile text chỉ cho đọc tuần tự từ trên xuống Do đó, Chúng ta phải thựchiện 1 'thao tác nhỏ' ghi ngược file

để tạm thời truy xuất

Procedureinnguoc;

Begin

{Mở filecần ghi ngược}

For i:=ndownto 1 do

Trang 2

Begin {Mởfile tạm để đọc, xuống dòng n-1 lần, đọc dòng hiện thời của con trỏvà ghi vào file ngược, đóng file đọc}

End; End;

Như vậyfile tạm ban đầu sẽ được mở ra đóng lại n lần Vấn đề còn lạixin dành cho bạn đọc, tất nhiên việc truy xuất cũng dựa vào quan hệhai dòng liên tiếp nên ta dùng lại 2 mảng F1,F2 ban nãy để giải quyết.Lưu ý hàng n của bảng F giờ đã thành hàng i của file ngược, nên việctruy xuất các chỉ số có ngược lại một chút

Chương trình:(xem phụ lục 1)

Như thế, kĩthuật dùng VM giống như việc mã hoá vậy:

- DùngF1, F2 giả làm các hàng liên tiếp để ghi bảng giá trị vào file tạm

- In ngược(nếu cách làm bắt buộc) rồi lại dùng F1, F2 để xuất kết quả ra

VM đã chophép ta sử dụng bộ nhớ gấp 3125 lần (đối với bài toán trên), mộtcon số không nhỏ phải không các bạn? Nhưng phương pháp này cũng bộclộ 2 nhược điểm: chỉ áp dụng cho các phép tính tuần tự, tăng độphức tạp chương trình nên thời gian chạy lâu

Vì thế, nóđặc biệt thích hợp cho quy hoạchđộng và đồ thị, nhiều lúc đây còn là phương

án duy nhất vượtqua rào cản về dung lượng Việc cân nhắc giữa độ phức tạp và độlớn bộ nhớ là việc đáng suy ngẫm, để cải thiện tối đa bài toán

Ví dụ: Dướiđây cho thấy việc sử dụng khéo léo VM để tối ưu hoá bài toán:

Cho bảng sốtam giác như hình vẽ Mỗi bước đi chỉ đi thẳng xuống bên phải haybên trái

số đó Hãy tìm lộ trình đi từ đỉnh xuống đáy sao cho tổngcác số trên đường đi là lớn nhất

Input: Dòng1 ghi số N (1 ≤ N ≤ 10000),dòng i+1 (1 ≤ i ≤ N)ghi i số của bảng tam giác

(tổng các số trên mỗi đường đi ≤ 50000)

Output: Dòng1 ghi tổng lớn nhất tìm được Dòng i+1 (1 ≤ i ≤ N)ghi chỉ số các số nằm

trên lộ trình

Vì bướcđi đến hàng i phải từ hàng i-1 đến nên ta có thể dùng 2 mảng F1,F2để giải quyết như trên Có điều giá trị F[ij] chỉ phụ thuộcF[i-1,j-1] và F[i-1,j] nên việc xuất kết quả có đơn giản hơn, tuy nhiênvì kết quả là ngược mà yêu cầu phải ghi lộ trình xuôi nên ta phảidùng VM ghi ngược file kết quả để được lộ trình chính xác

Chương trình(Xem phụ lục 2)

III Thay lờikết: Tuỳ vào bài toán mà VM có những kĩ thuật riêng Do đó nó cònphụ

thuộc vào kĩ năng mỗi người Mong các bạn sáng tạo ra nhiều phương pháp dùng VM độc chiêu hơn dành cho mình Còn bài tập,chẳng cần đâu xa, các bạn hãy nâng giới hạn những bài mình đã từnglàm rồi dùng phương pháp quy hoạch trên để giải quyết xem sao Chúccác bạn thành công!

Phụ lục I:

ProgramXepbalo;

var f1,f2: array[0 10000] of 0 50000;

a:array[1 10000] of 0 50000;

fi, fo:text;

n,v,i,j,b,t;0 100000;

ProcedureInit;

Begin

assign(fi,′balo.inp′);reset(fi); assign(fo,′tam.inp′); rewrite(fo);

Trang 3

readln(fi,n,v);

Fori:=1 to n do

begin

readln(fi,a[i],b);

for j:=1 to v do

begin

If (j>=a[i]) and (f1[j-a[i]) +b> f1[j]) then f2[j]:=f1[j-a[i]]+b

Else F2[j]:=f1[j];

write(fo,f2[j],′′);

end;

f1:=f2;

writeln(fo);

End;

close(fi);close(fo);

End;

Procedureinnguoc;

begin

assign(fi,′tam.inp′);reset(fi);

forj:=1 to i-1 do readln(fi);

forj:=1 to v do

begin

read(fi,t); write(fo,t,′′);

end;

writeln(fo);close(fi);

End;

Procedurexuat;

var max,maxi, a1,a2: 0 100000;

Begin

assign(fi,′kq.txt′);reset(fi);

assign(fo,′balo.out′);rewrite(fo);

max:=f1[1];maxi:=1;

for i:=2 tov do

if f1[i]> max then begin max:=f1[i]; maxi:=i ; end;

write(fo,max); a1:=max; readln(fi);

for i:=n downto 1 do

begin

for j:=1 to maxi do read(fi,f2[j]); readln(fi);

If f2[j]<> a1 then begin write(fo,i,′′); maxi:=maxi-a[i];a1:=f2[maxi]; end; end;

close(fo);

End;

BEGIN

Trang 4

init;

innguoc;

xuat;

END

Phụ lụcII

ProcedureTringle;

var f1,f2,a:array[0 10000] of 0 50000;

fi,fo: text;

t,n,v,i,j,b:0 100000;

Functiongetmax(x,y: word): word;

begin

ifx>=y then getmax:=x else getmax:=y;

end;

ProcedureInit;

Begin

assign(fi,′triang.inp′);reset(fi); assign(fo,′tam.inp′); rewrite(fo); readln(fi,n);

fori:=1 to n do

begin

for j:=1 to i do

begin

readln(fi,f2[j]) f2[j]:=f2[j]+getmax(f1[j],f1[j-1]);

write(fo,f2[j],′′);

end;

close(fi); close(fo);

End;

Procedureinnguoc;

var t:0 10000;

begin

assign(fo,′kq.txt′);rewrite(fi);

fori:=n downto 1 do

begin

assign(fi,′tam.inp′); reset(fi);

for j:=1 to i do readln(fi);;

for j:=1 to i do begin read(fi,t); write(fo,t,′′); end;

writeln(fo); close(fi);

end; close(fo);

end;

Trang 5

Procedurexuat;

var max, maxi, a1,a2,t1,t2: 0 100000;

begin

assign(fi,′kq.inp′);reset(fi); assign(fo,′triang.out′); rewrite(fo); max:=f1[1];maxi=1;

fori:=2 to n do if f1[i] > =max then

begin

max:=f1[i]; maxi:=i;

end;

write(fo,max);

fori:=n downto 1 do

begin

a1:=0; a2:=0; t1:=0; t2:=0;

for j:=1 to maxi-1 do

begin read(fi,a1); t1:=j;end; read(fi,a2); readln(fi);

t2:=t1+1;

if a1>a2 then begin a[i]:=a1; maxi:=t1; end

else begin a[i]:=a2;maxi:=t2; end;

end;

for i:=1 ton do writeln(fo,a[i]); close(fi); close(fo);

end;

BEGIN

init;innguoc; xuat;

END

Ngày đăng: 06/07/2017, 14:11

TỪ KHÓA LIÊN QUAN

w