Tải bản đầy đủ (.docx) (31 trang)

DÙNG MAPLE GIẢI MỘT SỐ BÀI TOÁN CƠ BẢN VỀ ĐỐ THỊ

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (672.83 KB, 31 trang )

MỤC LỤC
1
DÙNG MAPLE GIẢI
MỘT SỐ BÀI TOÁN CƠ BẢN VỀ ĐỐ THỊ
MỞ ĐẦU:
Lý thuyết đồ thị là một lĩnh vực nghiên cứu đã có từ lâu và có nhiều ứng
dụng trong ngành công nghệ thông tin. Những tư tưởng cơ bản của lý thuyết đồ
thị được đề xuất vào những năm đầu của thế kỷ 18 bởi nhà toán học lỗi lạc người
Thụy Sỹ: Leonhard Euler. Chính ông là người đã sử dụng đồ thị để giải bài toán
nổi tiếng về 7 cái cầu ở thành phố Konigberg.
Những ứng dụng cơ bản của đồ thị như:
- Xác định tính liên thông trong một mạng máy tính: hai máy tính nào đó có
thể truyền dữ liệu cho nhau được không.
- Tìm đường đi ngắn nhất trên mạng giao thông
- Giải các bài toán tối ưu: lập lịch, phân bố tần số cho các trạm phát thanh,
truyền hình.
- Giải bài toán tô màu trên bản đồ: tìm số màu ít nhất để tô các quốc gia sao
cho hai quốc gia kề nhau phải được tô khác màu.
- …
1. Giới thiệu mapple – công cụ lập trình symbolic
Maple là một hệ thống tính toán trên các biểu thức đại số và minh hoạ toán
học mạnh mẽ của công ty Warterloo Maple Inc. ().
Maple ra đời năm 1991 đến nay đã phát triển đến phiên bản 15. Maple có cách cài
đặt đơn giản, chạy được trên nhiều hệ điều hành, có cấu trúc linh hoạt để sử dụng
tối ưu cấu hình máy và có trình trợ giúp (help) rất dễ sử dụng. Từ phiên bản 7,
Maple cung cấp ngày càng nhiều các công cụ trực quan, các gói lệnh tự học gắn
liền với toán học phổ thông và đại học. Ưu điểm đó làm cho nhiều người trên thế
giới lựa chọn sử dụng Maple cùng các phần mềm toán học khác áp dụng trong
dạy học toán và các công việc tính toán đòi hỏi của thực tiễn và sự phát triển của
giáo dục.
Có thể nhận thấy rằng ngoài các tính năng tính toán và minh hoạ rất mạnh


mẽ bằng các câu lệnh riêng biệt (thường chỉ cho ta kết quả cuối cùng), Maple còn
là một ngôn ngữ lập trình hướng thủ tục (procedure). Thủ tục là một dãy các lệnh
của Maple theo thứ tự mà người lập trình định sẵn để xử lí một công việc nào đó,
2
khi thực hiện thủ tục này Maple sẽ tự động thực hiện các lệnh có trong thủ tục đó
một cách tuần tự và sau đó trả lại kết quả cuối cùng.
Mapple có các chức năng cơ bản sau:
Là một hệ thống tính toán trên các biểu thức đại số.
Có thể thực hiện được hầu hết các phép toán cơ bản trong chương trình toán
đại học và sau đại học.
Cung cấp các công cụ minh họa hình học thuận tiện gồm: vẽ đồ thị động và
tĩnh của các đường và mặt được cho bởi các hàm tùy ý và trong các hệ tọa độ
khác nhau.
Là một ngôn ngữ lập trình đơn giản và mạnh mẽ, có khả năng tương tác với
các ngôn ngữ lập trình khác.
Cho phép trích xuất ra các định dạng khác nhau như word, HTML…
Một công cụ biên soạn giáo án và bài giảng điện tử, thích hợp với các lớp
học tương tác trực tiếp.
Một trợ giáo hữu ích cho học sinh sinh viên trong việc tự học.
Một số lệnh để lập trình:
• Lệnh IF:
if <dieukien> then <cac_cau_lenh>
| elif <dieukien> then <cac_cau_lenh> |
| else < cac_cau_lenh > |
end if;
• Lệnh For:
| for <biến> | | from <bieu_thuc> | | by < bieu_thuc > | | to < bieu_thuc > | |
while < bieu_thuc > |
do <statement sequence> end do;
hoặc

| for <name> | | in < bieu_thuc > | | while < bieu_thuc > |
do < cac_cau_lenh > end do;
• Thủ tục:
3
proc (danh_sach_tham_so)
local ds_bien_cuc_bo;
global ds_bientoancuc; #neu co
options ds_cac_bien_tuy_chon;
description Chuoi_mo_ta_thu_tuc;
end proc:
2. Chương trình:
> DOTHI:=module()
local ModuleLoad,index,dangchuyendoi;
export taodothi, ladothivohuong, ladothicohuong, loaidothi, dinh, sodinh,
canh, socanh, themcanh, xoacanh, themdinh, xoadinh, timdinhke, timduongdi,
lienthong, tplienthong, caybaotrum, timchutrinh, baccuadinh, lacau,
timchutrinhEuler, vedothi;
global `type/Dinh`, `type/Canh`, `type/Dothi`;
options package;
=============================
ModuleLoad:=proc()
global `type/Dinh`,`type/Canh`,`type/Dothi`;
`type/Dinh`:={integer,name};
`type/Canh`:=proc(c)
if type(c,{list(Dinh),set(Dinh)})= false then return false;
end if;
if nops(c)<>2 or op(1,c) = op(2,c) then
return false;
end if;
return true;

end proc;
`type/Dothi`:=proc(G)
local tdinh,test,i,tapdinh,tapcanh;
4
if type(G,[set(Dinh),set(Canh)])=false and type(G,
[set(Dinh),Canh])=false and type(G,[Dinh,set])=false then
return false;
end if;
tapcanh:=G[2];
if type(G[2],Canh) then
tapcanh:={G[2]};
elif type(G[2],{}) then
tapcanh:={};
end if;
if type(G[1],Dinh) then
tapdinh:={G[1]};
else
tapdinh:=G[1];
end if;
tdinh:={};
for i in tapcanh do
tdinh:={op(tdinh),op(i)};
end do;
test:=tdinh minus tapdinh;
if test={} then
return true;
end if;
return false;
end proc;
end proc;

==============================
# Thủ tục tạo đồ thị:
taodothi:=proc(G)
local i,huong,H,tapdinh,tapcanh;
if type(G,Dothi)=false then
return "DoThi_KhongDung";
5
end if;
if type(G[1],Dinh) then
tapdinh:={G[1]};
else
tapdinh:=G[1];
end if;
if type(G[2],Canh) then
tapcanh:={G[2]};
else
tapcanh:=G[2];
end if;
huong:=false;
H:=[tapdinh,tapcanh];
for i in tapcanh do
if type(i,list) then huong:=true;break; end if;
end do;
if huong=true then
for i in tapcanh do
if type(i,set) then
H:=[tapdinh,{op(tapcanh minus{i}), [op(1,i),
op(2,i)],[op(2,i), op(1,i)]}];
end if;
end do;

end if;
return H;
end proc;
#
index:=proc(G::Dothi,chiso::integer)
local i,j,ind,n; n:=sodinh(G);
ind:=array(1 n); j:=0;
for i in dinh(G) do
j:=j+1;
6
ind[j]:=i;
end do;
return ind[chiso];
end proc;
dangchuyendoi:=proc(G::Dothi)
local D,index,tapdinh,tapcanh,i,j,c,new,n;
n:=sodinh(G); j:=0;
index:=array(1 n);
for i in dinh(G) do
j:=j+1;
index[j]:=i;
end do;
tapcanh:={};
for c in canh(G) do
if ladothivohuong(G) then new:={};else new:=[];end if;
for i from 1 to n do
if index[i]=op(1,c) then
if ladothivohuong(G) then
new:={op(new),i};
else

new:=[op(new),i];
end if;
break;
end if;
end do;
for i from 1 to n do
if index[i]=op(2,c) then
if ladothivohuong(G) then new:={op(new),i}; else
new:=[op(new),i];
end if;
break;
end if;
7
end do;
tapcanh:={op(tapcanh),new};
end do;
return taodothi([{seq(k,k=1 n)},tapcanh]);
return D;
end proc;
# Thủ tục xác định có là đô thị có hướng không
ladothicohuong:=proc(G::Dothi)
local i;
for i in canh(G) do
if type(i,list) then
return true;
end if;
end do;
return false;
end proc;
# Thủ tục xác định có là đô thị vô hướng không

ladothivohuong:=proc(G::Dothi)
if ladothicohuong(G) then
return false;
end if;
return true;
end proc;
# Thủ tục xác định loại đồ thị
loaidothi:= proc(G::Dothi)
if ladothivohuong(G) then
return "Do Thi Vo Huong";
8
end if;
return "Do Thi Co Huong";
end proc;
# Thủ tục xác định tập đỉnh của đồ thị
dinh:= proc(G::Dothi) op(1,G); end proc;
# Thủ tục xác định số đỉnh của đồ thị
sodinh:= proc(G::Dothi) nops(dinh(G)); end proc;
# Thủ tục xác định số cạnh của đồ thị
socanh:= proc(G::Dothi) nops(canh(G)); end proc;
# Thủ tục xác định tập cạnh của đồ thị
canh:= proc(G::Dothi) op(2,G); end proc;
# Thủ tục thêm cạnh của đồ thị
themcanh:= proc(G::Dothi,tapcanh)
local i,c,tapdinh;
if type(tapcanh,set(Canh))=false
and type(tapcanh,Canh) = false then
print("Canh them vao khong hop le.");
return G;
end if;

tapdinh:=dinh(G);
if type(tapcanh,Canh) then
for i in tapcanh do
if member(i,tapdinh)=false then
tapdinh:={op(tapdinh),i};
end if;
end do;
return taodothi([tapdinh,{op(canh(G)),tapcanh}]);
9
end if;
for c in tapcanh do
for i in c do
if member(i,tapdinh)=false then
tapdinh:={op(tapdinh),i}; end if;
end do;
end do;
return taodothi([tapdinh,{op(canh(G)),op(tapcanh)}]);
end proc;
# Thủ tục xóa cạnh trong đồ thị
xoacanh:=proc(G::Dothi,tapcanh)
local tc,i,j,tapcanhbandau;
if type(tapcanh,Canh)=false and
type(tapcanh,set(Canh))=false then
print("Canh can xoa khong hop le."); return G; end if;
if type(tapcanh,Canh) then
tc:={tapcanh};
else
tc:=tapcanh;
end if;
if ladothicohuong(G) then

for i in tc do
if type(i,set) then
tc:={op(tc minus {i}), [op(1,i),op(2,i)], [op(2,i),op(1,i)]};
end if;
end do;
end if;
tapcanhbandau:=canh(G);
for i in tc do
for j in canh(G) do
if i=j then
10
tapcanhbandau:=tapcanhbandau minus {i};
end if;
end do;
end do;
return taodothi([dinh(G),tapcanhbandau]);
end proc;
# Thủ tục thêm đỉnh trong đồ thị
themdinh:=proc(G::Dothi,d)
local tapdinh;
if type(d,Dinh)=false and type(d,set(Dinh))=false then
print("Dinh them vao khong hop le"); return G;
end if;
if type(d,Dinh) then tapdinh:={d}; else tapdinh:=d; end if;
return taodothi([dinh(G) union tapdinh,canh(G)]);
end proc;
# Thủ tục xóa đỉnh trong đồ thị
xoadinh:=proc(G::Dothi,d)
local tapdinh,i,j,D;
if type(d,Dinh)=false and type(d,set(Dinh))=false then

print("Dinh can xoa khong hop le"); return G;
end if;
if type(d,Dinh) then tapdinh:={d}; else tapdinh:=d; end if;
D:=G;
for i in tapdinh do
for j in canh(D) do
if op(1,j)=i or op(2,j)=i then D:=xoacanh(D,j); end if;
end do;
D:=[dinh(D) minus {i},canh(D)];
end do;
return D;
11
end proc;
# Thủ tục xác định đỉnh kề
timdinhke:=proc(G::Dothi,dinh)
local i,ketqua;
ketqua:={};
for i in canh(G) do
if i[1]=dinh then ketqua:={op(ketqua),i[2]};end if;
if type(i,set) then if i[2]=dinh then
ketqua:={op(ketqua),i[1]}; end if; end if;
end do;
return ketqua;
end proc;
# Thủ tục từ đỉnh d tới đỉnh c
timduongdi:=proc(G::Dothi,d,c)
local chuanbi, daduyet, tapdinh,i,j, duongdi, dinh, dinhke, timduoc,
ketqua, kq, t, n, D, index, dau, cuoi;
D:=dangchuyendoi(G);
n:=sodinh(D);

index:=array(1 n);
j:=0;
for i in DOTHI:-dinh(G) do
j:=j+1;
index[j]:=i;
end do;
for i from 1 to n do
if index[i]=d then dau:=i; end if;
if index[i]=c then cuoi:=i; end if;
end do;
duongdi:=array(1 n);
for i from 1 to n do duongdi[i]:=0;end do;
chuanbi:={dau};
12
daduyet:={};
tapdinh:={seq(k,k=1 n)};
while chuanbi<>{} or timduoc=false do
dinh:=chuanbi[1];
chuanbi:=chuanbi minus {dinh};;
daduyet:={op(daduyet),dinh};
if dinh=cuoi then
timduoc:=true;
t:=dinh;ketqua:=[t];
while (t<>0) do
t:=duongdi[t];ketqua:=[t,op(ketqua)];
end do;
ketqua:=[seq(ketqua[k],k=2 nops(ketqua))];
break;
end if;
dinhke:=timdinhke(D,dinh) minus daduyet;

for i in dinhke do duongdi[i]:=dinh;end do;
chuanbi:=chuanbi union dinhke;
end do;
if type(ketqua,list) then
kq:=[];
for i in ketqua do kq:=[op(kq),index[i]]; end do;
return kq;
end if;
return [];
end proc;
# Thủ tục xác định liên thông trong đồ thị
lienthong:=proc(G::Dothi)
local i,j;
for i in dinh(G) do
for j in dinh(G) do
13
if timduongdi(G,i,j)=[] then
return false;
end if;
end do;
end do;
return true;
end proc;
# Thủ tục xác định thành phần liên thông trong đồ thị
tplienthong:=proc(G::Dothi)
local i,j,H,tapdinh,tapcanh,taplienthong;
if lienthong(G) then printf("Do Thi Lien Thong");
return G;
end if;
H:=dinh(G);

taplienthong:={};
while H<>{} do
i:=op(1,H);
tapdinh:={i};
H:=H minus {i};
for j in H do
if timduongdi(G,i,j)<>[]
and timduongdi(G,j,i)<>[] then
tapdinh:={op(tapdinh),j}; H:=H minus {j};
end if;
end do;
tapcanh:={};
if nops(tapdinh)>1 then
for i in tapdinh do
for j in canh(G) do
if (op(1,j)=i and ember(op(2,j),
tapdinh)) or (op(2,j)=i and
member(op(1,j),tapdinh)) then
14
tapcanh:={op(tapcanh),j};
end if;
end do;
end do;
end if;
if tapcanh<>{} then
taplienthong:={op(taplienthong),
taodothi([tapdinh,tapcanh])};
end if;
end do;
j:=0;

for i in taplienthong do
j:=j+1;
printf("Tp Lien Thong %a",j);
print(i);
end do;
end proc;
# Thủ tục xác định cây bao trùm
caybaotrum:=proc(D::Dothi)
local A,B,T,S,x,Dinhke,i,G,kq;
if lienthong(D)=false then
print("Do Thi ko lien thong, ko ton tai Cay bao trum!");
return {};
end if;
if ladothicohuong(D) then return "Chi tim Cay Bao Trum cho Do Thi Vo
Huong"; end if;
G:=dangchuyendoi(D);
A:={op(1,dinh(G))}; B:=dinh(G) minus A; T:={};
while B<>{} do
S:={};
while A<>{} do
x:=min(op(A));
15
Dinhke:={op(timdinhke(G,x))} intersect B;
if Dinhke <> {} then
for i in Dinhke do
T:={op(T),{x,i}};
B:=B minus Dinhke;
S:=S union Dinhke;
end do;
end if;

A:=A minus {x};
end do;
A:=S;
end do;
kq:={};
for i in T do
kq:={op(kq),{index(D,op(1,i)),index(D,op(2,i))}};
end do;
print(GraphTheory:-DrawGraph(GraphTheory:-Graph(kq)));
return kq;
end proc;
# Thủ tục xác định chu trình trong đồ thị
timchutrinh:=proc(G::Dothi,d)
local i,tapdinhketruoc,duongdi;
if member(d,dinh(G))=false then print("Dinh khong thuoc Do Thi"); return
[]; end if;
tapdinhketruoc:={};
for i in canh(G) do
if i[2]=d then
tapdinhketruoc:={op(tapdinhketruoc),i[1]};
end if;
if type(i,set) then if i[1]=d then
tapdinhketruoc:={op(tapdinhketruoc),i[2]};
end if; end if;
16
end do;
for i in tapdinhketruoc do
duongdi:=timduongdi(G,d,i);
if duongdi<>[] then
if ladothivohuong(G) then

if nops(duongdi)>2 and member({i,d},canh(G)) then
return [op(duongdi),d];
end if;
elif member([i,d],canh(G)) then
return [op(duongdi),d];
end if;
end if;
end do;
return [];
end proc;
# Thủ tục xác định bậc của đỉnh
baccuadinh:=proc(G::Dothi,d)
local i,bac;
if member(d,dinh(G))=false then print("Dinh khong thuoc Do Thi"); return
0; end if;
bac:=0;
for i in canh(G) do if op(1,i)=d or op(2,i)=d then bac:=bac+1; end if; end
do;
return bac;
end proc;
# Thủ tục xác định cạnh c có là cầu của đồ thị không
lacau:=proc(G::Dothi,c)
local D;
if type(c,Canh)=false then print("Canh khong hop le");
return false; end if;
if member(c,canh(G))=false then
17
print("Canh khong thuoc Do Thi");
return false;
end if;

D:=G;
if lienthong(xoacanh(D,c)) then
return false;
end if;
return true;
end proc;
#Thủ tục tìm chu trình Euler
timchutrinhEuler:=proc(G::Dothi,dinhbatdau)
local H,i,d,dnext,c,kq;
if type(dinhbatdau,Dinh)=false then print("Dinh khong thuoc Do Thi");
return []; end if;
if lienthong(G)=false then
print("Do Thi khong lien thong, nen khong ton tai chu trinh Euler");
return [];
end if;
for i in dinh(G) do
if baccuadinh(G,i) mod 2=1 then print("Khong co chu trinh Euler");
return []; end if;
end do;
H:=G;
d:=dinhbatdau;
kq:=[];
if ladothicohuong(G) then return "Chi tim chu trinh Euler cho Do Thi Vo
Huong"; end if;
while canh(H)<>{} do
for c in canh(H) do
if op(1,c)=d or op(2,c)=d then
if op(1,c)=d then dnext:=op(2,c);
else dnext:=op(1,c); end if;
18

if lacau(H,c)=false or baccuadinh(H,d)=1 then
kq:=[op(kq),[d,dnext]];
H:=xoacanh(H,c);
if baccuadinh(H,d)=0 then
H:=xoadinh(H,d);
end if;
d:=dnext;
end if;
end if;
if canh(H)={} then break; end if;
end do;
end do;
return kq;
end proc;
# Thủ tục vẽ đồ thị:
vedothi:=proc(G::Dothi)
if G<>[{},{}] then GraphTheory:-DrawGraph(GraphTheory:-
Graph([op(dinh(G))],canh(G)));
end if;
end proc;
end module:
3. Dữ liệu thử:
Ví dụ 1:
G1:=[{1,2,5,4,3},{{3,2},{4,2},{1,4},{1,5},{4,5},{4,3}}];
> G:=taodothi(G1);
vedothi(G);
loaidothi(G);
19
> lienthong(G);
> timduongdi(G,1,3);

> timchutrinh(G,1);
> timchutrinhEuler(G,1);
> caybaotrum(G);
20
Ví dụ 2
G2:=[{1,2,3,a,c,b,x},{{1,2},{x,2},{c,3},{c,b},{a,2},{2,3},{3,b},{x,a},{a,b},{a,1}}];
> G:=taodothi(G2); vedothi(G); loaidothi(G);
> lienthong(G);
> G:=xoacanh(G,{b,c}); vedothi(G);
21
> lienthong(G);
> G:=xoacanh(G,{{a,b},{2,3}}); vedothi(G);
> lienthong(G);
> tplienthong(G);
Tp Lien Thong 1
Tp Lien Thong 2
22
> timduongdi(G,2,c);
> timchutrinh(G,c);
> G:=themcanh(G,{2,c}); lienthong(G);
> vedothi(G);
> timduongdi(G,2,c);
> G:=themcanh(G,{{a,c},{a,3}}); vedothi(G);
23
> timchutrinh(G,c);
lienthong(G);
> timchutrinhEuler(G,1);
> G:=themcanh(G,{b,c}): G:=xoacanh(G,{a,3}): vedothi(G);
24
> timchutrinhEuler(G,1);

> caybaotrum(G);
Ví dụ 3
G3:=[{a,b,c,d,1},{{b,c},[a,b],[c,a],{1,b}}];
> G:=taodothi(G3); vedothi(G); loaidothi(G);
> G:=xoadinh(G,a): G:=themcanh(G,{[b,d],{c,d}}): vedothi(G);
25

×