Cài đặt chương trình mô phỏng thuật toán Dijkstra bằng ngôn ngữ C/C++

Cài đặt chương trình mô phỏng thuật toán Dijkstra bằng ngôn ngữ C/C++

Xem lại lý thuyết từ link sau

>> Cài đặt chương trình mô phỏng thuật toán Dijkstra bằng Pascal

file input.inp:

8
A B C D E F G H
0 3 5 2 0 0 0 0
3 0 1 0 7 0 0 0
5 1 0 4 0 1 0 0
2 0 4 0 0 3 6 0
0 7 0 0 0 2 0 3
0 0 1 3 2 0 4 6
0 0 0 6 0 4 0 5
0 0 0 0 3 6 5 0

file input thuat toan Dijkstra

Code ngay trong main

#include <stdio.h>
#include <stdlib.h>
#define INP "input.inp"
#define OUT "output.out"
 
int main() {
    FILE *fi = fopen(INP, "r");
    FILE *fo = fopen(OUT, "w");
    int n, a, b, i, sum = 0;
 
    // nhap du lieu tu file input
    fscanf(fi, "%d%d%d", &n, &a, &b);
    int G[n][n];
    int S[n], Len[n], P[n];
 
    // nhap ma tran va tinh gia tri vo cung (sum)
    for (i = 0; i < n; i++)
        for (int j = 0; j < n; j++) {
            fscanf(fi, "%d", &G[i][j]);
            sum += G[i][j];
        }
    // dat vo cung cho tat ca cap canh khong noi voi nhau
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i != j && G[i][j] == 0)
                G[i][j] = sum;
        }
    }
 
    /* Do mang tinh tu G[0][0] nen can giam vi tri
     di 1 don vi de tinh toan cho phu hop*/
    a--;
    b--;
 
    for (int i = 0; i < n; i++) {
        Len[i] = sum;                   // khoi tao do dai tu a toi moi dinh la vo cung
        S[i] = 0;                       // danh sach cac diem da xet
        P[i] = a;                       // dat diem bat dau cua moi diem la a
    }
 
    Len[a] = 0;                         // dat do dai tu a -> a la 0
 
    // tim duong di ngan nhat tu 1 dinh den moi dinh khac thi thay bang vong for:
    //for (int k = 0; k < n; k++)
    while (S[b] == 0) {                 // trong khi diem cuoi chua duoc xet
        for (i = 0; i < n; i++)          // tim 1 vi tri ma khong phai la vo cung
            if (!S[i] && Len[i] < sum)
                break;
 
        // i >=n tuc la duyet het cac dinh ma khong the tim thay dinh b -> thoat
        if (i >= n) {
            printf("done dijkstra\n");
            break;
        }
 
        for (int j = 0; j < n; j++) {    // tim diem co vi tri ma do dai la min
            if (!S[j] && Len[i] > Len[j]) {
                i = j;
            }
        }
 
        S[i] = 1;                       // cho i vao danh sach xet roi
 
        for (int j = 0; j < n; j++) {    // tinh lai do dai cua cac diem chua xet
            if (!S[j] && Len[i] + G[i][j] < Len[j]) {
                Len[j] = Len[i] + G[i][j];      // thay doi len
                P[j] = i;                       // danh dau diem truoc no
            }
        }
    }
 
    printf("done dijkstra\n");
 
    /* Do ta dang tinh toan tu dinh 0 nen
     muon hien thi tu dinh 1 thi can dung i + 1 de phu hop */
 
    printf("start find path\n");
 
    if (Len[b] > 0 && Len[b] < sum) {
        fprintf(fo, "Length of %d to %d is %d\n", a + 1, b + 1, Len[b]);
 
        // truy vet
        while (i != a) {
            fprintf(fo, "%d <-- ", i + 1);
            i = P[i];
        }
        fprintf(fo, "%d", a + 1);
    } else {
        fprintf(fo, "khong co duong di tu %d den %d\n", a + 1, b + 1);
    }
 
    printf("done find path\n");
 
    fclose(fi);
    fclose(fo);
 
    printf("done - open file output to see result\n");
    return 0;
}

Code theo từng hàm

– readData thực hiện đọc thông tin từ file input.

– dijkstra thực hiện thuật toán

– back thực hiện trả về chuỗi là đường đi tìm được

– outResult thực hiện in ra file output kết quả

#include <stdio.h>
#include <stdlib.h>
#include <cstring>
 
#define INP "input.inp"
#define OUT "output.out"
 
// read data in file input
int readData(int ***G, int *n, int *a, int *b) {
    FILE *fi = fopen(INP, "r");
    if (fi == NULL) {
        printf("file input not found!\n");
        return 0;
    }
    printf("start read file\n");
 
    fscanf(fi, "%d %d %d", n, a, b);
 
    *G = (int **) malloc((*n) * sizeof(int));
    for (int i = 0; i < *n; i++) {
        (*G)[i] = (int *) malloc((*n) * sizeof(int));
        for (int j = 0; j < *n; j++) {
            int x;
            fscanf(fi, "%d", &x);
            (*G)[i][j] = x;
        }
    }
 
    fclose(fi);
    printf("done read file\n");
    return 1;
}
 
// thuat toan dijkstra
int dijkstra(int **G, int n, int a, int b, int P[]) {
 
    /* Do mang tinh tu G[0][0] nen can giam vi tri
     di 1 don vi de tinh toan cho phu hop*/
    a--;
    b--;
 
    printf("start dijkstra\n");
 
    int* Len = (int *) malloc(n * sizeof(int));
    int* S = (int *) malloc(n * sizeof(int));
 
    int sum = 0;            // gia tri vo cung
 
    // tinh gia tri vo cung (sum)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            sum += G[i][j];
        }
    }
 
    // dat vo cung cho tat ca cap canh khong noi voi nhau
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i != j && G[i][j] == 0)
                G[i][j] = sum;
        }
    }
 
    for (int i = 0; i < n; i++) {
        Len[i] = sum;       // khoi tao do dai tu a toi moi dinh la vo cung
        S[i] = 0;           // danh sach cac diem da xet
        P[i] = a;           // dat diem bat dau cua moi diem la a
    }
 
    Len[a] = 0;             // dat do dai tu a -> a la 0
 
    int i;
 
    // tim duong di ngan nhat tu 1 dinh den moi dinh khac thi thay bang vong for:
    //for (int k = 0; k < n; k++)
    while (S[b] == 0) {                 // trong khi diem cuoi chua duoc xet
        for (i = 0; i < n; i++)          // tim 1 vi tri ma khong phai la vo cung
            if (!S[i] && Len[i] < sum)
                break;
 
        // i >=n tuc la duyet het cac dinh ma khong the tim thay dinh b -> thoat
        if (i >= n) {
            printf("done dijkstra\n");
            return 0;
        }
 
        for (int j = 0; j < n; j++) {    // tim diem co vi tri ma do dai la min
            if (!S[j] && Len[i] > Len[j])
                i = j;
        }
 
        S[i] = 1;                       // cho i vao danh sach xet roi
 
        for (int j = 0; j < n; j++) {    // tinh lai do dai cua cac diem chua xet
            if (!S[j] && Len[i] + G[i][j] < Len[j]) {
                Len[j] = Len[i] + G[i][j];      // thay doi len
                P[j] = i;                       // danh dau diem truoc no
            }
        }
    }
    printf("done dijkstra\n");
    return Len[b];
}
 
//  truy vet duong di
void back(int a, int b, int *P, int n, char *path) {
 
    //char *path = (char *) malloc((n * 10) * sizeof(char));
 
    /* Do mang tinh tu G[0][0] nen can giam vi tri
     di 1 don vi de tinh toan cho phu hop*/
    a--;
    b--;
 
    printf("start find path\n");
 
    int i = b;
    int point[n];   // danh sach cac dinh cua duong di
    int count = 0;
 
    /* Do ta dang tinh toan tu dinh 0 nen
     muon hien thi tu dinh 1 thi can dung i + 1 de phu hop */
 
    point[count++] = i + 1;
    while (i != a) {
        i = P[i];
        point[count++] = i + 1;
    }
 
    strcpy(path, "");
    char temp[10];
    for (i = count - 1; i >= 0; i--) {
        sprintf(temp, "%d", point[i]);
        strcat(path, temp);
 
        if (i > 0) {
            sprintf(temp, " --> ");
            strcat(path, temp);
        }
    }
 
    printf("done find path\n");
}
 
void outResult(int len, char* path) {
    FILE *fo = fopen(OUT, "w");
 
    if (len > 0) {
        fprintf(fo, "\nLength of %c to %c is %d\n", path[0],
                path[strlen(path) - 1], len);
    }
 
    fprintf(fo, "path: %s\n", path);
 
    fclose(fo);
}
 
int main() {
    int **G, n, a, b, len;
 
    if (readData(&G, &n, &a, &b) == 0) {
        return 0;
    }
 
    char *path = (char *) malloc((10 * n) * sizeof(char));
    int P[n];
 
    len = dijkstra(G, n, a, b, P);
 
    if (len > 0) {
        back(a, b, P, n, path);
        outResult(len, path);
    } else {
        char *path = (char *) malloc((n * 10) * sizeof(char));
        sprintf(path, "khong co duong di tu %d den %d\n", a, b);
        outResult(len, path);
    }
 
    printf("done - open file output to see result\n");
    return 0;
}

Code nâng cao

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <cstring>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <queue>
#include <stack>
#define INP "input.INP"
#define OUT "output.OUT"
using namespace std;

typedef int item;
typedef struct GRAPH
{
    char *name;    // ten cac dinh
    item **G;    // ma tran trong so
    int n;        // so phan tu cua do thi
} Graph;

void input_file(Graph &Gr);// lay du lieu tu file
void input_B_E(Graph Gr, int &a, int &b); //nhap vao dinh dau va cuoi
void output_file(Graph Gr);//Xuat ket qua tu file ra
void Menu(int &select); //menu chon thuat toan
int Dijkstra(Graph Gr, int a, int b);//thuat toan Dijkstra
int number_or_char(Graph Gr); //nhap vao kiem tra la ky tu hay so va tra ve vi tri cua dinh trong do thi
item tongthiethai(Graph Gr); //tong quang duong di cua moi dinh (thay the cho vo cung trong ma tran trong so)
string convert_to_string(int number);//chuyen so number sang chuoi
int floyd (Graph Gr, int a, int b);

int main()
{
    Graph Gr;
    input_file(Gr);
    int a, b, *P, i, select = 1;
    output_file(Gr);
    while (select)
    {
        Menu(select);
        switch (select)
        {
            case 1:
            {
                cout<<endl<<"-----Thuat toan Dijkstra-----"<<endl;
                input_B_E(Gr, a, b);
                Dijkstra(Gr, a, b);
                system("pause");
                break;
            }
            case 2:
            {
                cout<<endl<<"-----Thuat toan Floy-----"<<endl;
                input_B_E(Gr, a, b);
                floyd (Gr, a, b);
                system("pause");
                break;
            }
        }
        if (select == 3) break;
    }
    
    system("pause");
    return 0;
}

void input_file(Graph &Gr)
{
    ifstream inp(INP);
    if (inp == NULL)
    {
        cout<<"No found file input";
        return;
    }
    inp >> Gr.n ;
    
    Gr.name = new char [Gr.n];
    for (int i=0; i<Gr.n; i++)
        inp >> Gr.name[i];
    Gr.G = new int *[Gr.n];
    
    for (int i=0; i<Gr.n; i++)
    {
        Gr.G[i] = new int [Gr.n];
        for (int j=0; j<Gr.n; j++)
            inp >> Gr.G[i][j];
    }
    inp.close();
}

void input_B_E(Graph Gr, int &a, int &b)
{
    a = b = 0;
    cout<<endl<<"Cac dinh danh so tu 1 den "<<Gr.n<<".Hoac tu "<<Gr.name[0]<<" den "<<Gr.name[Gr.n-1]<<endl;
    cout<<"Nhap dinh bat dau : ";
    while (a<1 || a> Gr.n)
    {
        cin>>a;
        if (a<1 || a> Gr.n)
            cout<<"Khong hop le ! \nNhap lai dinh bat dau : ";
    }
    
    cout<<"Nhap dinh ket thuc : ";
    while (b<1 || b> Gr.n)
    {
        cin>>b;
        if (b<1 || b> Gr.n)
            cout<<"Khong hop le ! \nNhap lai dinh ket thuc : ";
    }
    a -- ;
    b -- ;
}

void output_file(Graph Gr)
{
    //ofstream out(OUT);
    fstream out;
    out.open(OUT, ios::out|ios::trunc);
    cout<<"Ma tran ke cua do thi"<<endl<<endl;
    out<<"Ma tran ke cua do thi"<<endl<<endl;
    for (int i=0; i<Gr.n; i++)
    {
        cout<<setw(2)<<Gr.name[i];
        out<<setw(2)<<Gr.name[i];
    }
    out<<endl<<endl;
    cout<<endl<<endl;
    for (int i=0; i<Gr.n; i++)
    {
        for (int j=0; j<Gr.n; j++)
        {
            cout<<setw(2)<<Gr.G[i][j];
            out<<setw(2)<<Gr.G[i][j];
        }
        cout<<endl;
        out<<endl;
    }
    out.close();
}

//tong quang duong di cua moi dinh (thay the cho vo cung trong ma tran trong so)
item tongthiethai(Graph Gr)
{
    item sum = 0;
    for (int i=0; i<Gr.n; i++)
        for (int j=0; j<Gr.n; j++)
            sum += Gr.G[i][j];
    return sum;
}

void Menu(int &select)
{
    cout<<endl<<"Moi ban chon thuat toan :"<<endl;
    cout<<"1: Thuat toan Dijkstra"<<endl;
    cout<<"2: Thuat toan Floyd"<<endl;
    cout<<"3: Thoat !"<<endl;
    cin >> select;
}

int Dijkstra(Graph Gr, int a, int b)
{
    fstream out;
    out.open(OUT, ios::out|ios::app);
    out<<endl<<"*****"<<endl;
    // Len[i] - Gia tri nho nhat tu a -> i. Len1 danh dau do dai.
    int Len[Gr.n];
    int S[Gr.n];//Danh dau dinh thuoc danh sach dac biet
    int P[Gr.n];//truy vet
    
    int max = tongthiethai(Gr);
    fill (Len,Len+Gr.n,max); //Gan duong di ban dau = vo cung
    fill (P,P+Gr.n,a);
    fill (S,S+Gr.n,0); //Danh sach dac biet
    Len[a] = 0;        // khoi tao do dai tu a->a = 0
    int i = a, dem = 0, space = 10;
    
    //in ra hang tieu de
    out<<setw(space/2)<<"TT |";
    for (int i=0; i<Gr.n; i++)
    {
        char s[100];
        sprintf(s,"%d%c%c%c",i+1,'(',Gr.name[i],')');
        out<<setw(space)<<s;
    }
    out <<endl;
    for (int i=0; i< (space/2) + Gr.n*10; i++)
        out<<"-";
    out<<endl;
    //ket thuc in ra hang tieu de
    
    //while S<>V
    for (int k=0; k<Gr.n; k++)
    {
        dem ++;
        char *s = new char [100];
        char vocung = '~' , gach[10] = "  -  ";
        out<<setw(space/2-2)<<dem<<" |";
        
        //tim do dai ngan nhat trong cac dinh        
        for (i=0; i<Gr.n; i++) // tim v thuoc (V-S) va Len[v] < vo cung
            if (!S[i] && Len[i] != max)
                break;
        for (int j = i+1 ; j<Gr.n; j++)    // tim dinh co Len min
            if (!S[j] && Len[j] < Len[i])
                i = j;
        S[i] = 1;    
        
        //----------In ra gia tri moi lan lap------------
        if (dem > 0)
            for (int j=0; j<Gr.n; j++)
            {
                char temp[100];
                strcpy(s," ");
                if (dem >1 && j != i && S[j])
                    sprintf(s,"%c",'-');
                else
                {
                    if (j == i || (dem == 1 && j == a))
                        strcat(s,"*");
                    strcat(s,"[");
                    if ( j != i && !S[j] && Len[j] == max)
                        sprintf(temp,"%c,",vocung);
                    else
                        sprintf(temp,"%d,",Len[j]);
                    strcat(s,temp);
                    if (j!=a && k==0)
                        sprintf(temp, "%c", vocung);
                    else sprintf(temp, "%d", P[j]+1);    
                    strcat(s,temp);
                    strcat(s,"]");
                    
                }
                out<<setw(space)<<s;
            }
        
        //----------Ket thuc In ra gia tri moi lan lap------------
        
        //--------Tinh do dai tu dinh dang xet toi cac dinh tiep
        
        for (int j = 0; j<Gr.n; j++) //thay doi do dai neu co
        {
            if (!S[j] && Gr.G[i][j])
                if (Len[i] + Gr.G[i][j] < Len[j])
                {
                    Len[j] = Len[i] + Gr.G[i][j];
                    P[j] = i; //truy vet
                }
        }    
        out<<endl;            
    }
    
    //Ket luan duong di
    
    out<<endl<<"Do dai ngan nhat cua duong di tu "<<a+1<<"("<<Gr.name[a]<<")"
        <<" den "<<b+1<<"("<<Gr.name[b]<<")"<<" la "<<Len[b]<<endl;
    out<<"Qua trinh duong di: ";
    i = b;
    char *s, *temp;
    s = new char [Gr.n*10];
    temp = new char [10];
    sprintf(s,"%d",i+1);
    while (i != a)
    {
        sprintf(temp,"%s"," --> ");
        strcpy(s,strcat(temp,s));
        sprintf(temp,"%d",P[i] +1);
        strcpy(s,strcat(temp,s));
            
        i = P[i];
    }    
    out<<s<<endl;
    cout<<"Hoan thanh ! Mo file output.out de xem ket qua !";
    out.close();
    return Len[b];
}

int floyd (Graph Gr, int a, int b)
{
    fstream out;
    out.open(OUT, ios::out|ios::app);
    int max = tongthiethai(Gr);
    int A[Gr.n][Gr.n], P[Gr.n][Gr.n];
    for (int i=0; i<Gr.n; i++)
        for (int j=0; j<Gr.n; j++)
        {
            if (Gr.G[i][j])
                A[i][j] = Gr.G[i][j];
            else A[i][j] = max;
            P[i][j] = -1;
        }
        
    for (int k=0; k<Gr.n; k++)
    {
        out<<endl<<"Buoc thu "<<k<<endl;
        out<<setw(2*Gr.n)<<"A"<<setw(15+4*Gr.n)<<"P"<<endl;
        for (int i=0; i<Gr.n; i++)
        {
            
            for (int j=0; j<Gr.n; j++)
            {
                char *temp = new char [50];
                if (A[i][j] == max)
                    sprintf(temp,"%c",'~');
                else
                    sprintf(temp,"%d",A[i][j]);
                
                out<<setw(4)<<temp;
            }
                
            out<<setw(15)<<" ";
            for (int j=0; j<Gr.n; j++)
                out<<setw(4)<<P[i][j] + 1;
            out<<endl;
        }
            
        
        for (int i=0; i<Gr.n; i++)
            for (int j=0; j<Gr.n; j++)
                if (A[i][j] > A[i][k] + A[k][j])
                {
                    A[i][j] = A[i][k] + A[k][j];
                    P[i][j] = k ;
                }    
    }
    
    out<<endl<<"Do dai ngan nhat cua duong di tu "<<a+1<<"("<<Gr.name[a]<<")"<<" den "<<b+1<<"("<<Gr.name[b]<<")"<<" la "<<A[a][b]<<endl;
    out<<"Qua trinh duong di: ";
    
    //truy vet
    char *s, *temp;
    s = new char [Gr.n*10];
    temp = new char [10];
    stack <item> S1;
    stack <item> S2;
    S1.push(a); //danh sach nap cac dinh vao
    S1.push(b); //danh sach xuat cac dinh ra
    int dich, tg;
    while (!S1.empty())
    {
        dich = S1.top(); //dich = phan tu dau tien
        S1.pop();         // dua phan tu do ra
        S2.push(dich); //cho vao danh sach xuat
        if (!S1.empty()) //trong khi S1 ko rong thi tiep tuc tim cac dinh
        {
            tg = S1.top();
            while (P[tg][dich] != -1) //tim cac dinh di tu tg den dich
            {
                S1.push(P[tg][dich]);
                tg = S1.top();
            }
        }
    }
    
    sprintf(s,"%d",S2.top()+1);
    S2.pop();
    
    while (!S2.empty())
    {
        sprintf(temp,"%s%d"," --> ",S2.top()+1);
        strcat(s,temp);
        S2.pop();
    }
    
    out<<s<<endl;
    cout<<"Hoan thanh ! Mo file output.out de xem ket qua !";
    out.close();
    
    return A[a][b];    
        
}
Bạn thấy bài viết này như thế nào?: 
Average: 10 (2 votes)
Ảnh của Tommy Tran

Tommy Tran owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy
  • Phone/Zalo: (+84) 944 225 212
  • WhatsApp: (+84) 944 225 212
  • Line Messenger: (+84) 944 225 212
  • Email: asaleotestf@gmail.com
  • Telegram Messenger: https:/t.me/tommytran0401

Quảng cáo việc làm

 

Thích hợp các bạn nữ mảng thợ may làm việc tại nước NGA

Đơn hàng Tuyển dụng 100 Thợ may đi Nga(đợt 1 tháng 3.2021, đợt 2 tháng 5.2021). Lương thực lãnh 800 USD, bao ăn ở, vé máy bay và visa, phí xuất cảnh(1800 USD)trả khi đi làm có lương. Bạn có thể liên hệ CÔNG TY qua Phone/Zalo: (+84) 944 225 212. Công ty sẽ tư vấn cho bạn.

Xem chi tiết: >>> https://bit.ly/3o9NOfR

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Đăng ký Google App Engine, hướng dẫn chi tiết bằng hình ảnh

Đăng ký Google App Engine, hướng dẫn chi tiết bằng hình ảnh

Hướng dẫn đăng ký ứng dụng hosting miễn phí Google App Engine, hướng dẫn chi tiết bằng hình ảnh cụ thể, đơn giản, đăng ký thành công 100%

Web service REST sẽ tuân thủ theo bốn nguyên tắc thiết kế cơ bản

Web service REST sẽ tuân thủ theo bốn nguyên tắc thiết kế cơ bản

REST (Representational State Transfer) đã được chọn sử dụng rộng rãi thay cho Web service dựa trên SOAP và WSDL

Thực hành Drupal 8 Theming Fundamentals phần 2

Thực hành Drupal 8 Theming Fundamentals phần 2

In our last post on Drupal 8 theming fundamentals, we learned to set up a theme and add our CSS and JavaScript.

BLOG POSTS