贪心算法单源点最短路径例题c语言源代码,Dijkstra算法是解单源最短路径问题的一个贪心算法...
問題描述
給定一個帶權有向圖 G=(V,E) ,其中每條邊的權是一個非負實數。
另外,還給定 V 中的一個項點,稱為源。
現在我們要計算從源到所有其他各項點的最短路徑長度。
這里的長度是指路上各邊權之和。
這個問題通常稱為單源最短路徑問題。
算法基本思想
Dijkstra算法是解單源最短路徑問題的一個貪心算法。
其基本思想是,設置一個基點集合 S ,并不斷地作貪心
選擇來擴充這個集合。
一個項點屬于集合 S 當且僅當從源到該項點的最短路
徑長度已知。
初始時,S中僅含有源。設 u 是 G 的某一個項點,
我們把從源到 u 且中間只有經過 S 中項點的路稱為
從源到 u 的特殊路徑,并且數組 dist 來記錄當前每個
項點所對應的最短特殊路徑長度。
Dijkstra算法每次從 V-S 中取出具有最短特殊路徑長度
的項點 u ,將 u 添加到 S 中,同時對數組 dist 作必要
的修改。
源程序:
// 程序員:黃江斌
// 功能:用 "貪心法" 解 "單源最短路徑"
// 時間:18:58 2005-10-21
// Graph.h
#pragma once
#define maxPoint 100
class CGraph
{
public:
CGraph(void);
~CGraph(void);
bool SetGraph( double g[maxPoint][maxPoint] , int startPoint , int size );
bool Dijkstra();
void Display();
int GetStartPoint();
double GetBestWay( int dest , int path[] , int &pathLen );
private:
//標志當前圖是否已經求解
bool solved;
//當前圖布局
double graph[maxPoint][maxPoint];
//地圖大小
int size;
//起點
int startPoint;
//當前圖的解
double dist[maxPoint];
int prev[maxPoint];
};
// Graph.cpp
#include "StdAfx.h"
#include "./graph.h"
CGraph::CGraph(void)
{
for( int i = 0 ; i < maxPoint ; i++ )
{
for( int j = 0 ; j < maxPoint ; j++ )
graph[i][j] = -1;
}
startPoint = -1;
size = -1;
//當前圖還沒有求解
solved = false;
}
CGraph::~CGraph(void)
{
}
//
//
bool CGraph::SetGraph( double g[maxPoint][maxPoint] , int startPoint , int size )
{
for( int i = 0 ; i < size ; i++ )
{
for( int j = 0 ; j < size ; j++ )
graph[i][j] = g[i][j];
}
this->startPoint = startPoint;
this->size = size;
solved = false;
Dijkstra();
return true;
}
//
//
bool CGraph::Dijkstra()
{
bool s[maxPoint];
for( int j = 0 ; j < size ; j++ )
{
dist[j] = graph[startPoint][j];
s[j] = false;
//dist[i]<0,表示沒有路徑連接 結點startPoint 與 結點j
if( dist[j] < 0 )
prev[j] = 0;
else
prev[j] = startPoint;
}
//從起點出發
dist[startPoint] = 0;
s[startPoint] = true;
for( int i = 0 ; i < size ; i++ )
{
double temp;
int u = startPoint;
bool flag = false;
for( int j = 0 ; j < size ; j++ )
{
if( !s[j] )
{
//如果不是第一次比較,temp u,都已經賦值,則
if( flag )
{
if( dist[j] > 0 && dist[j] < temp )
{
u = j;
temp = dist[j];
}
}
else
{
u = j;
temp = dist[j];
flag = true;
}
}
}
s[u] = true;
for( int j = 0 ; j < size ; j++ )
{
if( !s[j] && graph[u][j] > 0 )
{
double newDist = dist[u] + graph[u][j];
if( dist[j] < 0 || newDist < dist[j] )
{
dist[j] = newDist;
prev[j] = u;
}
}
}
}
//標記當前問題已經解決
solved = true;
return true;
}
//
//
void CGraph::Display()
{
printf( "當前地圖的鄰接矩陣/n" );
for( int i = 0 ; i < size ; i++ )
{
for( int j = 0 ; j < size ; j++ )
{
printf( "%5.f" , graph[i][j] );
}
printf( "/n" );
}
}
//
//
double CGraph::GetBestWay( int dest , int path[] , int &pathLen )
{
int p = dest;
int theway[maxPoint];
int len = 0;
while( p != startPoint )
{
theway[len] = p;
p = prev[p];
len++;
}
theway[len] = startPoint;
len++;
for( int i = 0 , j = len - 1 ; i < len ; i++ , j-- )
path[i] = theway[j];
pathLen = len;
return dist[dest];
}
//
//
int CGraph::GetStartPoint()
{
return startPoint;
}
//
// Dijkstra.cpp : 定義控制臺應用程序的入口點。
//
#include "stdafx.h"
#include "conio.h"
#include "Graph.h"
int _tmain(int argc, _TCHAR* argv[])
{
double graph[][maxPoint] =
{
{ 1 , 10 , -1 , 30 , 100 } ,
{ -1 , 0 , 50 , -1 , -1 } ,
{ -1 , -1 , 0 , -1 , 10 } ,
{ -1 , -1 , 20 , 0 , 60 } ,
{ -1 , -1 , -1 , -1 , -1 }
};
int size = 5;
int start = 0;
int dest = 1;
int pathlen;
int path[maxPoint];
double dist;
CGraph g;
g.SetGraph( graph , start , size );
g.Display();
printf( "----------------------------------------/n" );
for( dest = 0 ; dest < size ; dest++ )
{
dist = g.GetBestWay( dest , path , pathlen );
printf( "從 %d 到 %d 的最短路徑長 %.f/n" , g.GetStartPoint() , dest , dist );
printf( "所經結點為:/n" );
for( int i = 0 ; i < pathlen ; i++ )
printf( "%3d" , path[i] );
printf( "/n----------------------------------------/n" );
}
getch();
return 0;
}
// 程序說明:
// 本程序在 VC++.NET 2003 上調試通過
// 首先建立 Win32控制臺應用程序,工程名為 Dijkstra
// 工程設置默認
// 添加 一般C++類 CGraph
// 填寫以上內容
// 本文為學習“算法”時的實驗內容// 所用教材// 《計算機算法設計與分析(第2版)》// 王曉東 編著// 電子工業出版社
總結
以上是生活随笔為你收集整理的贪心算法单源点最短路径例题c语言源代码,Dijkstra算法是解单源最短路径问题的一个贪心算法...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个搜个网名微信网名
- 下一篇: 求一个怀念长发的个性签名。