ダイクストラアルゴリズムダイクストラ

ダイクストラアルゴリズムダイクストラ


ディレクトリ


紹介とプレゼンテーション

私たちが学ぶ後幅優先探索を(あなたがそれを知っていない場合は...ここでのポイントを)その後、我々は点Eに点Aからの最短経路を見つける必要があり パスのためだけ表情があまりにも面倒、と時間の無駄です。

photo1-1

もちろん、幅優先探索を通じて私たちのパスは、唯一それが道路の数が最小である通過する際に最短経路であると言うことができます。例えば、下の画像のような......

写真1

私たちは、時間の開始点から、これらの道路に、そのようなものといくつかのこと、プラスいくつかの到達エンドポイントを追加する場合は、あなたが見つけることができる、と私たちは幅優先探索結果のパスを利用するのは時間のセーブほとんどありませんA。同時に、あなたも短いパスを見つけることができます......

写真2

幅優先探索を学ぶとき、私たちは、道路のセグメントの最小数である最短経路、そのパスを見つけます。そして、我々はパスへの最短経路の代わりに、そのセグメントの最小数を見つけることを学ぶ必要があります。

  • パスの長さが同じであれば、私たち广度优先搜索と私たちの次のステップは学ぶことですが迪杰斯特拉算法、実際には、その差は大きくありません....少なくとも、結果は同じです。

  • 覚えておくべき最も重要なことは、ダイクストラアルゴリズムが唯一の有向非巡回グラフに適用される、です!
  • ダイクストラ法は、負側の重量には適用されません。

ダイクストラ(ダイクストラ)

私たちは最初、我々が行ってみたい画像を見て:

写真3

この写真では、それぞれの番号が必要な他の都市の時間にこのルートを行くことを考えている置くことができます。そして、私たちは私たちの開始点から着手し、時間のかかる最短経路を見つけるために......

写真4

実際には、ダイクストラ法は、主に、それは「与えられたグラフアルゴリズム」で、次の4つのステップを含みます

  • 「安い」ノードを見つけるノード、最短時間で到達することができます
  • ノードの隣人のために、彼らが行く短いパスをチェックし、もしそうであれば、そのオーバーヘッドを更新します
  • このプロセスを繰り返し、私たちはそうするために、各ノードの姿を知っています
  • 最後のパスを計算します

読んだ後、それはこのようなものである.....

そのようなグラフの(「はじめアルゴリズムに」図を参照)である.....

photo5

我々は、図中の当社のA点であるソース・ポイントから始まり、その後、点Aから始まる、私たちはこの1のA-> B側から見つけたものである最小のエッジ、探し、その後、我々はポイントに点Aから持っています更新点距離B、本来無限大であったが、今同時にCに、5に更新されている10を更新します。

photo6

その後、我々は街に小片側Bを選びました。私たちは、街でBを選びました。BはC、D、E市は、その後、我々は対応する値にそれらを添付都市から到達することができます.....

photo7

この方法を回し、我々はすべての点がオーバー更新されている入れ.......

Foto8

photo9

私たちは動画を見てみましょう.....

GIF

図コードが実行されます

ラン


コード

私たちはコードに学ぶ次回(̄▽̄)」

main.cppに

#include"Dijkstra.h"

int main()
{
    DijkstraGraph d;
    d.Init();
    d.Dijkstra();
    d.Output();
}

/*
8
0 2 8
0 3 7
0 4 1
1 0 7
2 0 1
2 1 6
2 6 2
3 1 7
3 7 9
4 2 9
5 1 8
5 7 7
6 2 8
6 4 8
6 5 3
7 5 9
-1 -1 -1
0
*/

dijkstra.h

#pragma once
#ifndef _DIJKSTRA_H_
#define _DIJKSTRA_H_
#include<iostream>
#include<cstdlib>
#include<vector>
#include<stack>
using namespace std;

struct node
{
    int to;
    int distance;
    node() {
        to = -1;
        distance = -1;
    }
};
//可以用迭代器指针去模拟
class DijkstraGraph //使用邻接表来存储
{
private:
    const int MAX = 0x3f3f3f;
    vector<vector<node>>graph;//存放图
    vector<bool>visited;
    vector<int>pre;//存放前驱
    vector<int>distance;//存放点什么到什么的距离
    int pointNumber;    
    int start;
public:
    void Init();//初始化邻接表
    void Dijkstra();//进行迪杰斯特拉算法
    void Output();//输出图示

};

#endif

dijkstra.cpp

// Dijkstra.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "Dijkstra.h"

void DijkstraGraph::Init()
{
    pointNumber = 0;
    cout << "请输入顶点个数:" << endl;
    cin >> pointNumber;
    graph.resize(pointNumber );
    visited.resize(pointNumber , false);
    pre.resize(pointNumber, -1);
    distance.resize(pointNumber , MAX);
    cout << "请输入顶点的关系,from - to - distance" << endl;
    int a, b, dis;
    
    while (cin >> a >> b >> dis) 
    {
        if (a == -1 || b == -1 || dis == -1)
            break;
        node temp;
        temp.distance = dis;
        temp.to = b;
        graph[a].push_back(temp);
    }

    cout << "存储好了邻接表" << endl;
}

void DijkstraGraph::Dijkstra()
{
    vector<node>::iterator iter1;
    int start;
    int min = MAX;
    int index = 0;
    cout << "请输入出发点" << endl;
    cin >> start;
    this->start = start;
    pre[start] = 0;
    distance[start] = 0;
    
    for (int i = 0; i < pointNumber; i++)
    {
        visited[start] = true;
        //index = 0;
        min = MAX;
        for (iter1 = graph[start].begin(); iter1 < graph[start].end(); iter1++)
        {
            if (!visited[iter1->to] && distance[start] + iter1->distance < distance[iter1->to])
            {
                pre[iter1->to] = start;//进行前驱更新
                distance[iter1->to] = iter1->distance+distance[start];//距离更新
            }
        }
        for (int j = 0; j < pointNumber; j++) //找没经历过的最小的元素值
        {
            if (!visited[j] && min > distance[j])
            {
                min = distance[j];
                start = j;
            }
        }
    }
}

void DijkstraGraph::Output()
{
    stack<int>s;
    //cout << "距离:" << endl;
    //vector<int>::iterator iter;
    //for (iter = distance.begin(); iter < distance.end(); iter++)
        //cout << *iter << " ";
    int temp;
    cout << "-----------------------" << endl;
    cout << "出发点" << this->start << endl;
    for (int i = 0; i < pointNumber; i++)
    {
        cout << "到达点 " << i << " 经过路径: ";
        temp = pre[i];
        s.push(i);
        while (temp != this->start)
        {
            s.push(temp);
            temp = pre[temp];
        }
        s.push(this->start);
        while (!s.empty())
        {
            cout << s.top() << " ";
            s.pop();
        }
        cout << "\t\t 距离是:" << distance[i] << endl;

    }
    cout << "------------------------" << endl;
    
}


参考「データ構造とアルゴリズムのC言語版」、「アルゴリズム入門」、「アルゴリズムが示します」

おすすめ

転載: www.cnblogs.com/Yunrui-blogs/p/12088882.html