有事您Q我 #div_digg { position: fixed; bottom: 10px; right: 15px; border: 2px solid #ECD7B1; padding: 10px; width: 140px; background-color: #fff; border-radius: 5px 5px 5px 5px !important; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); }

关键路径(CriticalPath)算法

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <malloc.h>
  4 
  5 #define MAXVEX 30        //最大顶点数
  6 #define MAXEDGE 30        //最大边数
  7 #define INFINITY 65535    //
  8 
  9 //定义全局变量
 10 int *etv, *ltv;//事情最早发生和最迟发生指针数组
 11 int *stack2;//用于存储拓扑排序的栈
 12 int top2;//用于指向stack2栈指针
 13 
 14 /*    邻接矩阵结构    */
 15 typedef struct
 16 {
 17     int vexs[MAXVEX];//顶点下标
 18     int arc[MAXVEX][MAXVEX];//矩阵(路径)
 19     int numVertexes, numEdges;//当前图中的顶点数和边数
 20 }MGraph;
 21 
 22 
 23 /*    邻接表结构    */
 24 typedef struct EdgeNode    //
 25 {//边表结点
 26     int adjvex;//顶点下标
 27     int weight;//路径
 28     struct EdgeNode *next;//指向想一个边表结点
 29 }EdgeNode;
 30 
 31 typedef struct VertexNode
 32 {//顶点结点
 33     int in;//入度
 34     int data;//顶点信息
 35     EdgeNode *firstedge;//指向边表头指针
 36 }VertexNode, AdjList[MAXVEX];
 37 
 38 typedef struct
 39 {
 40     AdjList adjList;//顶点向量
 41     int numVertexes, numEdges;//顶点数和边数
 42 }graphAdjList, *GraphAdjList;
 43 
 44 
 45 
 46 void CreateMGraph(MGraph *G)
 47 {/*    构建图    */
 48     int i, j;
 49 
 50 //    printf("请输入顶点数和边数:\n");
 51     G->numVertexes = 10;
 52     G->numEdges = 13;
 53 
 54     //初始化顶点下标
 55     for(i=0; i<G->numVertexes; i++)
 56         G->vexs[i] = i;
 57 
 58     //初始化矩阵
 59     for(i=0; i<G->numVertexes; i++)
 60         for(j=0; j<G->numVertexes; j++)
 61             if(i == j)
 62                 G->arc[i][j] = 0;
 63             else
 64                 G->arc[i][j] = INFINITY;
 65 
 66     //内置输入
 67     G->arc[0][1] = 3;
 68     G->arc[0][2] = 4;
 69     G->arc[1][3] = 5;
 70     G->arc[1][4] = 6;
 71     G->arc[2][3] = 8;
 72     G->arc[2][5] = 7;
 73     G->arc[3][4] = 3;
 74     G->arc[4][6] = 9;
 75     G->arc[4][7] = 4;
 76     G->arc[5][7] = 6;
 77     G->arc[6][9] = 2;
 78     G->arc[7][8] = 5;
 79     G->arc[8][9] = 3;
 80 
 81     return ;
 82 }
 83 
 84 
 85 
 86 void CreateALGraph(MGraph G, GraphAdjList *GL)
 87 {/*    利用邻接矩阵,构建邻接表    */
 88     int i, j;
 89     EdgeNode *e;
 90     
 91     *GL = (GraphAdjList)malloc(sizeof(graphAdjList));//*GL代表主函数的GL指向
 92     (*GL)->numVertexes = G.numVertexes;/*    读取信息    */
 93     (*GL)->numEdges = G.numEdges;
 94 
 95     //初始化
 96     for(i=0; i<G.numVertexes; i++)
 97     {
 98         (*GL)->adjList[i].in = 0;
 99         (*GL)->adjList[i].data = G.vexs[i];//读取顶点下标
100         (*GL)->adjList[i].firstedge = NULL;
101     }
102 
103     //构建邻接表
104     for(i=0; i<G.numVertexes; i++)
105         for(j=0; j<G.numVertexes; j++)
106             if(0 != G.arc[i][j]  &&  INFINITY > G.arc[i][j])
107             {//若存在路径
108                 e = (EdgeNode *)malloc(sizeof(EdgeNode));//申请
109                 e->adjvex = j;//存顶点
110                 e->weight = G.arc[i][j];//存路径
111                 e->next = (*GL)->adjList[i].firstedge;//存表头指针
112                 (*GL)->adjList[i].firstedge = e;//头插
113                 (*GL)->adjList[j].in ++;//顶点入度+1
114             }
115     return ;
116 }
117 
118 
119 
120 void TopologicalSort(GraphAdjList GL)
121 {/*    拓扑排序    */
122     EdgeNode *e;
123     int i, gettop, k;
124     int top = 0;//用于指向stack栈顶
125     int count = 0;//技术输出
126     int *stack;//建栈存储入度位0的顶点
127     stack = (int *)malloc(sizeof(int));
128     for(i=0; i<GL->numVertexes; i++)//把所有入度位0的顶点如stack栈中
129         if(0 == GL->adjList[i].in)
130             stack[++top] = i;
131     
132     etv = (int *)malloc(sizeof(int) * GL->numVertexes);//最早发生etv指针申请空间
133     for(i=0; i<GL->numVertexes; i++)//初始化最早发生etv数组
134         etv[i] = 0;
135 
136     stack2 = (int *)malloc(sizeof(int) * GL->numVertexes);//存储拓扑排序序列
137     top2 = 0;//用于指向stack2栈顶
138     printf("Topological:\t");
139     while(0 != top)
140     {//若有顶点入度为0
141         gettop = stack[top--];//出栈
142         printf("%3d->", GL->adjList[gettop].data);//输出出栈的栈顶的顶点信息
143         count ++;//输出记数
144 
145         stack2[++top2] = gettop;//出栈元素赋给存储拓扑序列栈
146         
147         for(e=GL->adjList[gettop].firstedge; e; e=e->next)
148         {//出栈的栈顶元素若有邻接点
149             k = e->adjvex;//邻接点-顶点下标
150             if(! (--GL->adjList[k].in))//邻接点顶点下标-1(gettop已指向),是否入度位0?
151                 stack[++top] = k;//是则入stack的栈
152 
153             /*出栈的最早发生时间值+出栈邻接表的路径  >  出栈邻接表顶点下标的最早发生时间值
154               就是v0-v1-v3和v0-v2-v3都是从起点到达汇点,3哪一个路径较远    */
155             if((etv[gettop] + e->weight) > etv[k])
156                 etv[k] = etv[gettop] + e->weight;
157         }
158     }
159     printf("\n");
160 
161     if(count < GL->numVertexes)//若有环,则结束程序
162         exit(-1);
163 
164     return ;
165 }
166 
167 
168 
169 void CriticalPath(GraphAdjList GL)
170 {/*    关键路径    */
171     EdgeNode *e;
172     int i, gettop, k, j;
173     int ete, lte;//最早发生和最迟发生的变量
174 
175     TopologicalSort(GL);//调用拓扑排序函数
176 
177     ltv = (int *)malloc(sizeof(int) * GL->numVertexes);//最迟发生指针边表指向申请空间
178     for(i=0; i<GL->numVertexes; i++)//初始化最迟发生数组
179         ltv[i] = etv[GL->numVertexes - 1];//起到汇最大值
180 
181     //输出最早发生数组
182     printf("etv:\t\t");
183     for(i=0; i<GL->numVertexes; i++)
184         printf("%3d->", etv[i]);
185     printf("\n");
186     
187     while(0 != top2)
188     {//存放拓扑排序数列
189         gettop = stack2[top2--];
190         for(e=GL->adjList[gettop].firstedge; e; e=e->next)
191         {
192             k = e->adjvex;
193             if((ltv[k] - e->weight) < ltv[gettop])
194                 ltv[gettop] = ltv[k] - e->weight;
195             /*最晚发生时间值(出stack2(存拓扑排序)栈元素的邻接点顶点下标) - 邻接路径   <    最晚发生数组【出栈元素0】
196               用拓扑排序的最长路径 - 邻接路径 < 最晚发生值[出栈元素]*/
197         }
198     }
199 
200     printf("ltv:\t\t");//输出最晚值数组
201     for(i=0; i<GL->numVertexes; i++)
202         printf("%3d->", ltv[i]);
203     printf("\n");
204 
205     for(j=0; j<GL->numVertexes; j++)
206         for(e=GL->adjList[j].firstedge; e; e=e->next)
207         {
208             k = e->adjvex;
209             ete = etv[j];//最早发生时间
210             lte = ltv[k] - e->weight;//最迟发生时间
211 
212             if(ete == lte)//相等即在关键路径上
213                 printf("<v%d - v%d> length : %d \n", GL->adjList[j].data, GL->adjList[k].data, e->weight);
214         }
215 
216     return ;
217 }
218 
219 int main(void)
220 
221 {    
222     MGraph G;
223     GraphAdjList GL;
224     system("title 关键路径");
225     CreateMGraph(&G);
226     CreateALGraph(G, &GL);
227     CriticalPath(GL);
228 
229     return 0;
230 }

 

posted @ 2015-03-11 22:31  次奥哥  阅读(2076)  评论(0编辑  收藏  举报
有事您Q我 #div_digg { position: fixed; bottom: 10px; right: 15px; border: 2px solid #ECD7B1; padding: 10px; width: 140px; background-color: #fff; border-radius: 5px 5px 5px 5px !important; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); }