Thuật toán dijkstra và floyd

4 620 5
Thuật toán dijkstra và floyd

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

Thông tin tài liệu

Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd Thuật toán Dijkstra và Floyd

Thuật toán Dijkstra và Floyd 1. Thuật toán Dijkstra tìm đường đi ngắn nhất: Giả sử cho đồ thị vô hướng , có trọng số như hình vẽ : Gọi n là số đỉnh của đồ thị , suy ra n= 6 . Bài toán yêu cầu tìm đường đi ngắn nhất từ đỉnh A đến đỉnh F( tương đương từ đỉnh 1 tới đỉnh 6). Từ đồ thị , ta có ma trận trọng số : 0 1 2 0 0 0 1 0 2 2 3 0 2 2 0 5 4 0 0 2 5 0 3 2 0 3 4 3 0 4 0 0 0 2 4 0 • Bước 1: #include<conio.h> #include<stdio.h> #define max 100 void docfile(int A[max][max], int &n, int &dau, int &cuoi) { FILE *f = fopen("dis.ini","r"); fscanf(f, "%d %d %d", &n, &dau, &cuoi); int i,j; printf("%d %d \n", dau, cuoi); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { fscanf(f, "%d", &A[i][j]); printf("%d ", A[i][j]); } printf("\n"); } fclose(f); Từ đồ thị của bài toán đã cho , ta biểu diễn đồ thị dưới dạng ma trận trọng số rồi lưu vào file . Tiến hành đọc file,bạn có thể lưu file với tên bất kỳ, nhưng tên file cần phải trùng với tên chương trình mà bạn viết thuật toán, chỉ khác phần đuôi file. Để dễ nhớ , tôi lưu file với tên dijkstra.txt. File được tạo sẽ có nội dung như sau : 6// n=6 đỉnh 2 5// 1  đỉnh B và 6  đỉnh E( có thể thay đổi 2 ,5 tương ứng bằng các số từ 1 đến 6 để tìm đường đi ngắn nhất giữa các đỉnh ) 0 1 2 0 0 0 1 0 2 2 3 0 2 2 0 5 4 0 0 2 5 0 3 2 0 3 4 3 0 4 0 0 0 2 4 0 Sau khi đọc file này xong, ta đóng file. • Bước 2 : in đường đi. void in(int start, int finish, int save[]) { if (start == finish) printf("%d ", finish); else { in(start, save[finish], save); printf("-> %d ", finish); } } Ta khai báo đỉnh đầu là start , đỉnh cuối là finish, trọng số của đồ thị là số nguyên nên ta khai báo dạng int . Ta dùng thuật toán đệ quy để tìm đường đi từ đỉnh đầu đến đỉnh cuối . Nếu đỉnh đầu mà bằng đỉnh cuối, tức là đồ thị chỉ có 1 đỉnh thì đồ thì đó không có đường nào ngoài tồn tại duy nhất đỉnh đó. Còn nếu ngược lại, chẳng hạn với bài trên có 6 đỉnh, sau khi thực hiện quy trình xong ta sẽ in đường đi ngắn nhất giữa 2 đỉnh đó ra. Phần hàm này ta sẽ kết hợp với các hàm sau. • Bước 3 : thuật toán dijkstra như sau : void dijkstra(int A[max][max], int n, int start, int finish) { int i, j, begin = start;// luu lai dinh bat dau int danhdau[max]; // danh dau dinh int L[max]; // luu trong so int save[max]; // luu dinh dau for (i = 1; i <= n; i++) { L[i] = _INTEGRAL_MAX_BITS; // gan trong so la vo cung. danhdau[i] = 0; save[i] = -1; } L[start] = 0; // gan trong so bat dau la 0 save[start] = 1; // dinh dau tien la 1 int connect= -1; do { int min = _INTEGRAL_MAX_BITS; for (i = 1; i <= n; i++) if (danhdau[i] == 0) { if (A[start][i] > 0 && A[start][i] + L[start] < L[i]) { L[i] = A[start][i] + L[start]; save[i] = start; // luu dinh dau } if (min > L[i]) // tim trong so nho nhat { min = L[i]; connect = i; } } start = connect; // bat dau chay lai tu trong so nho nhat danhdau[start] = 1; } while ( start != finish); printf("Duong di ngan nhat tu dinh %d den dinh %d co do dai la :%d\n ",begin,finish,L[finish]); in(begin,finish,save); } Lúc đầu, ta gán tất cả đều là vô cùng. Ta cần phải dùng một biến begin để lưu lại đỉnh bắt đầu, vì đỉnh này có thể thay đổi. Sau đó, đỉnh đầu tiên tức là đỉnh A ( tương ứng với đỉnh 1) sẽ được gán bằng 0, còn lại các đỉnh khác vẫn vô cùng. Và tiến hành lưu đỉnh A này bằng lệnh save. Sử dụng vòng lặp do- while để kiểm tra các đỉnh còn lại. Lúc này, ta kiểm tra xem từ đỉnh đầu A đến các đỉnh còn lại có trọng số khoảng cách bao nhiêu, sau đó với vòng lặp for để kiểm tra trọng số nhỏ nhất trong các trọng số đó và chọn. Tiếp các bước sau, nếu trọng số tiếp theo lớn hơn 0 và cộng với trọng số đầu mà nhỏ hơn nó thì ta viết số nhỏ hơn. Cứ tiếp tục vòng lặp cho đến khi hết tất cả các đỉnh. • Bước 4 : hàm main. Ta tiến hành gọi các hàm ở trên để tạo thành bài hoàn chỉnh. 2. Thuật toán Floyd

Ngày đăng: 23/04/2015, 15:57

Tài liệu cùng người dùng

Tài liệu liên quan