精华内容
下载资源
问答
  • 关键路径法

    2012-05-25 11:39:04
    关键路径法(Critical Path Method, CPM)是一种基于数学计算的项目计划管理方法,是网络...在关键路径法的活动上加载资源后,还能够对项目的资源需求和分配进行分析。关键路径法是现代项目管理中最重要的一种分析工具。
  • CPM关键路径法

    2021-04-22 17:09:05
    目录CPM关键路径法定义构造方法CPM中节点表示例题关键路径的意义: CPM关键路径法 定义 关键路径法(CriticalPath ...在关键路径法的活动上加载资源后,还能够对项目的资源需求和分配进行分析。关键路径法是现代项目管

    CPM关键路径法

    定义

    关键路径法(CriticalPath Method, CPM)是一种基于数学计算的项目计划管理方法,是网络图计划方法的一种。关键路径法将项目分解成为多个独立的活动并确定每个活动的工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始-结束)将活动连接,从而能够计算项目的工期、各个活动时间特点(最早最晚时间、时差)等。在关键路径法的活动上加载资源后,还能够对项目的资源需求和分配进行分析。关键路径法是现代项目管理中最重要的一种分析工具。

    构造方法

    • 项目网络只有一个起点only one start node
    • 项目网络只有一个终点only one end node
    • 连接(表示一个活动)有持续时间a link has duration
    • 节点无持续时间nodes have no duration
    • 时间从左到右time moves from left to right
    • 节点顺序编号nodes are numbered sequentially
    • 网络不包含圈a network may not contain loop
    • 网络不包含悬点(dangle)
    • 前置是指某活动紧前活动Precedents are the immediate preceding activities
    例如:
    下列网络图中哪些存在错误:
    在这里插入图片描述
    在这里插入图片描述

    • 关键路径法主要关注两个目标:

    – 尽快完成整个项目
    – 识别那些一旦延期将对整个项目周期产生影响的活动
    

    • 对每一个活动赋予持续时间后,我们可以采用前向路径(forward pass)计算项目和各个活动的最早发生(完成/开始)时间,采用反向路径法(backward pass)计算项目和活动的最晚发生(完成/开始)时间

    CPM中节点表示

    • Event number: 事件编号
    • Earliest Date:最早(开始/完成)时间
    • Latest Date:最晚(开始/完成)时间
    • Slack:松弛时间
    在这里插入图片描述

    例题

    在这里插入图片描述
    1.根据题目首先画出活动网络图如下:
    在这里插入图片描述
    2.前向路径的计算以及后向路径计算
    forward pass前向路径计算:
    •一个活动的最早开始时间(EST)就是它的开始节点的最早完成时间
    •一个活动的最早完成时间(EFT)就是它的结束节点的最早完成时间
    在这里插入图片描述
    3.松弛时间
    最早开始时间和最晚开始时间的差称为松弛时间(Slack),它表示一个事件推迟多少时间可以不影响项目的结束。Slack为0的事件为关键事件,将关键事件连接起来的最长路径为关键路径
    在这里插入图片描述

    关键路径的意义:

    – 必须保证关键路径上的资源和关键路径活动顺利执行
    – 要缩短整个项目周期,必须缩短关键路径

    展开全文
  • 关键路径

    千次阅读 2018-10-14 15:54:58
    首先贴一下百度百科对CPM的定义: 关键路径法(Critical Path Method, CPM)是一种基于数学计算的项目计划管理方法,是网络图计划方法的一种,属于肯定型的网络图。关键路径法将项目分解成为多个...在关键路径法的活动...

    首先贴一下百度百科对CPM的定义:

    关键路径法(Critical Path Method, CPM)是一种基于数学计算的项目计划管理方法,是网络图计划方法的一种,属于肯定型的网络图。关键路径法将项目分解成为多个独立的活动并确定每个活动的工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始结束)将活动连接,从而能够计算项目的工期、各个活动时间特点(最早最晚时间、时差)等。在关键路径法的活动上加载资源后,还能够对项目的资源需求和分配进行分析。关键路径法是现代项目管理中最重要的一种分析工具。

    最早开始时间:活动开始的最早时间
    最晚开始时间:在保证不延期的前提下可以开始的最晚时间

    对于给定的活动图求出他的关键路径,最早和最晚开始时间一般采用回溯法,通俗讲就是从结束节点回推各个节点的开始时间。下面用一个例子展示这种算法:

    如图,求出关键路径,最早开始时间和最晚开始时间,时差和各个活动的前驱节点。
    这里写图片描述
    在这里插入图片描述
    求各个路径的总权值,权值最大的即为关键路径
    ABDIJL 权值为3+5+2+2+8=20
    ABDIJKL 权值为3+5+2+2+2+3=17
    ABIJL 权值为19
    ABIJKL 权值为16
    AEGJL 权值为17
    AEGJKL 权值为14
    AEGHKL 权值为17
    ACFHKL 权值为16
    由此可知关键路径为ABDIJL。
    回溯求出最早,最晚开始时间和差值

    !!!!:对于关键路径上的活动最早最晚开始时间的差值始终为0;
    最晚开始时间=后驱节点对应的时间-活动时间
    (如果后驱节点对应多个时间,选取最小的那个)

    最早开始时间=max{到达前驱结点的路径权值}+1
    (这个加1是为什么呢?举个例子,一个工程的前半部分需要20天,从月初的1号开始,在20号正好完成,所以后半部分工程从21号开始)
    e.p.
    活动KL的的前驱节点为K,
    最晚开始时间=(20+1)-3=18
    (此处加1意义同上,但在计算最晚开始时间时只在最后活动加1,其他活动不必再加1,考虑考虑,这是符合常理的)
    最早开始时间=max{c(ABDIJ),c(ABIJ),c(AEGJ),c(AEGH),c(ACFH)}+1=15
    所以,
    KL: Precursor{K} , Earliest start Time:15, latest Start Time:18 Slacktime:3;

    在计算一个HK:
    通过计算KL我们知道K对应的最晚开始 时间为18
    最晚开始时间=18-4=14
    最早开始时间=11(方法同上)

    所以此题所有答案如下:

    AB: Precursor{A} , Earliest start Time:1, latest Start Time:1 Slacktime:0;
    BD: Precursor{B} , Earliest start Time:4, latest Start Time:4 Slacktime:0;
    DI: Precursor{D} , Earliest start Time:9, latest Start Time:9 Slacktime:0;
    BI: Precursor{B} , Earliest start Time:4, latest Start Time:5 Slacktime:1;
    AE: Precursor{A} , Earliest start Time:1, latest Start Time:5 Slacktime:3;
    EG: Precursor{E} , Earliest start Time:5, latest Start Time:8 Slacktime:3;
    GJ: Precursor{G} , Earliest start Time:8, latest Start Time:11 Slacktime:3;
    GH: Precursor{G} , Earliest start Time:8, latest Start Time:11 Slacktime:3;
    IJ: Precursor{I} , Earliest start Time:11, latest Start Time:11 Slacktime:0;
    AC: Precursor{A} , Earliest start Time:1, latest Start Time:5 Slacktime:4;
    CF: Precursor{A} , Earliest start Time:6, latest Start Time:10 Slacktime:4;
    FH: Precursor{F} , Earliest start Time:9, latest Start Time:13 Slacktime:4;
    HK: Precursor{H} , Earliest start Time:11, latest Start Time:14 Slacktime:3;
    JK: Precursor{J} , Earliest start Time:13, latest Start Time:16 Slacktime:3;
    JL: Precursor{J} , Earliest start Time:13, latest Start Time:13 Slacktime:0;
    KL: Precursor{K} , Earliest start Time:15, latest Start Time:18 Slacktime:3;

    另外需要说明一点的是,在计算最晚开始时间时,如果后驱节点对应多个时间,选取最小的那个。
    例如,IJ
    J对应的最晚开始时间分别出现在JK和JL,选取小的那个13。
    转载于https://www.cnblogs.com/wonpangnew/p/5171295.html
    若侵立删

    展开全文
  • 的关键路径算法

    千次阅读 2011-11-20 21:02:18
    关键路径法将项目分解成为多个独立活动并确定每个活动工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始结束)将活动连接,从而能够计算项目工期、各个活动时间特点(最早最晚时间、时差)等。...
     
    

    关键路径法(Critical Path Method, CPM)是一种基于数学计算的项目计划管理方法,是网络图计划方法的一种,属于肯定型的网络图。关键路径法将项目分解成为多个独立的活动并确定每个活动的工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始结束)将活动连接,从而能够计算项目的工期、各个活动时间特点(最早最晚时间、时差)等。

     

    头文件:CriticalPath.h

    #ifndef CRITICALPATH_H
    #define CRITICALPATH_H
    #define MAXVEX 20
    typedef int VertexType;  //图的顶点数据类型
    typedef struct edgenode{
    	int AdjVex;   //顶点的下标值
    	int weight;   //顶点的权值
    	struct edgenode* next;  //指向下一个边集点
    }EdgeNode;
    typedef struct vertexnode{
    	VertexType data; //顶点信息
    	int in; //顶点的入度
    	EdgeNode *FirstEdge;  //指向边集点
    }VertexNode;
    typedef struct graph{
    	VertexNode Vertex[MAXVEX]; //图的顶点集
    	int NumVertex,NumEdge; //图的顶点数和边数
    }Graph;
    
    void CreateGraph(Graph *G); //创建图
    void TopoLogicalSort(Graph *G); //拓扑排序算法
    void CriticalPath(Graph *G); //关键路径算法
    #endif //CRITICALPATH_H
    


    实现文件:CriticalPath.cpp

    #include "CriticalPath.h"
    #include <stdio.h>
    #include <stdlib.h>
    int *etv,*ltv; //事件最早发生时间和最迟发生时间数组
    int top2; //用于Stack2的指针
    int *Stack2; //用于存储拓扑序列的栈
    void CreateGraph(Graph *G) //创建图
    {
    	EdgeNode *e = NULL;
    	G->NumVertex = 10;
    	G->NumEdge = 13;
    	for(int i = 0;i < G->NumVertex;++i)
    	{
    		G->Vertex[i].data = i;
    		G->Vertex[i].in = 0;
    		G->Vertex[i].FirstEdge = NULL;
    	}
    	//顶点间的连接信息
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v0 -> v1 权值为3
    	e->next = G->Vertex[0].FirstEdge;
    	e->AdjVex = 1;
    	e->weight = 3;
    	G->Vertex[0].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v0 -> v2 权值为4
    	e->next = G->Vertex[0].FirstEdge;
    	e->AdjVex = 2;
    	e->weight = 4;
    	G->Vertex[0].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v1 -> v3 权值为5
    	e->next = G->Vertex[1].FirstEdge;
    	e->AdjVex = 3;
    	e->weight = 5;
    	G->Vertex[1].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v1 -> v4 权值为6
    	e->next = G->Vertex[1].FirstEdge;
    	e->AdjVex = 4;
    	e->weight = 6;
    	G->Vertex[1].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v2 -> v3 权值为8
    	e->next = G->Vertex[2].FirstEdge;
    	e->AdjVex = 3;
    	e->weight = 8;
    	G->Vertex[2].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v2 -> v5 权值为7
    	e->next = G->Vertex[2].FirstEdge;
    	e->AdjVex = 5;
    	e->weight = 7;
    	G->Vertex[2].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v3 -> v4 权值为3
    	e->next = G->Vertex[3].FirstEdge;
    	e->AdjVex = 4;
    	e->weight = 3;
    	G->Vertex[3].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v4 -> v6 权值为 9
    	e->next = G->Vertex[4].FirstEdge;
    	e->AdjVex = 6;
    	e->weight = 9;
    	G->Vertex[4].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v4 -> v7 权值 4
    	e->next = G->Vertex[4].FirstEdge;
    	e->AdjVex = 7;
    	e->weight = 4;
    	G->Vertex[4].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v5 -> v7 权值为6
    	e->next = G->Vertex[5].FirstEdge;
    	e->AdjVex = 7;
    	e->weight = 6;
    	G->Vertex[5].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v6 -> v9 权值为2
    	e->next = G->Vertex[6].FirstEdge;
    	e->AdjVex = 9;
    	e->weight = 2;
    	G->Vertex[6].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v7 -> v8 权值为5
    	e->next = G->Vertex[7].FirstEdge;
    	e->AdjVex = 8;
    	e->weight = 5;
    	G->Vertex[7].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    
    	e = (EdgeNode*)malloc(sizeof(EdgeNode)); //v8 -> v9 权值为3
    	e->next = G->Vertex[8].FirstEdge;
    	e->AdjVex = 9;
    	e->weight = 3;
    	G->Vertex[8].FirstEdge = e;
    	++G->Vertex[e->AdjVex].in;
    }
    void TopoLogicalSort(Graph *G)
    {
    	int *Stack; //用于存储入度为0的顶点下标
    	int top = 0; //Stack栈的指针
    	int count = 0; //统计输出的顶点数
    	int gettop; //去除的顶点下标
    	Stack = (int *)malloc(sizeof(int) * G->NumVertex);
    	top2 = 0;
    	Stack2 = (int *)malloc(sizeof(int) * G->NumVertex); //存储拓扑排序的序列
    	for(int i = 0;i < G->NumVertex;++i)
    	{
    		if(!(G->Vertex[i].in)) //将入度为0的顶点存储在Stack栈中
    			Stack[++top] = i;
    	}
    	etv = (int*)malloc(sizeof(int) * G->NumVertex);
    	for(int i = 0;i < G->NumVertex;++i) //事件最早发生时间初始化为0
    	{
    		etv[i] = 0;
    	}
    	while(top != 0) //Stack栈不为空,即还有未处理完的顶点
    	{
    		gettop = Stack[top--]; //出栈
    		count++;
    		Stack2[++top2] = gettop; //将已处理的顶点压入Stack2栈中
    //		printf("V%d ",G->Vertex[gettop].data);
    		for(EdgeNode *e = G->Vertex[gettop].FirstEdge;e;e = e->next) //处理下标为gettop的顶点所连接的顶点
    		{
    			int k = e->AdjVex;
    			if(!(--G->Vertex[k].in)) //如果被指向的顶点入度减1为0的话压入Stack栈中
    				Stack[++top] = k;
    			if(etv[gettop] + e->weight > etv[k]) //事件最早发生的时间
    				etv[k] = etv[gettop] + e->weight;
    		}
    	}
    //	printf("\n");
    	if(count < G->NumVertex) //如果顶点没有完全输出
    	{
    		printf("拓扑排序错误,程序即将退出:\n");
    		system("pause");
    		exit(1);
    	}
    }
    void CriticalPath(Graph *G)
    {
    	int ete,lte; //声明事件最早发生时间和最迟发生时间的变量
    	TopoLogicalSort(G); //拓扑排序求事件的最早发生时间和拓扑序列Stack2
    	ltv = (int *)malloc(sizeof(EdgeNode) * G->NumVertex);
    	for(int i = 0;i < G->NumVertex;++i) //初始化事件最晚发生时间
    	{
    		ltv[i] = etv[G->NumVertex - 1];
    	}
    	while(top2 != 0) //如果Stack2栈不为空
    	{
    		int gettop = Stack2[top2--]; //出栈
    		for(EdgeNode *e = G->Vertex[gettop].FirstEdge;e;e = e->next) //处理下标为gettop的顶点所连接的顶点
    		{
    			int k = e->AdjVex;
    			if(ltv[k] - e->weight < ltv[gettop])
    				ltv[gettop] = ltv[k] - e->weight;
    		}
    	}
    	for(int i = 0;i < G->NumVertex;++i)
    	{
    		for(EdgeNode *e = G->Vertex[i].FirstEdge;e;e = e->next)
    		{
    			int k = e->AdjVex;
    			ete = etv[i];  //事件最早发生时间
    			lte = ltv[k] - e->weight; //事件最晚发生时间
    			if(ete == lte) //相等即在关键路径上
    			{
    				printf(" <V%d -> V%d) weight: %d\n",G->Vertex[i].data,G->Vertex[k].data,e->weight);
    			}
    		}
    	}
    }


    测试文件:main.cpp

    #include "CriticalPath.h"
    int main()
    {
    	Graph G;
    	CreateGraph(&G);
       	CriticalPath(&G);
    	return 0;
    }


     

    展开全文
  • 关键路径法将项目分解成为多个独立活动并确定每个活动工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始结束)将活动连接,从而能够计算项目工期、各个活动时间特点(最早最晚时间、时差)等。...

    首先贴一下百度百科对CPM的定义:

    关键路径法(Critical Path Method, CPM)是一种基于数学计算的项目计划管理方法,是网络图计划方法的一种,属于肯定型的网络图。关键路径法将项目分解成为多个独立的活动并确定每个活动的工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始结束)将活动连接,从而能够计算项目的工期、各个活动时间特点(最早最晚时间、时差)等。在关键路径法的活动上加载资源后,还能够对项目的资源需求和分配进行分析。关键路径法是现代项目管理中最重要的一种分析工具。

    最早开始时间:活动开始的最早时间 
    最晚开始时间:在保证不延期的前提下可以开始的最晚时间

    对于给定的活动图求出他的关键路径,最早和最晚开始时间一般采用回溯法,通俗讲就是从结束节点回推各个节点的开始时间。下面用一个例子展示这种算法

    如图,求出关键路径,最早开始时间和最晚开始时间,时差和各个活动的前驱节点。 
    这里写图片描述

    1. 求各个路径的总权值,权值最大的即为关键路径 
      ABDIJL 权值为3+5+2+2+8=20 
      ABDIJKL 权值为3+5+2+2+2+3=17 
      ABIJL 权值为19 
      ABIJKL 权值为16 
      AEGJL 权值为17 
      AEGJKL 权值为14 
      AEGHKL 权值为17 
      ACFHKL 权值为16 
      由此可知关键路径为ABDIJL。
    2. 回溯求出最早,最晚开始时间和差值

      **!!!!:对于关键路径上的活动最早最晚开始时间的差值始终为0; 
      最晚开始时间=后驱节点对应的时间-活动时间 
      (如果后驱节点对应多个时间,选取最小的那个)** 
      最早开始时间=max{到达前驱结点的路径权值}+1 
      (这个加1是为什么呢?举个例子,一个工程的前半部分需要20天,从月初的1号开始,在20号正好完成,所以后半部分工程从21号开始) 
      e.p. 
      活动KL的的前驱节点为K, 
      最晚开始时间=(20+1)-3=18 
      (此处加1意义同上,但在计算最晚开始时间时只在最后活动加1,其他活动不必再加1,考虑考虑,这是符合常理的) 
      最早开始时间=max{c(ABDIJ),c(ABIJ),c(AEGJ),c(AEGH),c(ACFH)}+1=15 
      所以, 
      KL: Precursor{K} , Earliest start Time:15, latest Start Time:18 Slacktime:3;

    在计算一个HK: 
    通过计算KL我们知道K对应的最晚开始 时间为18 
    最晚开始时间=18-4=14 
    最早开始时间=11(方法同上)

    所以此题所有答案如下:

    AB: Precursor{A} , Earliest start Time:1, latest Start Time:1 Slacktime:0; 
    BD: Precursor{B} , Earliest start Time:4, latest Start Time:4 Slacktime:0; 
    DI: Precursor{D} , Earliest start Time:9, latest Start Time:9 Slacktime:0; 
    BI: Precursor{B} , Earliest start Time:4, latest Start Time:5 Slacktime:1; 
    AE: Precursor{A} , Earliest start Time:1, latest Start Time:5 Slacktime:3; 
    EG: Precursor{E} , Earliest start Time:5, latest Start Time:8 Slacktime:3; 
    GJ: Precursor{G} , Earliest start Time:8, latest Start Time:11 Slacktime:3; 
    GH: Precursor{G} , Earliest start Time:8, latest Start Time:11 Slacktime:3; 
    IJ: Precursor{I} , Earliest start Time:11, latest Start Time:11 Slacktime:0; 
    AC: Precursor{A} , Earliest start Time:1, latest Start Time:5 Slacktime:4; 
    CF: Precursor{A} , Earliest start Time:6, latest Start Time:10 Slacktime:4; 
    FH: Precursor{F} , Earliest start Time:9, latest Start Time:13 Slacktime:4; 
    HK: Precursor{H} , Earliest start Time:11, latest Start Time:14 Slacktime:3; 
    JK: Precursor{J} , Earliest start Time:13, latest Start Time:16 Slacktime:3; 
    JL: Precursor{J} , Earliest start Time:13, latest Start Time:13 Slacktime:0; 
    KL: Precursor{K} , Earliest start Time:15, latest Start Time:18 Slacktime:3;

    另外需要说明一点的是,在计算最晚开始时间时,如果后驱节点对应多个时间,选取最小的那个。 
    例如,IJ 
    J对应的最晚开始时间分别出现在JK和JL,选取小的那个13。

    由于最近在学习软件工程这门课程,所以按照官方定义自己捉摸了这个做题的路子,有什么不对的还请指正。

    展开全文
  • 关键路径法将项目分解成为多个独立活动并确定每个活动工期,然后用逻辑关系(结束-开始、结束-结束、开始-开始和开始结束)将活动连接,从而能够计算项目工期、各个活动时间特点(最早最晚时间...
  • 针对传统自主导航车(AGV)无法满足高精度路径跟踪和关键点精确定位问题,首次提出一种基于模糊控制的路径纠偏和二维码的关键点精确定位组合方法。首先建立AGV四轮差动运动学模型,以位置偏差和角度偏差作为输入,...
  • 循环取货车辆路径问题特点是取货车辆按照设计好的路径在规定时间窗口内从供应商处将货物运送至汽车厂,同时将从汽车厂返回空箱送回供应商处。循环取货是小批量、多频次、及时、闭环拉动式取货模式,具有节省...
  • 考虑超高压故障限流器在大电网中应用特点,以获取预设全局限流效果和确保配置最优经济性为目标,基于邻接转移阻抗灵敏度加权值,提出一种能够区分短路电流关键路径、反映限流经济代价、指示全局限流效果及均衡水平...
  • 关键路径* 9 算法分析与设计*(2-3学时) 10 稀疏矩阵和广义表*(2-3学时) 稀疏矩阵存储 广义表基本概念 五、上机实践 1. 在课程前12周,学生应当完成一批程序设计作业,主要内容为一些典型数据结构...
  • 项目管理002

    2013-03-29 15:26:06
    甘特图 关键路径法 计划评审技术(PERT) WBS 蒙特卡罗模拟技术和挣值分析技术 项目管理快速发展的特点:适应现代产品的创新速度;适应现代的复杂项目系统;适应以用户满意为核心的服务理念。 转载于:...

空空如也

空空如也

1 2 3 4 5 6
收藏数 117
精华内容 46
关键字:

关键路径法的特点