C语言拓扑拍序与关键路完整算法径,C语言代码记忆之拓扑排序与关键路径

#include

#include

#define MAX_VERTEX_NUM 10

#define MAX_STACK_VOLUME 30

typedef struct ArcNode { // Arc structure

int adjvex;

struct ArcNode *nextarc;

int weight;

}ArcNode;

typedef struct VNode { // Vertex structure

int data;

ArcNode *firstarc;

}VNode, AdjList[MAX_VERTEX_NUM];

typedef struct { // Adjacency List structure

AdjList vertices;

int vexnum;

int arcnum;

}ALGraph;

typedef struct { // The most simple stack structure

int stack[MAX_STACK_VOLUME];

int top;

}Stack;

/*

These functions are prepared for stack

*/

void initStack(Stack *s) {

int i;

s->top = 0;

for (i = 0; i < MAX_STACK_VOLUME; i++) {

s->stack[i] = -1;

}

}

void push(Stack*s, int value) {

s->stack[s->top] = value;

s->top++;

}

int pop(Stack *s) {

if (s->top == 0) {

printf("Stack had been empty\n");

return -1;

}

return s->stack[--s->top];

}

int empty(Stack s) {

return (s.top == 0) ? 1 : 0;

}

/*

These functions are prepared for ALGraph

*/

void createArc(ALGraph *alg, int start_v, int end_v, int weight) {

// Create arc for adjacency list

ArcNode *p_read = alg->vertices[start_v].firstarc;

ArcNode *p_new = (ArcNode *)malloc(sizeof(ArcNode));

p_new->adjvex = end_v;

p_new->weight = weight;

p_new->nextarc = NULL;

if (p_read != NULL) {

while (p_read->nextarc != NULL) {

p_read = p_read->nextarc;

}

p_read->nextarc = p_new;

} else {

alg->vertices[start_v].firstarc = p_new;

}

}

void createALG(ALGraph *alg, int vexnum, int arcnum) {

// Create adjacency list for sample

alg->vexnum = vexnum;

alg->arcnum = arcnum;

int i;

for (i = 0; i < vexnum; i++) {

alg->vertices[i].firstarc = NULL;

}

createArc(alg, 0, 1, 6);

createArc(alg, 0, 2, 4);

createArc(alg, 0, 3, 5);

createArc(alg, 1, 4, 1);

createArc(alg, 2, 4, 1);

createArc(alg, 3, 5, 2);

createArc(alg, 4, 6, 9);

createArc(alg, 4, 7, 8);

createArc(alg, 5, 7, 4);

createArc(alg, 6, 8, 2);

createArc(alg, 7, 8, 4);

}

void showALG(ALGraph alg) {

// Show ALGraph's adjacency list

printf("Show ALGraph: \n");

int i;

for (i = 0; i < alg.vexnum; i++) {

ArcNode *p_read = alg.vertices[i].firstarc;

if (p_read == NULL) printf("V%d\n", i);

else {

printf("V%d --> ", i);

while (p_read != NULL) {

printf("V%d(%d)", p_read->adjvex, p_read->weight);

p_read = p_read->nextarc;

if (p_read != NULL) printf(" --> ");

}

printf("\n");

}

}

}

void findIndegree(ALGraph alg, int indegree[]) {

// Put the ALGraph's vertices indegree into indegree[]

int i;

for (i = 0; i < alg.vexnum; i++) {

indegree[i] = 0;

}

for (i = 0; i < alg.vexnum; i++) {

ArcNode *p_read = alg.vertices[i].firstarc;

while (p_read != NULL) {

indegree[p_read->adjvex]++;

p_read = p_read->nextarc;

}

}

}

void TopologicalSort(ALGraph alg) {

// Topological sort for ALGraph without weight

printf("\nThe most simple topological sort without wight: (Not all sequences)\n");

int i;

int count;

int indegree[alg.vexnum];

findIndegree(alg, indegree);

/*for (i = 0; i < alg.vexnum; i++) {

printf("V%d's indegree is %d\n", i, indegree[i]);

}*/

// For simulate topological sort, we need a stack.

Stack stack;

initStack(&stack);

for (i = 0; i < alg.vexnum; i++) {

if (indegree[i] == 0) push(&stack, i);

}

count = 0;

while (!empty(stack)) {

int v = pop(&stack);

if (count == 0) printf("V%d", v);

else {

printf(", V%d", v);

}

count++;

ArcNode *p_read = alg.vertices[v].firstarc;

while (p_read != NULL) {

if ((--indegree[p_read->adjvex]) == 0) {

push(&stack, p_read->adjvex);

}

p_read = p_read->nextarc;

}

}

printf("\n");

if (count < alg.vexnum) {

printf("This ALGraph has loop\n");

}

}

/*

These two functions are used to find criticalpath

*/

int TopologicalOrder(ALGraph alg, Stack *t, int ve[]) {

// Topological sort for ALGraph and calculate the earliest time of vertices

int i;

int count;

int indegree[alg.vexnum];

Stack stack;

count = 0;

findIndegree(alg, indegree);

initStack(&stack);

for (i = 0; i < alg.vexnum; i++) {

ve[i] = 0;

if (indegree[i] == 0) push(&stack, i);

}

while(!empty(stack)) {

int v = pop(&stack);

push(t, v);

count++;

ArcNode *p_read = alg.vertices[v].firstarc;

while (p_read != NULL) {

int k = p_read->adjvex;

if((--indegree[k]) == 0) {

push(&stack, k);

}

if (ve[v] + p_read->weight > ve[k]) {

ve[k] = ve[v] + p_read->weight;

}

p_read = p_read->nextarc;

}

}

if (count < alg.vexnum) {

return 0; // This means the ALGraph has loop

}

return 1;

}

void findCriticalpath(ALGraph alg) {

// Finding critical path using topological and inverse topological sort

printf("\nThe critical path:\n");

Stack t;

int ve[alg.vexnum];

int vl[alg.vexnum];

int i;

initStack(&t);

if (TopologicalOrder(alg, &t, ve) == 0) {

printf("ERROR! The ALGraph has loop\n");

}

for (i = 0; i < alg.vexnum; i++) {

vl[i] = ve[alg.vexnum - 1];

}

while (!empty(t)) {

int v = pop(&t);

ArcNode *p_read = alg.vertices[v].firstarc;

while (p_read != NULL) {

int k = p_read->adjvex;

int durt = p_read->weight;

if (vl[k] - durt < vl[v]) {

vl[v] = vl[k] - durt;

}

p_read = p_read->nextarc;

}

}

for (i = 0; i < alg.vexnum; i++) {

ArcNode *p_read = alg.vertices[i].firstarc;

while (p_read != NULL) {

int k = p_read->adjvex;

int durt = p_read->weight;

if (ve[i] == vl[k] - durt) {

printf("V%d --%d--> V%d\n", i, durt, k);

}

p_read = p_read->nextarc;

}

}

}

int main() {

// Main entry and give a sample

printf("为了模拟拓扑排序和关键路径,假设一个项目将会有如下内容:\n");

printf("1\ 项目分为9个事件点(编号V0~8)\n");

printf("2\ 每个事件点之间(从一个事件点到另一个事件点名为活动)估算了时间\n\n");

printf("事件点之间有如下关系:(事件编号 --耗时--> 事件编号)\n");

printf("V0 --6--> V1 && V0 --4--> V2 && V0 --5-->V3\n");

printf("V1 --1--> V4\n");

printf("V2 --1--> V4\n");

printf("V3 --2--> V5\n");

printf("V4 --9--> V6 && V4 --8--> V7\n");

printf("V5 --4--> V7\n");

printf("V6 --2--> V8\n");

printf("V7 --4--> V8\n\n");

ALGraph alg;

createALG(&alg, 9, 11);

showALG(alg);

TopologicalSort(alg); //最简单的拓扑排序,不考虑路径权重

findCriticalpath(alg); //运用拓扑、逆拓扑顺序以及权重找关键路径

printf("\n");

getchar();

return 0;

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值