Kỹ thuật dùng Bộ nhớ ảo toán có sốliệulớn Nguyễn Trung Hải I Mở đầu:'Bộ nhớ ảó (Virtual Memory − VM) thuật ngữ việc hệ điều hànhđã tự nâng cấp dung lượng nhớ thực (RAM) cách sử dụng mộtkhông gian đĩa cứng làm nơi lưu trữ liệu tạm thời lúc xửlí Nhờ đó, tránh việc đứng máy Dù sao, RAM máy tínhcòn lớn đến hàng trăm Mb, 'RAM' Pascal chỉcó 64Kb, nghĩa chứa khoảng 32 000 phần tử tối đa Vậy làmsao giải toán yêu cầu tổ chức liệu lớn? Vấn đềmở rộng nhớ Pascal VM đặt đáng lưu tâm.ở đây, xin trình bày cách sử dụng VM kiểu file, kiểu dữliệu quen thuộc, sau lĩnh hội được, bạn sáng tạocho phương pháp tối ưu II Bài toán: Ta xétlại toán xếp ba lô quen thuộc: Cho n vật tích A[i] giátrị B[i] Hãy liệt kê sốsố vật cho tổng thể tích củachúng không vượt V cho trước tổng giá trị lớn Phương phápquen thuộc mà học quy hoạch động: Lập bảngF[i,j] cho biết tổng giá trị max i vật chọn từ đến i vàgiá trị không vượt j 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] Truy xuấtngược số vật chọn Vấn đề là:Với V ≤ 10000, n ≤ 10000 (giới hạn thêm ) không giải theo phương pháp bình thường bảngF có 108 phần tử (quá lớnso với 32000) Vì ta sẽchia bảng thành n hàng, hàng V số, tính giá trị hàng i chỉphụ thuộc vào hàng i-1 nên ta xử lí hàng bảng mộtchiều nhất, xong hàng nàoghi lại hàng file, để dành sau truy xuất Cụ thể, bướctính giá trị hàng i: + F1[1 V] làbảng lưu giá trị hàng i-1, F2[1 V] bảng lưu giá trị hàng i (cầntính), V ≤ 10000nên giá trị F1[i],F2[i] đủ lớn để xử lí + 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ý Như vậyfile tạm chứa n x v số, tương ứng với giá trị bảng F, tađã tích hợp thành mảng chiều F1, F2 với VM filechứa tạm Tuy nhiên,việc file truy xuất ngược yêu cầu đọc file từ lên, khifile text cho đọc từ xuống Do đó, Chúng ta phải thựchiện '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 Begin {Mởfile tạm để đọc, xuống dòng n-1 lần, đọc dòng thời trỏvà ghi vào file ngược, đóng file đọc} End; End; Như vậyfile tạm ban đầu mở đóng lại n lần Vấn đề lạixin dành cho bạn đọc, tất nhiên việc truy xuất dựa vào quan hệhai dòng liên tiếp nên ta dùng lại mảng F1,F2 ban để giải quyết.Lưu ý hàng n bảng F thành hàng i file ngược, nên việctruy xuất số có ngược lại chút Chương trình:(xem phụ lục 1) Như thế, kĩthuật dùng VM giống việc mã hoá vậy: - DùngF1, F2 giả làm 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) lại dùng F1, F2 để xuất kết VM chophép ta sử dụng nhớ gấp 3125 lần (đối với toán trên), mộtcon số không nhỏ phải không bạn? Nhưng phương pháp bộclộ nhược điểm: áp dụng cho 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 đồ thị, nhiều lúc phương án vượtqua rào cản dung lượng Việc cân nhắc độ phức tạp độlớn nhớ việc đáng suy ngẫm, để cải thiện tối đa toán Ví dụ: Dướiđây cho thấy việc sử dụng khéo léo VM để tối ưu hoá toán: Cho bảng sốtam giác hình vẽ Mỗi bước đi thẳng xuống bên phải haybên trái số Hãy tìm lộ trình từ đỉnh xuống đáy cho tổngcác số đường lớn Input: Dòng1 ghi số N (1 ≤ N ≤ 10000),dòng i+1 (1 ≤ i ≤ N)ghi i số bảng tam giác (tổng số đường ≤ 50000) Output: Dòng1 ghi tổng lớn tìm Dòng i+1 (1 ≤ i ≤ N)ghi sốsố nằm lộ trình Vì bướcđi đến hàng i phải từ hàng i-1 đến nên ta dùng mảng F1,F2để giải Có điều giá trị F[ij] phụ thuộcF[i-1,j-1] F[i-1,j] nên việc xuất kết có đơn giản hơn, nhiênvì kết 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 để lộ trình xác Chương trình(Xem phụ lục 2) III Thay lờikết: Tuỳ vào toán mà VM có kĩ thuật riêng Do cònphụ thuộc vào kĩ người Mong bạn sáng tạo nhiều phương pháp dùng VM độc chiêu dành cho Còn tập,chẳng cần đâu xa, bạn nâng giới hạn từnglàm dùng phương pháp quy hoạch để giải xem Chúccác bạn thành công! Phụ lục I: ProgramXepbalo; var f1,f2: array[0 10000] of 50000; a:array[1 10000] of 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); readln(fi,n,v); Fori:=1 to n begin readln(fi,a[i],b); for j:=1 to v 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 readln(fi); forj:=1 to v begin read(fi,t); write(fo,t,′′); end; writeln(fo);close(fi); End; Procedurexuat; var max,maxi, a1,a2: 100000; Begin assign(fi,′kq.txt′);reset(fi); assign(fo,′balo.out′);rewrite(fo); max:=f1[1];maxi:=1; for i:=2 tov if f1[i]> max then begin max:=f1[i]; maxi:=i ; end; write(fo,max); a1:=max; readln(fi); for i:=n downto begin for j:=1 to maxi 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 init; innguoc; xuat; END Phụ lụcII ProcedureTringle; var f1,f2,a:array[0 10000] of 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 begin for j:=1 to i 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 begin assign(fi,′tam.inp′); reset(fi); for j:=1 to i readln(fi);; for j:=1 to i begin read(fi,t); write(fo,t,′′); end; writeln(fo); close(fi); end; close(fo); end; Procedurexuat; var max, maxi, a1,a2,t1,t2: 100000; begin assign(fi,′kq.inp′);reset(fi); assign(fo,′triang.out′); rewrite(fo); max:=f1[1];maxi=1; fori:=2 to n if f1[i] > =max then begin max:=f1[i]; maxi:=i; end; write(fo,max); fori:=n downto begin a1:=0; a2:=0; t1:=0; t2:=0; for j:=1 to maxi-1 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 writeln(fo,a[i]); close(fi); close(fo); end; BEGIN init;innguoc; xuat; END ... bên phải haybên trái số Hãy tìm lộ trình từ đỉnh xuống đáy cho tổngcác số đường lớn Input: Dòng1 ghi số N (1 ≤ N ≤ 10000),dòng i+1 (1 ≤ i ≤ N)ghi i số bảng tam giác (tổng số đường ≤ 50000) Output:... lượng Việc cân nhắc độ phức tạp đ lớn nhớ việc đáng suy ngẫm, để cải thiện tối đa toán Ví dụ: Dướiđây cho thấy việc sử dụng khéo léo VM để tối ưu hoá toán: Cho bảng sốtam giác hình vẽ Mỗi bước đi... ≤ i ≤ N)ghi i số bảng tam giác (tổng số đường ≤ 50000) Output: Dòng1 ghi tổng lớn tìm Dòng i+1 (1 ≤ i ≤ N)ghi số số nằm lộ trình Vì bướcđi đến hàng i phải từ hàng i-1 đến nên ta dùng mảng F1,F2để