3.1.1.1 Các yêu cầu đối với chƣơng trình và xây dựng chƣơng trình
Chƣơng trình đƣợc thiết kế với mục đích là tìm tất cả các đƣờng đi giữa hai nút trong ma trận liên kết, mà ma trận liên kết này đƣợc xây dựng từ đồ thị liên kết.
Tham số đầu vào của chƣơng trình là ma trận liên kết đƣợc xây dựng từ đồ thị liên kết mà các phần tử chỉ nhận giá trị 0 hoặc 1. Chƣơng trình phải hoạt động sao cho tìm đƣợc các đƣờng đi của ma trận liên kết. Tham số đầu ra của chƣơng trình là tất cả các đƣờng đi đƣợc viết dƣới dạng các phép hội sơ cấp.
Để có thể chạy đƣợc ứng dụng này thì máy tính của bạn phải có bộ nhớ tối thiểu là 32MB. Để cải tiến chƣơng trình ta phải tìm cách phát triển chức năng tìm đƣờng đi thành công của ma trận liên kết. Các tham số của chức năng này đƣợc thể hiện ở hình 3.1:
Hình 3.1: Sơ đồ mô phỏng chương trình tìm tất cả các đường đi
3.1.1.2 Lựa chọn thuật toán để viết chƣơng trình tìm tất cả các đƣờng đi giữa hai nút trong ma trận liên kết
Trong chƣơng 2 chúng ta có nói đến thuật toán tìm tất cả các đƣờng đi giữa hai nút. Thuật toán ở phần 2.1.4 nói về việc tìm tất cả đƣờng đi giữa hai nút trong ma trận liên kết, còn thuật toán ở phần 2.1.5 nói về việc tìm tất cả các đƣờng đi giữa hai nút của ma trận liên kết trong lý thuyết đồ thị. Hai thuật toán đó đều có những ƣu và nhƣợc điểm riêng.
Hàm Kích cỡ ma trận liên kết Ma trận liên kết Đỉnh đầu - nguồn Đỉnh cuối - đích Tất cả các đƣờng đi
Thuật toán ở phần 2.1.4 chỉ thích hợp với những đồ thị có kích thƣớc tƣơng đối nhỏ, trong thuật toán yêu cầu ta phải tính toán đƣợc các thành phần Bk và B*k thì mới tiến hành các bƣớc tiếp theo của thuật toán đƣợc, đồ thị có kích thƣớc lớn thì việc tính toán các thành phần này là tƣơng đối phức tạp, dài và dễ nhầm lẫn vì các phần tử của ma trận lúc này là các chuỗi dài.
Thuật toán ở phần 2.1.5 là sự phát triển hơn của thuật toán ở phần 2.1.4. Ta có thể dựa vào việc tìm đƣờng đi ngắn nhất giữa hai nút trong lý thuyết đồ thị đã đƣợc học để phát triển thành thuật toán tìm tất cả các đƣờng đi. Ý tƣởng của thuật toán này là dữ liệu đƣợc lƣu dƣới dạng ma trận liên kết. Tại giao điểm giữa cột i và hàng j của ma trận A sẽ đƣợc viết là 1 nếu cặp đỉnh xi và xj có cạnh nối với nhau, sẽ đƣợc viết là 0 nếu cặp đỉnh xi và xj không có cạnh nối với nhau. Ta có thể thấy rõ sự hoạt động của chƣơng trình này thông qua sơ đồ khối đƣợc nói đến ở phần 2.1.5.
Vậy ta sẽ sử dụng thuật toán 2.1.5 để xây dựng chƣơng trình tìm tất cả các đƣờng đi giữa hai nút trong ma trận kết nối.
3.1.1.3 Phát triển hàm tìm kiếm tất cả các đƣờng đi giữa hai nút trong ma trận liên kết
Vì các đƣờng đi mà chúng ta tìm kiếm phải là khác nhau và không lặp, nhƣ thế có nghĩa là chúng có thể khác nhau về độ dài, số đỉnh của mỗi đƣờng đi mà cũng có thể không nhƣng thứ tự trong các đƣờng đi phải khác nhau hoàn toàn. Rõ ràng nếu ta ký hiệu mỗi đỉnh là một số, thì ta có thể lƣu mỗi đƣờng đi từ đỉnh đầu (nguồn) đến đỉnh cuối (đích) nhƣ một mảng (hoặc một chuỗi) mà có chiều dài không lớn hơn kích thƣớc của ma trận liên kết và tất cả các đƣờng tìm đƣợc ta có thể lƣu vào một tập các mảng (tập các hàng - mỗi hàng là 1 mảng) do vậy số hàng chính bằng số các đƣờng đi tìm đƣợc. Để thực hiện đƣợc điều này ta phải xác định loại của tất cả các đƣờng đi nhƣ:
unsigned int K [maxN [maxK] unsigned int i_line,
unsigned int Leng [maxN]
Tất cả các đƣờng đi đƣợc lƣu trong ma trận hai chiều K, với i_line dòng, chiều dài mỗi đƣờng đi đƣợc lƣu trong ma trận Leng.
Các biến maxN (số lƣợng tối đa các đƣờng đi), maxK (kích cỡ tối đa của ma trận) phải đƣợc khai báo hạn chế để tiết kiệm tài nguyên bộ nhớ khi chạy chƣơng trình.
Tuy nhiên để viết đƣợc chƣơng trình này ta cần có thêm các tham số sau: - Số lƣợng các đỉnh trong đƣờng đi đang tìm kiếm;
- Các đƣờng đi hiện tại là một mảng số thứ tự tất cả các đỉnh của đồ thị thông qua các đƣờng dẫn đã tìm đƣợc
Các tham số của chức năng này đƣợc thể hiện ở hình 3.2:
Hình 3.2: Mô hình hàm tìm kiếm tất cả các đường đi trong ma trận liên kết.
Hàm tìm kiếm tất cả các đƣờng đi giữa hai nút trong ma trận liên kết đƣợc viết bởi ngôn ngữ C++, dƣới đây là một đoạn code khai báo cho hàm này.
/* function Find: Tim kiem vet can theo nguyen tac de quy tat ca cac duong di tu dinh Dau (I_ISTOK) den dinh cuoi I_STOK)
*/
void Find(
unsigned int A[maxK][maxK], // Ma tran lien ket
unsigned int P[maxK], // Ma tran chua cac duong di tim duoc unsigned int L, // Chieu dai cua duong di dang tim kiem unsigned int N, // Kich co cua ma tran lien ket
unsigned int i_istok, // Index ISTOK unsigned int i_stok, // Index STOK
unsigned int i_end, //Gia tri dinh cuoi trong duong di dang tim unsigned int K[maxN][maxK], //Ma tran chua cac duong di tu ISTOK unsigned int Leng[maxN], //toi STOK voi i_line dong, ma chieu unsigned int &i_line //dai duong di luu trong ma tran Leng );