AOE 关键路径求解
来源:互联网 发布:生物医学数据挖掘 编辑:程序博客网 时间:2024/05/29 02:32
// 求解关键路径
// 效率极低 最好使用 矩阵 或者十字链表
// 若采用十字链表和矩阵可以大幅度的提高效率
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
enum
{
Vertex_No_Connection = -1,
Vertex_Total_Number = 9,
Vertex_Max_Edge_Value = 10000,
};
// 连接头结点的后面 next 结点
struct SNextHeadNode
{
int nVertexNode ;
int nEdgeValue ;
SNextHeadNode* pNextNode ;
};
// 头结点
struct SHeadNode
{
int nVertexNode;
SNextHeadNode* pFirstLink ;
};
SHeadNode * headNodeSet[ Vertex_Total_Number];
int InDgreeOfNodeSet[ Vertex_Total_Number];
int nPreOrderTag[ Vertex_Total_Number]; // 前向遍历产生的 Tag 标识
int nPostOrderTag[ Vertex_Total_Number]; // 后向遍历产生的 Tag 标识
int nSourceIndex; // 源点
int nMaxNodeIndex; // 汇点
void InitHeadList()
{
int nThreeItemNum [11][3] =
{
{ 0, 1, 6 }, { 0, 2, 4 }, { 0, 3, 5 }, { 1, 4, 1 },
{ 2, 4, 1 }, { 4, 6, 9 }, { 4, 7, 7 }, { 6, 8, 2 },
{ 7, 8, 4 }, { 3, 5, 2 }, { 5, 7, 4 }
};
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
headNodeSet[i ] = new SHeadNode;
if( !headNodeSet [i] )
{
std::cout <<"Error 1"<< std::endl ;
system( "pause" );
return ;
}
headNodeSet[i ]->nVertexNode = i;
headNodeSet[i ]->pFirstLink = NULL;
}
for( int i = 0; i < 11; ++i )
{
SNextHeadNode* pNextHeadNode = new SNextHeadNode ;
if( !pNextHeadNode )
{
std::cout <<"Error 2"<< std::endl ;
system( "pause" );
return ;
}
pNextHeadNode->pNextNode = NULL;
pNextHeadNode->nVertexNode = nThreeItemNum [i][1];
pNextHeadNode->nEdgeValue = nThreeItemNum [i][2];
// Front Insert
int nSourceIndex = nThreeItemNum[ i][0];
pNextHeadNode->pNextNode = headNodeSet [nSourceIndex]-> pFirstLink;
headNodeSet[nSourceIndex ]->pFirstLink = pNextHeadNode ;
}
}
void InitInDgreeOfNodeSet()
{
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
InDgreeOfNodeSet[i ] = 0;
}
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
SNextHeadNode* pLinkHeadNode = headNodeSet [i]-> pFirstLink;
while( pLinkHeadNode )
{
int nLinkNode = pLinkHeadNode-> nVertexNode;
++ InDgreeOfNodeSet[nLinkNode ];
pLinkHeadNode = pLinkHeadNode ->pNextNode;
}
}
}
void InitPreOrderTag()
{
// nPreOrderTag
for( int i = 0; i < Vertex_Total_Number ; ++i )
nPreOrderTag[i ] = 0;
}
void FindTheSourceIndex()
{
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
if( InDgreeOfNodeSet [i] == 0 )
{
nSourceIndex = i ;
break;
}
}
}
void SolutionPostNode( int nMaxValue , int nMaxIndex )
{
if( nMaxIndex == nSourceIndex )
return ;
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
int nSourceNodeIndex = headNodeSet [i]-> nVertexNode;
SNextHeadNode* pLinkNode = headNodeSet [i]-> pFirstLink;
while( pLinkNode )
{
int nDestNodeIndex = pLinkNode ->nVertexNode;
if( nDestNodeIndex == nMaxIndex )
{
int nEdgeValue = pLinkNode ->nEdgeValue;
if( nMaxValue - nEdgeValue < nPostOrderTag [nDestNodeIndex] )
{
nPostOrderTag[nSourceNodeIndex ] = nMaxValue - nEdgeValue;
SolutionPostNode( nPostOrderTag [nSourceNodeIndex], nSourceNodeIndex );
}
}
pLinkNode = pLinkNode ->pNextNode;
}
}
}
void Process()
{
FindTheSourceIndex();
// 寻找入度为的结点找到最长路径,即最短时间
while( 1 )
{
int nIndex = -1;
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
if( InDgreeOfNodeSet [i] == 0 )
{
nIndex = i ;
break;
}
}
if( nIndex == -1 )
break;
// 找到度数为点将其入度置为 -1
InDgreeOfNodeSet[nIndex ] = -1;
SNextHeadNode* pLinkNextNode = headNodeSet [nIndex]-> pFirstLink;
while( pLinkNextNode )
{
int nNodeIndex = pLinkNextNode ->nVertexNode;
int nEdgeValue = pLinkNextNode-> nEdgeValue;
-- InDgreeOfNodeSet[nNodeIndex ];
if( nPreOrderTag [nIndex] + nEdgeValue > nPreOrderTag [nNodeIndex] )
nPreOrderTag[nNodeIndex ] = nPreOrderTag [nIndex] + nEdgeValue;
pLinkNextNode = pLinkNextNode ->pNextNode;
}
}
// 求解nPost 后向结点的值
int nMaxValue = -1;
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
if( nPreOrderTag [i] > nMaxValue )
{
nMaxValue = nPreOrderTag[ i];
nMaxNodeIndex = i ;
}
}
for( int i = 0; i < Vertex_Total_Number ; ++i )
{
nPostOrderTag[i ] = nMaxValue;
}
SolutionPostNode( nMaxValue , nMaxNodeIndex );
nPostOrderTag[nSourceIndex ] = 0;
}
void PrintHelp( int nSource )
{
if( nSource == nMaxNodeIndex )
{
std::cout <<nSource<< std::endl ;
return ;
}
std::cout <<nSource<< "---->" ;
SNextHeadNode* pLinkNextHead = headNodeSet [nSource]-> pFirstLink;
while( pLinkNextHead )
{
int nVertexIndex = pLinkNextHead-> nVertexNode;
if( nPostOrderTag [nVertexIndex] == nPreOrderTag [nVertexIndex] )
{
PrintHelp( nVertexIndex );
}
pLinkNextHead = pLinkNextHead ->pNextNode;
}
}
void PrintPathInfo()
{
// 广度搜索。。。输出所有的最优解
PrintHelp( nSourceIndex );
}
int _tmain( int argc , _TCHAR* argv[])
{
InitHeadList();
InitInDgreeOfNodeSet ();
InitPreOrderTag();
Process();
PrintPathInfo();
system("pause" );
return 0;
}
0 0
- AOE 关键路径求解
- 算法:求解AOE网的关键路径
- 利用AOE网求解关键路径问题
- AOE 关键路径
- AOE求关键路径
- AOE关键路径
- AOE关键路径
- AOE关键路径
- AOE网--求关键路径
- 求关键路径、AOE网
- AOE图的关键路径
- AOE网与关键路径
- 关键路径与AOE网
- AOE网求关键路径
- 求关键路径(AOE)
- 关键路径(AOE网)
- AOE网上的关键路径
- AOE网上的关键路径
- 封装jquery ui 提示框
- linux进程间内存共享和信号量协作[基于哈工大操作系统实验]
- 《视频解密》中文版(第四版) 第五章 模拟视频接口
- 画个圈圈诅咒你们
- 三星Note3添加S Note笔记模板教程
- AOE 关键路径求解
- 6.3 Invoking Block Objects
- 雷军和周鴻祎:青春不会被浪費(孕峰)
- PHP -- array_walk()
- C++ 运行单个实例,防止程序多次启动
- 《视频解密》中文版(第四版) 第六章 数字视频接口(第一部分)
- 三星Note3使用技巧之S搜索功能如何使用
- linux 下简单文件读写
- iis集成验证小结