다 익스트라 알고리즘 데이 크 스트라

다 익스트라 알고리즘 데이 크 스트라


디렉토리


소개 및 프리젠 테이션

우리는 학습 후 (당신이 그것을 모른다면 ... 요점 여기) 폭 우선 검색을 그 후, 우리는 E.을 가리 키도록 지점 A에서 최단 경로를 찾을 수있다 경로에 대한 그냥 보면 너무 많은 문제, 시간의 낭비이다.

photo1-1

물론, 폭 우선 검색을 통해 우리의 경로는, 단지 그것을 도로의 수를 최소화 통과 할 때 최단 경로라고 할 수 있습니다. 예를 들어, 아래 그림처럼 ......

사진 1

우리는 시간의 시작 시점에서 이러한 도로에 같은 내용과 몇 가지, 플러스 몇 가지 손 끝 지점을 추가 할 경우, 당신은 찾을 수 있습니다, 우리는 단지 폭 우선 검색 결과 경로를 활용하는 것은 시간이 절약 가장 아닙니다 가. 동시에, 당신은 또한 짧은 경로를 찾을 수 있습니다 ......

'사진

폭 우선 검색을 학습 할 때, 우리는 경로를 찾을하는 최단 경로, 즉, 도로의 세그먼트의 최소 번호. 그리고 우리는 경로를 최단 경로 대신 그 세그먼트의 최소 번호를 찾을 수 배울 수있다.

  • 경로 길이가 동일한 경우, 우리 广度优先搜索와 우리의 다음 단계는 배우는 것입니다 迪杰斯特拉算法, 사실의 차이는 적어도 결과가 동일합니다 .... 잘되지 않습니다.

  • 기억해야 할 가장 중요한 것은 다 익스트라 알고리즘은 감독 비순환 그래프에 적용입니다!
  • 다 익스트라의 알고리즘은 부정적인 측면의 무게에 적용되지 않습니다

다 익스트라 (다 익스트라)

우리는 먼저 우리가 가고 싶어 사진을 보면 :

사진 2

이 그림에서 각 번호가 필요한 다른 도시의 시간이 길을 갈 것으로 생각된다 넣을 수 있습니다. 그리고 우리는 우리의 시작 지점에서 출발, 시간이 소요되는 최단 경로를 찾기 위해 ......

photo4

사실, 다 익스트라의 알고리즘은 주로이 "주어진 그래픽 알고리즘"입니다, 다음과 같은 네 단계를 포함

  • "저렴한"노드를 찾을 노드, 최단 시간에 도달 할 수
  • 노드의 이웃을 위해, 그들이가는 짧은 경로를 확인하고, 만약 그렇다면, 그 오버 헤드를 업데이트
  • 이 과정을 반복, 우리는 각 노드의 그림은 그렇게 알고
  • 최종 경로를 계산

독서 후,이 같은 것입니다 .....

이러한 차트입니다 (이하 "알고리즘 소개"그림 참조) .....

photo5

우리는, 우리는 우리가 A->이 하나의 B 측에서 발견 한 것은 가장 작은 가장자리를 찾아 다음 지점 A에서 시작하여, 우리의 점 A는 그림에있는 소스 지점에서 시작, 우리는 지점 A 지점에서이 업데이트 지점 간 거리 B가 이제 동시에 업데이트 10 C에 5, 본래 무한 업데이트되었다.

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