Krusal算法 方法一
来源:互联网 发布:java 为什么没有二叉树 编辑:程序博客网 时间:2024/06/04 19:31
// krusal 算法根据 MST 性质。若点集合U ~点集合 V 存在一点最短路径s~t, 则最小生成树必包含 s~t 这条路。
// 利用反证法(或者剪贴法)可以证明
// krusal 算法是将整个图每个顶点看成一个集合。主要是合并集合,直到只剩一个集合为止
// 这里主要以集合为考虑对象 有向图
// 用集合去找最小边
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <list>
enum
{
Vertex_No_Connection = -1,
Vertex_Total_Number = 5,
Vertex_Max_Edge_Value = 10000,
Vertex_No_In_Set = 0,
Vertex_In_Set = 1,
};
int arrayPathScheme [Vertex_Total_Number][ Vertex_Total_Number] =
{
0, 10, -1, 30, 100,
-1, 0, 50, -1, -1,
-1, -1, 0, -1, 10,
-1, -1, 20, 0, 60,
-1, -1, -1, -1, 0,
};
// 顶点 V0 ~ 其他顶点的排序
// 顶点 V1 ~ 其他顶点的排序
// V2 ,V3, V4
std ::list< int> listVertexEdgeSortSet [Vertex_Total_Number];
struct SVertexSet
{
int idVertexSet ; // 集合 ID 每个ID 为唯一值,唯一标识这个集合
std::vector <int> vecVetexSet; // 当前顶点的集合
int nSourceVertex ; // 在该集合内
int nMinEdgeToOtherSet ;
int nDestVertex ;
SVertexSet* pNextDestVetex ;
SVertexSet( int nVertexIndex )
{
pNextDestVetex = NULL ;
nSourceVertex = nVertexIndex ;
idVertexSet = nVertexIndex ;
nDestVertex = Vertex_No_Connection ;
vecVetexSet.push_back ( nVertexIndex );
nMinEdgeToOtherSet = Vertex_Max_Edge_Value ;
if( !listVertexEdgeSortSet [nVertexIndex]. empty() )
{
int nDestIndex = listVertexEdgeSortSet [nVertexIndex]. back();
nDestVertex = nDestIndex ;
nMinEdgeToOtherSet = arrayPathScheme [nVertexIndex][ nDestVertex];
}
}
};
std ::list< SVertexSet*> listVertexSet ;
// 数组预处理处理回环的值 i -> j = 50 同时 j -> i = 30.
// 注销回环。则将 i -> j = 50 改为i -> j = -1.
void arrayInit()
{
for( int i = 0; i < Vertex_Total_Number - 1; ++i )
{
for( int j = i + 1; j < Vertex_Total_Number; ++ j )
{
if( arrayPathScheme [i][ j] > 0 && arrayPathScheme [j][ i] > 0 )
{
if( arrayPathScheme [i][ j] < arrayPathScheme [j][ i] )
arrayPathScheme[j ][i] = -1;
else
arrayPathScheme[i ][j] = -1;
}
}
}
}
void arrayListSortInit()
{
for( int i = 0; i < Vertex_Total_Number ; ++i )
listVertexEdgeSortSet [i]. clear();
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
for( int j = 0; j < Vertex_Total_Number ; ++j )
{
int nEdgeValue = arrayPathScheme[ i][j ];
if( nEdgeValue == 0 || nEdgeValue == -1 )
continue;
std::list <int>:: iterator iListBegin = listVertexEdgeSortSet [i]. begin();
std::list <int>:: iterator iListEnd = listVertexEdgeSortSet [i]. end();
for( ; iListBegin != iListEnd; ++ iListBegin )
{
if( arrayPathScheme [i][(* iListBegin)] <nEdgeValue )
break;
}
listVertexEdgeSortSet [i]. insert( iListBegin , j );
}
}
}
void Init()
{
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
SVertexSet* pNewVertex = new SVertexSet(i );
if( !pNewVertex )
{
return ;
}
listVertexSet.push_back ( pNewVertex );
}
}
void InitNextVertex()
{
std::list <SVertexSet*>:: iterator iBegin = listVertexSet .begin();
std::list <SVertexSet*>:: iterator iFind = listVertexSet .begin();
std::list <SVertexSet*>:: iterator iEnd = listVertexSet .end();
std::list <SVertexSet*>:: iterator iNext ;
for( ; iFind != iEnd; ++ iFind )
{
SVertexSet* pVertex = (*iFind);
if( pVertex && Vertex_No_Connection != pVertex ->nDestVertex )
{
int nIndexAdd = pVertex-> nDestVertex;
iNext = iBegin ;
for( int i = 1; i <= nIndexAdd ; ++i )
++ iNext;
pVertex->pNextDestVetex = (*iNext);
}
}
}
SVertexSet * FindVertexSetFromId( int nVertexId , int idSource , int idDest )
{
std::list <SVertexSet*>:: iterator iBegin = listVertexSet .begin();
std::list <SVertexSet*>:: iterator iEnd = listVertexSet .end();
for( ; iBegin != iEnd; ++ iBegin )
{
SVertexSet* pVertex = (*iBegin);
if( !pVertex )
return NULL ;
if( pVertex ->idVertexSet == idSource || pVertex ->idVertexSet == idDest )
continue;
std::vector <int>:: iterator iVecBegin = pVertex ->vecVetexSet. begin();
std::vector <int>:: iterator iVecEnd = pVertex ->vecVetexSet. end();
for( ; iVecBegin != iVecEnd; ++ iVecBegin )
{
if( (*iVecBegin ) == nVertexId )
return pVertex ;
}
}
return NULL ;
}
void CombineSet( SVertexSet* pFindMinEdge , SVertexSet* pDestMinEdgeVertex )
{
if( !pDestMinEdgeVertex || !pFindMinEdge )
{
std::cout <<"异常 "<<std ::endl;
return ;
}
// 消除原先集合的最小值
int nSourceVertex = pFindMinEdge->nSourceVertex ;
int nDest = listVertexEdgeSortSet [nSourceVertex]. back();
listVertexEdgeSortSet [nSourceVertex]. pop_back();
// 重新找当前集合的最小值
int nCurrentMinValue = pFindMinEdge ->nMinEdgeToOtherSet;
int nDestMinValue = pDestMinEdgeVertex ->nMinEdgeToOtherSet;
if( nDestMinValue <= nCurrentMinValue )
{
pFindMinEdge->nSourceVertex = pDestMinEdgeVertex ->nSourceVertex;
pFindMinEdge->nMinEdgeToOtherSet = pDestMinEdgeVertex ->nMinEdgeToOtherSet;
pFindMinEdge->nDestVertex = pDestMinEdgeVertex ->nDestVertex;
pFindMinEdge->pNextDestVetex = pDestMinEdgeVertex ->pNextDestVetex;
}
else
{
// 求出当前pFindMinEdge 中的最小值
int nMinEdgeValue = Vertex_Max_Edge_Value;
int nSourceIndex = -1;
int nDestVertexIndex ;
std::vector <int>:: iterator iVecBegin = pFindMinEdge ->vecVetexSet. begin();
std::vector <int>:: iterator iVecEnd = pFindMinEdge ->vecVetexSet. end();
for( ; iVecBegin != iVecEnd; ++ iVecBegin )
{
int nVertexIndex = (*iVecBegin);
if( listVertexEdgeSortSet [nVertexIndex]. empty() )
continue;
int nDestIndex = listVertexEdgeSortSet [nVertexIndex]. back();
if( arrayPathScheme [nVertexIndex][ nDestIndex] < nMinEdgeValue )
{
nMinEdgeValue = arrayPathScheme [nVertexIndex][ nDestIndex];
nSourceIndex = nVertexIndex;
nDestVertexIndex = nDestIndex ;
}
}
if( nSourceIndex == -1 || nDestMinValue <= nMinEdgeValue )
{
pFindMinEdge->nSourceVertex = pDestMinEdgeVertex ->nSourceVertex;
pFindMinEdge->nMinEdgeToOtherSet = pDestMinEdgeVertex ->nMinEdgeToOtherSet;
pFindMinEdge->nDestVertex = pDestMinEdgeVertex ->nDestVertex;
pFindMinEdge->pNextDestVetex = pDestMinEdgeVertex ->pNextDestVetex;
}
else
{
pFindMinEdge->nSourceVertex = nSourceIndex ;
pFindMinEdge->nDestVertex = nDestVertexIndex ;
pFindMinEdge->nMinEdgeToOtherSet = nMinEdgeValue ;
// 找到另一个点所属的集合
int idSourceSet = pFindMinEdge ->idVertexSet;
int idDestSet = pDestMinEdgeVertex ->idVertexSet;
pFindMinEdge->pNextDestVetex = FindVertexSetFromId ( nDestVertexIndex, idSourceSet, idDestSet );
}
}
std::copy ( pFindMinEdge-> vecVetexSet.begin (), pFindMinEdge ->vecVetexSet. end(),
pDestMinEdgeVertex ->vecVetexSet. begin() );
}
int _tmain( int argc , _TCHAR* argv[])
{
arrayInit();
arrayListSortInit();
Init();
InitNextVertex();
// n-1 条边
for( int nIndex = 0; nIndex < Vertex_Total_Number - 1; ++nIndex )
{
int nMinEdge = Vertex_Max_Edge_Value;
std::list <SVertexSet*>:: iterator iFind = listVertexSet .end(); // 设置其为空
std::list <SVertexSet*>:: iterator iBegin = listVertexSet .begin();
std::list <SVertexSet*>:: iterator iEnd = listVertexSet .end();
for( ; iBegin != iEnd; ++ iBegin )
{
SVertexSet* pVertexSet = (*iBegin);
if( pVertexSet ->nDestVertex == Vertex_No_Connection )
continue;
if( pVertexSet ->nMinEdgeToOtherSet < nMinEdge )
{
iFind = iBegin;
nMinEdge = pVertexSet ->nMinEdgeToOtherSet;
}
}
if( iFind == listVertexSet. end() || !(*iFind ) || nMinEdge == Vertex_Max_Edge_Value )
{
std::cout <<"异常 "<<std ::endl;
system( "pause" );
return 0;
}
SVertexSet* pFindMinEdge = (*iFind);
SVertexSet* pDestMinEdgeVertex = (*iFind )->pNextDestVetex;
if( !pFindMinEdge || !pDestMinEdgeVertex )
{
std::cout <<"异常 "<<std ::endl;
system("pause" );
return 0;
}
// 输出最短路径
std::cout <<" SourceNode:"<< pFindMinEdge->nSourceVertex <<" DestNode:"<< pFindMinEdge->nDestVertex <<" EdgeValue: "<< pFindMinEdge->nMinEdgeToOtherSet <<std:: endl;
// 1. 更新合并后的集合
CombineSet( pFindMinEdge , pDestMinEdgeVertex );
// 2. 更新指向pDestMinEdgeVertex 指向pFind
iBegin = listVertexSet .begin();
for( ; iBegin != iEnd; ++ iBegin )
{
if( (*iBegin ) && (*iBegin)-> pNextDestVetex == pDestMinEdgeVertex )
(* iBegin)->pNextDestVetex = pFindMinEdge ;
}
// 将Begin 集合删除
std::list <SVertexSet*>:: iterator iFindDest = listVertexSet .begin();
std::list <SVertexSet*>:: iterator iFindEnd = listVertexSet .end();
for( ; iFindDest != iFindEnd; ++ iFindDest )
{
if( (*iFindDest ) == pDestMinEdgeVertex )
break;
}
//pDestMinEdgeVertex
if( pDestMinEdgeVertex )
delete pDestMinEdgeVertex ;
if( iFindDest != iFindEnd )
listVertexSet.erase ( iFindDest );
}
system( "pause" );
return 0;
}
0 0
- Krusal算法 方法一
- Krusal算法 方法2
- krusal算法正确性的证明
- 还是畅通工程 krusal算法
- 常用算法设计方法(一) --- 迭代法
- poj1679(prim或者krusal的变形)
- 算法设计方法(一) —— 贪心法
- 学习排序算法(一):单文档方法 Pointwise
- String 常用方法最优算法实现总结 (一)
- 划分方法聚类(一) K-MEANS算法
- 【算法】CTR预估中的贝叶斯平滑方法(一)
- 算法一
- 算法一
- 算法一
- 机器学习算法(一)——关联规则Apriori算法及R语言实现方法
- Java虚拟机垃圾回收(一) 基础:回收哪些内存/对象 引用计数算法 可达性分析算法 finalize()方法 HotSpot实现
- 深度剖析排序算法(一)——冒泡排序内涵及其改进方法。
- 小游戏算法系列一之俄罗斯方块矩阵旋转的一种方法
- Oracle中查表时,当某列值为null时怎么替代
- 如何解决Java.lang.NoClassDefFoundError(键人岐)
- OpenVPN的性能极限
- [汇编] 免杀常用等价替换汇编指令修改方法
- Python 起步二 循环与逻辑,读取文件
- Krusal算法 方法一
- sip2peer服务端研究分享4:BS,SBC Server分析:
- java通过jdbc访问Access数据库
- 我的精华文章索引(持续更新中)
- Krusal算法 方法2
- 【USACO 2013 January Gold】座位 --线段树
- linux ipcs 和ipcrm 使用例子
- 关于iOS tabBar隐藏和显示问题
- 摘自C指针编程之道-队列