AOE 关键路径求解

//   求解关键路径

//   效率极低   最好使用   矩阵   或者十字链表

//   若采用十字链表和矩阵可以大幅度的提高效率

#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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值