家的英文怎么写 关键路径法会计英文怎么写
关键路径法会计英文怎么写
关键路径法会计英文怎么写
关键路径法会计
[词典] [经] critical path aounting;
aounting
英 [əˈkaʊntɪŋ] 美 [əˈkaʊntɪŋ]
n. 会计; 会计学; 记账;
v. 记述,报告(aount的现在分词);
关键路径怎么算, 管理中关键路径怎么算?
关键路径是专案管理中进度控制的一个术语。关键路径法的4个关键步骤:
(1) 关键路径是专案网路图中最长的路径,他决定了专案的总耗时时间;
(2) 专案经理必须把注意力集中在那些优先等级较高的任务,确保他们准时完成,关键路径上任何活动的推迟都将导致整个专案推迟;
(3) 项关键路径要时间,向非关键路径要资源;

(4) 调整进度,平衡资源。
关键路径是指设计中从输入到输出经过的延时最长的逻辑路径。优化关键路径是一种提高设计工作速度的有效方法。一般地,从输入到输出的延时取决于讯号所经过的延时最大路径,而与其他延时小的路径无关。
在优化设计过程中关键路径法可以反复使用,直到不可能减少关键路径延时为止。EDA工具中综合器及设计分析器通常都提供关键路径的资讯以便设计者改进设计,提高速度。
关键路径唯一吗?
关键路径法(Critical Path Method,CPM),又称为要径法,是计划专案活动中用到的一种算术方法。对于有效的计划管理而言,关键路径是一个十分重要的工具。与计划评核术(Project Evaluation and Review Techniqu,PERT)非常类似。要径法所使用的估计作业时间是单一或确定的,而计划评核术则是使用机率性的估计作业时间。这两种技术经常混合使用,简称CPM/PERT
AOE 工程 关键路径
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
事件
struct Event
{
事件名称
char Name[100];
是否始发事件
bool IsBegin;
是否终点事件
bool IsEnd;
};
路径
struct Path
{
出发事件
char FromEventName[100];
到达事件
char ToEventName[100];
权重
int Height;
};
输入事件,返回生成的事件阵列并通过引数返回事件个数
struct Event * CreateEvents(int *OutEventCount)
{
int EventNum = 0;
struct Event * ReturnValue = NULL;
fflush(stdin);
printf("输入事件总数量(整数) = ");
try
{
scanf("%d",&EventNum);
}
catch(...)
{
printf("输入不正确!");
return NULL;
}
*OutEventCount = EventNum;
ReturnValue = (struct Event *)malloc(sizeof(struct Event) * EventNum);
memset(ReturnValue,0x0,sizeof(struct Event) * EventNum);
if ( NULL == ReturnValue )
{
printf("分配记忆体失败!");
return NULL;
}
for ( int i = 0 ; i < EventNum ; i++ )
{
int TmpInput = 0;
printf("输入第[%d]个事件名称 =",i+1);
scanf("%s",ReturnValue[i].Name);
printf("此事件是否开始事件 (输入0表示否,输入1表示是) =");
scanf("%d",&TmpInput);
if ( TmpInput == 1 )
{
ReturnValue[i].IsBegin = true;
}
printf("此事件是否结束事件 (输入0表示否,输入1表示是) =");
scanf("%d",&TmpInput);
if ( TmpInput == 1 )
{
ReturnValue[i].IsEnd = true;
}
}
return ReturnValue;
}
销毁事件分配的记忆体
void DestroyEvents(struct Event **pE)
{
if ( NULL != pE )
{
free(*pE);
}
*pE = NULL;
}
输入路径 返回生成的路径阵列,并通过引数返回路径数
struct Path * CreatePathes(int *OutPathCount)
{
struct Path * ReturnValue = NULL;
int Count = 0;
fflush(stdin);
try
{
while ( true )
{
if ( ReturnValue != NULL )
{
int tmpGoOn = 0;
printf("继续新增路径?(输入1继续新增,输入0退出新增路径) = ");
scanf("%d",&tmpGoOn);
if ( 0 == tmpGoOn )
{
break;
}
}
else
{
printf("--------------n");
}
ReturnValue = (struct Path *)realloc(ReturnValue,sizeof(struct Path) * (Count + 1 ));
Count++;
printf("输入此路径出发事件名称 = ");
scanf("%s",ReturnValue[Count-1].FromEventName);
printf("输入此路径到达事件名称 = ");
scanf("%s",ReturnValue[Count-1].ToEventName);
printf("输入此路径权重 = ");
scanf("%d",&(ReturnValue[Count-1].Height));
}
}
catch(...)
{
printf("输入不正确!");
return NULL;
}
*OutPathCount = Count;
return ReturnValue;
}
销毁事件分配的记忆体
void DestroyPathes(struct Path **pP)
{
if ( NULL != pP )
{
free(*pP);
}
*pP = NULL;
}
递回函式
计算从当前事件到终点事件的关键路径
引数:
const struct Event *pIn_CurrentEvent ---- 当前事件
const struct Event *pIn_Events ---- 所有事件阵列
const int TotalEventNum ---- 事件总数
const struct Path *pIn_Pathes ---- 所有路径阵列
const int TotalPathNum ---- 路径总数
struct Event * pIn_Out_ImportentPaths ---- 用来储存关键路径上的事件阵列
const int ImportPathsNum ---- 用来储存关键路径上的事件阵列大小
返回值:
从当前事件到终点事件的关键路径权重
int Run(const struct Event *pIn_CurrentEvent,const struct Event *pIn_Events,const int TotalEventNum,const struct Path *pIn_Pathes,const int TotalPathNum,struct Event * pIn_Out_ImportentPaths,const int ImportPathsNum)
{
1.找到从当前事件出发的所有路径
2.针对从当前事件出发的所有路径到达的事件分别呼叫Run看谁返回的权重最大
3.结束条件:当当前事件为终点事件时结束递回
结束递回
if ( pIn_CurrentEvent->IsEnd )
{
return 0;
}
找到当前事件出发的所有路径
struct Path *TmpFromThisPathes = (struct Path *)malloc(sizeof(struct Path) * TotalPathNum);
int TmpForThisPathesIndex = 0;
if ( NULL == TmpFromThisPathes )
{
printf("递回呼叫中分配记忆体失败!");
return 0;
}
memset(TmpFromThisPathes,0x0,sizeof(struct Path) * TotalPathNum);
for ( int i = 0 ; i < TotalPathNum ; i ++ )
{
if ( strcmp(pIn_Pathes[i].FromEventName,pIn_CurrentEvent->Name) == 0 )
{
memcpy(&(TmpFromThisPathes[TmpForThisPathesIndex]),&(pIn_Pathes[i]),sizeof(struct Path));
TmpForThisPathesIndex++;
}
}
找到当前事件可到达的所有事件 并找到当前路径所有可到达事件中权重最大的
int MaxPower = -1;
Event MaxEvent;
memset(&MaxEvent,0x0,sizeof(MaxEvent));
for ( int i = 0 ; i < TmpForThisPathesIndex ; i++ )
{
for ( int j = 0 ; j < TotalEventNum ; j++ )
{
if ( strcmp(pIn_Events[j].Name,TmpFromThisPathes[i].ToEventName) == 0 )
{
在此对此事件的下一个事件递回呼叫来得到哪条路径的权重最大
int TmpGotPower = Run(&(pIn_Events[j]),pIn_Events,TotalEventNum,pIn_Pathes,TotalPathNum,pIn_Out_ImportentPaths,ImportPathsNum);
if ( MaxPower < TmpGotPower + TmpFromThisPathes[i].Height )
{
记录下最大的权重和对应的下个事件
MaxPower = TmpGotPower + TmpFromThisPathes[i].Height;
memcpy(&MaxEvent,&(pIn_Events[j]),sizeof(Event));
}
}
}
}
free(TmpFromThisPathes);
TmpFromThisPathes = NULL;
储存关键路径上的事件
if ( MaxEvent.IsEnd )
{
去掉中间储存的不是关键路径的资讯
memset(pIn_Out_ImportentPaths,0x0,ImportPathsNum * sizeof(Event));
}
for ( int i = 0 ; i < ImportPathsNum ; i++ )
{
if ( strlen(pIn_Out_ImportentPaths[i].Name) < 1 )
{
memset(&(pIn_Out_ImportentPaths[i]),0x0,sizeof(Event));
memcpy(&(pIn_Out_ImportentPaths[i]),&MaxEvent,sizeof(Event));
break;
}
}
return MaxPower;
}
void main(void)
{
int EventNum = 0;
int PathNum = 0;
struct Event * pTheEvents = CreateEvents(&EventNum);获取输入事件
struct Path *pThePathes = CreatePathes(&PathNum);获取输入路径
if ( NULL == pTheEvents || NULL == pThePathes )
{
goto END_COME_HERE;
}
获取始发点事件 即 IsBegin 为真的事件
struct Event * pTheBeginEvent = NULL;
for ( int i = 0 ; i < EventNum ; i++ )
{
if ( pTheEvents[i].IsBegin )
{
pTheBeginEvent = pTheEvents + i;
break;
}
}
if ( NULL == pTheBeginEvent )
{
printf("无始发点事件!n");
goto END_COME_HERE;
}
定义储存关键路径的阵列 EventNum 只是用来表示大小,因为关键路径上的事件个数总不会超过所有事件总数
struct Event *ImportentPaths = (struct Event *)malloc(EventNum * EventNum * sizeof(struct Event));
if ( NULL == ImportentPaths )
{
printf("分配记忆体失败!n");
goto END_COME_HERE;
}
memset(ImportentPaths,0x0,EventNum * EventNum * sizeof(struct Event));
递回呼叫
int TheTotalHeight = Run(pTheBeginEvent,pTheEvents,EventNum,pThePathes,PathNum,ImportentPaths,EventNum);
因始发事件没有在递回函式中新增到关键路径经过的事件中,所以在此新增.
for ( int i = 0 ; i < EventNum * EventNum ; i++ )
{
if ( strlen(ImportentPaths[i].Name) < 1 )
{
memset(&(ImportentPaths[i]),0x0,sizeof(Event));
memcpy(&(ImportentPaths[i]),pTheBeginEvent,sizeof(Event));
break;
}
}
输出(说明,因为是递回呼叫,所以所储存的关键路径上的事件是反序的
printf("已找到,总权重为:%d,关键路径为:n",TheTotalHeight);
for ( int i = 0 ; i < EventNum * EventNum ; i++ )
{
if ( strlen(ImportentPaths[i].Name) < 1 )
{
break;
}
printf("%s,",ImportentPaths[i].Name);
}
free(ImportentPaths);
ImportentPaths = NULL;
END_COME_HERE:
DestroyEvents(&pTheEvents);
DestroyPathes(&pThePathes);
fflush(stdin);
getchar();
}
=========================================
执行结果如下图: ...图片贴不上来,我放到我空间里了::hi.baidu./moxsone/album/item/1d5fae0f010d9ad2a9645741.
关键路径问题 (Vc++)
#include <iostream.h>
#include<stdlib.h>
#include<string.h>
#include <stdio.h>
*****stack.h以下是栈的实现
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
template<class QElemType>
class stack
{
public:
void InitStack();
void DestroyStack();
void ClearStack();
Status StackEmpty();
Status StackLength();
void GetTop(QElemType & e);
void Push(QElemType e);
void Pop(QElemType & e);
private:
struct SqStack{
QElemType *base;
QElemType *;
int stacksize;
}S;
};
******stack.cpp------
template<class QElemType>
void stack<QElemType>::InitStack()
{
S.base = (QElemType *)malloc(STACK_INIT_SIZE * sizeof(QElemType));
if(!S.base) exit(0);
S. = S.base;
S.stacksize = STACK_INIT_SIZE;
}
template <class QElemType>
void stack<QElemType>::DestroyStack()
{
free(S.base);
}
template <class QElemType>
void stack<QElemType>::ClearStack()
{
S. = S.base;
}
template <class QElemType>
Status stack<QElemType>::StackEmpty()
{
if(S. == S.base) return 1;
else return 0;
}
template <class QElemType>
Status stack<QElemType>::StackLength()
{
return (S. - S.base);
}
template <class QElemType>
void stack<QElemType>::GetTop(QElemType & e)
{
if(S. != S.base)
e = *(S. - 1);
else cout << "ERROR" << endl;
}
template <class QElemType>
void stack<QElemType>::Push(QElemType e)
{
if(S. - S.base >= S.stacksize)
{
S.base = (QElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(QElemType));
if(!S.base) exit(0);
S. = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.++ = e;
}
template <class QElemType>
void stack<QElemType>::Pop(QElemType & e)
{
if(S. == S.base) cout << "ERROR" << endl;
else
e = * --S.;
}
********* ****栈实现结束
********图的实现
*********Graph.h图的实现
template <class TElemType>
class Graph
{
public:
void CreateAlgraph();
void DestroyAlgraph();
void TopologicalSort(); 有向图拓扑排序,检验环的存在与否
float * TopologicalOrder(stack<int> &sre,int &e);
void Criticalpath(); 求有向无环图关键路径
private:
int count;
struct Arode
{
int adjvex;
Arode *nextarc;
float weight;
};
template <class TElemType>
struct Vexnode
{
TElemType data;
Arode *firarc;
};
struct ALgraph
{
int vexnum;
int arum;
bool kind;
Vexnode<TElemType> *vex;
};
ALgraph algraph; 邻接表储存
};
template <class TElemType>
void Graph<TElemType>::CreateAlgraph()
{
int i,j,m,n;
float w;
TElemType v1,v2;
Arode *p;
cout << "输入图型别(1是无向图,0是有向图):" << endl;
cin >> algraph.kind;
cout << "输入顶点数和边数:" << endl;
cin >> algraph.vexnum >> algraph.arum;
algraph.vex = (Vexnode<TElemType> *)malloc(algraph.vexnum * sizeof(Vexnode<TElemType>));
cout << "输入顶点资讯:" << endl;
for(i = 0;i < algraph.vexnum;i++)
{
cin >> algraph.vex[i].data;
algraph.vex[i].firarc = NULL;
}
if(algraph.kind)
{
cout << "输入各边依附的两点和权值:" << endl;
for(i = 0;i < algraph.arum;i++)
{
cin >> v1 >> v2 >>w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arode *)malloc(2*sizeof(Arode));
p[0].adjvex = n;p[0].weight = w;
p[1].adjvex = m;p[1].weight = w;
p[0].nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
p[1].nextarc = algraph.vex[n].firarc;algraph.vex[n].firarc = ++p;
}
}
else
{
cout << "输入各边的弧尾与弧头结点及有向边的权值:" << endl;
for(i = 0;i < algraph.arum;i++)
{
cin >> v1 >> v2 >> w;
for(j = 0;j < algraph.vexnum;j++)
{
if(v1 == algraph.vex[j].data) m = j;
if(v2 == algraph.vex[j].data) n = j;
}
p = (Arode *)malloc(sizeof(Arode));
p->adjvex = n;p->weight = w;
p->nextarc = algraph.vex[m].firarc;algraph.vex[m].firarc = p;
}
}
} 构造完成
template <class TElemType>
void Graph<TElemType>::DestroyAlgraph()
{
int i;
Arode *p,*q;
for(i = 0;i < algraph.vexnum;i++)
{
p = algraph.vex[i].firarc;
if(p)
{
q = p->nextarc;
while(q)
{
free(p);
p = q;
q = q->nextarc;
}
free(p);
}
}
free(algraph.vex);
}
template <class TElemType>
float * Graph<TElemType>::TopologicalOrder(stack<int> &sre,int &e)
{
stack<int> o;
o.InitStack();
sre.InitStack();
float *re = (float *)malloc(algraph.vexnum * sizeof(float));
int *indegree = (int *)malloc(algraph.vexnum * sizeof(int));
int i,v,v1,count = 0;
for(i = 0;i < algraph.vexnum;i++) re[i] = 0;
Arode *p;
for(i = 0;i < algraph.vexnum;i++) indegree[i] = 0;
for(i = 0;i < algraph.vexnum;i++)
for(p = algraph.vex[i].firarc;p;p = p->nextarc)
{
v = p->adjvex;
indegree[v]++;
}
for(i = 0;i < algraph.vexnum;i++)
if(indegree[i] == 0) o.Push(i);
while(!o.StackEmpty())
{
o.Pop(v);
sre.Push(v);
count++;
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(0 == --indegree[v1]) o.Push(v1);
if(re[v] + p->weight > re[v1]) re[v1] = re[v] + p->weight;
}
}
e = v;
o.DestroyStack();
if(count < algraph.vexnum) return NULL;
return re;
}
template <class TElemType>
void Graph<TElemType>::Criticalpath()
{
float *rl = (float *)malloc(algraph.vexnum * sizeof(float));
stack<int> sre;
int e;
float *re = TopologicalOrder(sre,e);
if(re)
{
int i,v,v1;
Arode *p;
for(i = 0;i < algraph.vexnum;i++) rl[i] = re[e];
while(!sre.StackEmpty())
{
sre.Pop(v);
for(p = algraph.vex[v].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(rl[v1] - p->weight < rl[v]) rl[v] = rl[v1] - p->weight;
}
}
cout << "关键路径如下:" << endl;
for(i = 0;i < algraph.vexnum;i++)
for(p = algraph.vex[i].firarc;p;p = p->nextarc)
{
v1 = p->adjvex;
if(rl[v1]-p->weight == re[i]) cout << "(" << algraph.vex[i].data << "," << algraph.vex[v1].data << ") ";
}
cout << endl;
free(re);
}
else cout << "有向图中存在环,不合要求!" << endl;
free(rl);
sre.DestroyStack();
}
小测试程式test.cpp
int main()
{
Graph<int> gph;
gph.CreateAlgraph();
gph.Criticalpath();
gph.DestroyAlgraph();
return 0;
}
什么是关键路径?
在专案管理中,关键路径是指网路终端元素的元素的序列,该序列具有最长的总工期并决定了整个专案的最短完成时间。
关键路径的工期决定了整个专案的工期。任何关键路径上的终端元素的延迟将直接影响专案的预期完成时间(例如在关键路径上没有浮动时间)。 一个专案可以有多个,并行的关键路径。另一个总工期比关键路径的总工期略少的一条并行路径被称为次关键路径。 最初,关键路径方法只考虑终端元素之间的逻辑依赖关系。关键链方法中增加了资源约束。 关键路径方法是由杜邦公司发明的。
project 软体怎么显示关键路径
切换到“跟踪甘特图”,看右侧图形区中红色的任务,都是关键路径;
在“检视”选项卡——“资料”区,“突出显示”——关键;
求关键路径pascal程式码
给你最快的SPFA演算法~~~~~
program SPFA;
var
n,m,i,j,k,head,tail,s,t,x,y,z,now:longint;
a,b:array[0..100,0..100]of longint;{a[x,y]存x,y之间边的权;b[x,c]存与x相连的第c个边的另一个结点y}
d,dis:array[0..100]of integer;{伫列与个点距离}
v:array[0..100]of boolean;{是否入队的标记}
lu:array[0..100]of integer;{路径记录}
procedure di(t1:integer);{路径输出}
begin
if t1=0 then exit;
di(lu[t1]);
write(t1,' ');
end;
begin
readln(n,m);{几个点几条边}
for i:=1 to m do
begin
readln(x,y,z);
a[x,y]:=z; a[y,x]:=z;
inc(b[x,0]); b[x,b[x,0]]:=y; {b[x,0]:以x为一个结点的边的条数}
inc(b[y,0]); b[y,b[y,0]]:=x;
end;
readln(s,t); head:=1; d[head]:=s; tail:=1;
fillchar(dis,sizeof(dis),26); dis[s]:=0; v[s]:=true;{初始化}
while head<=tail do{SPFA过程}
begin
now:=d[head];{取队首元素}
for i:=1 to b[now,0] do
if dis[b[now,i]]>dis[now]+a[now,b[now,i]] then
begin
dis[b[now,i]]:=dis[now]+a[now,b[now,i]];{松弛操作}
lu[b[now,i]]:=now;{记录当前最优路径}
if not v[b[now,i]] then begin
inc(tail);
d[tail]:=b[now,i];{扩充套件节点入队}
v[b[now,i]]:=true;
end;
end;
v[now]:=true;{释放节点}
inc(head);
end;
writeln('dis=',dis[t]);
writeln(dis[t]);
di(t);
end.
关键路径(c++,要注释哦)
呵呵,有意思