plc编程常用算法.docx

上传人:b****5 文档编号:28153832 上传时间:2023-07-08 格式:DOCX 页数:18 大小:222.77KB
下载 相关 举报
plc编程常用算法.docx_第1页
第1页 / 共18页
plc编程常用算法.docx_第2页
第2页 / 共18页
plc编程常用算法.docx_第3页
第3页 / 共18页
plc编程常用算法.docx_第4页
第4页 / 共18页
plc编程常用算法.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

plc编程常用算法.docx

《plc编程常用算法.docx》由会员分享,可在线阅读,更多相关《plc编程常用算法.docx(18页珍藏版)》请在冰豆网上搜索。

plc编程常用算法.docx

plc编程常用算法

常用算法

基本概念:

1.算法:

就是解决问题方法的精确描述。

并不是所有问题都有算法,有些问题经研究可行,则相应有算法;而有些问题不能说明可行,则表示没有相应算法。

算法具有以下性质:

是一有穷动作的序列;

动作序列仅有一个初始动作;序列中每个动作的后继动作是确定的;序列的终止表示问题得到解答或问题没有解答

2.算法的分类:

数值的和非数值的

数值的算法是以数学方式表示的问题求数值解的方法,女口:

代数方程

计算、矩阵计算、线性方程组求解、函数方程求解等;

非数值的算法是求非数值解的方法,如排序查找、模式匹配、排列模

拟、表格处理、文字处理等。

3.算法设计:

主要是针对各类具体问题设计良好的算法及研究设计算法的规律和方法。

4.常用的算法设计方法:

数值算法:

迭代法、递归法、插值法等;非数值算法:

分治法、贪婪法、回溯法等。

5.算法分析:

是对设计出的每一个具体的算法,利用数学工具,讨论

各种复杂度。

算法的复杂度分时间复杂度和空间复杂度。

常用数值计算算法

1.迭代法

迭代法适用于方程(或方程组)求解,是使用间接方法求方程近似根的一种常用算法。

(参见清华版《PASCAL程序设计P89练习4.23》

设方程f(x)=0,该方法将方程表示为等价形式:

x=g(x),或一般地

将f(x)拆成两个函数fl、f2,即卩f(x)=fi(x)-f2(x)=0,因而有fi(x)=f2(x)。

其中fi(x)是这样一个函数,对于任意数C,容易求出fi(x)=c的精确度很高的实根。

迭代法求解算法如下:

(1).首先选一个x的近似根X0,从X0出发,代入右面函数,并解

方程f1(x)=f2(x0)得到下一个近似根X1;

(2).将上次近似根X1代入右面函数,并解方程f1(x)=f2(x1),得到

又一个近似根X2

(3).重复⑵的计算,得到一系列近似根X0,X1,X2,…,Xi,Xi+1,…,xn,…;

(4)

4.插值法

也称为内插法。

在实际问题中出现的函数f(x),往往只知道它在某区间中若干点的函数值,这时作出适当的特定函数,使得在这些点上取已知值,并且在这区间内其它各点上就用这特定函数所取的值作为函数

f(x)的近似值,这方法称为“插值法”。

如果这特定函数是多项式,就称之为“插值多项式”或“内插多项式”。

(常见用于高等代数中的计算)三.常用非数值计算算法

1.穷举搜索法

穷举所有可能情形,并从中找出符合要求的解。

最直观的是联系循环的算法。

例5:

百钱买百鸡问题;第一届初中组3(也可用累加法)

第七届初中组四、2输出1-100内的素数;验证哥德巴赫猜想(详见清华版《PASCAL程序设计》P82-86例4.16,4.17)

例6:

找出n个自然数(1,2,3,,n)中r个数的组合

当n=5,r=3时,约定前一个数应大于后一个数,

有:

543542541532531521432431421321

可简单地用三重循环进行搜索,算法如下:

fori:

=5downto1do

forj:

=5downto1do

fork:

=5downto1do

if((i<>j)and(i<>k)and(j<>k)and(i>j)and(j>k))

thenwriteln(i,j,k);

或者

fori:

=5downto3do

forj:

=i-1downto3-1do

fork:

=j-1downto1do

if((i<>j)and(i<>k)and(j<>k)and(i>j)and(j>k))

thenwriteln(i,j,k);

2.递归法

例如:

在例6中,可首先固定第一位数(如5),其后是在另4个数中再“组合”2个数。

这就将“5个数中3个数的组合”推到了“4个数中2个数的组合”上去了。

第一位数可以是n^r(如5宀3),n个数中

r个数组合递推为n-1个数中r-1个数的组合,这是一个递归的算法:

procedurecomb(n,r:

integer);

vari,temp:

integer;

begin

fori:

=ndowntordo

if((i<>n)and(k<>r)

thenbegintemp:

=1

whiletemp<=(k-r)*3do{k为过程外定义的}begin

write(‘‘);temp:

=temp+1

end;

end;

write(i);

if(I>1)thencomb(i-1,r-1){递推到下一情形}

elsewriteln;

end;

例7:

求m与n的最大公约数;汉诺塔游戏(TowerofHanoi)(详见清华版《PASCAL程序设计》P109-P112例5.9,5.10)

例8:

第六届初中组二、2第五届高中组二、第五届初中组五

3.回溯法

一种选优搜索法,按选优条件向前搜索,以达到目标。

但当搜索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足条件的某个状态的点称为“回溯点”。

例如:

在例6中将自然数排列在数组A中:

A[1]

A[2]

A[3]

5

4

3

5

4

2

3

2

1

排数时从

A[1]tA[2]

tA[3],后一个至少比前一个数小1,并且应

满足「i+A[ri]>r这个关系。

若n+A[ri]

为直观起见,当输出一组组合数后,若最后一位为1,也应作一

次回溯(若不回,便由上述回溯条件处理)。

算法如下:

procedurecomb2(n,r,a[m]:

integer);

varj,ri:

integer;

begin

ri=1;a[1]=n;

repeat

if(ri<>r){没有搜索到底}

thenif(ri+a[ri]>r){是否回溯}

thenbegin

a[ri+1]:

=a[ri]+1;ri:

=ri+1

end;

elsebegin

ri:

=ri-1;a[ri]:

=a[ri]-1{回溯}

end;

elsebegin

forj:

=1tordowrite(a[j]);

writeln;

if(a[r]=1){是否回溯}

thenbegin

ri:

=ri-1;a[ri]:

=a[ri]-1{回溯}

end;

elsea[ri]:

=a[ri]-1end;

until(a[1]<>r-1)

end;

例9:

八皇后问题(详见清华版《PASCAL程序设计》P165)

练习:

清华版《PASCAL程序设计》P172习题7.19跳马问题和7.20迷宫问题、四色问题

例10:

第三届初中组二、3

4.贪婪法

一种可以快速得到满意解(但不一定是最优解)的方法。

方法的“贪

婪”性反映在对当前情况,总是作最大限度的选择。

即满足条件的均

选入,然后分别展开,最后选得一个问题解。

这方法不考虑回溯,也不考虑某次选择并不符合最优条件,但最终能得到最优结果的选择。

例11:

用贪婪法求解“货郎担问题”。

所谓货郎担问题是指,给定一个无向图,并已知各边的权,在这样的图中,要找一个闭合回路,使回路经过图中的每一个点,而且回路各边的权之和为最小,如右图所示。

a,b,c,d,e,f这6个点,坐标分别为(0,0)、(4,3)、

(1,7)、(15,7)、(15,4)、(18,0),这是最优解。

(算法程序略)

求解步骤一般如下:

(1).计算各点间距离(邻接矩阵);

(2).距离关系表排序;

(3).贪婪法选择边,入选的边应符合如下两条件:

每个端点不能

联系两条以上的边;不会使入选的边形成回路,除非入选正好是边数等于端点数。

为此引入端点关系表

(4).如果由⑶得不到解,应调整距离关系表中距离相同的边的次

序,再试;

(5).若有解,则按端点关系表给出回路的轨迹。

例12:

旅行路线选择。

设有n个城市(或景点),今从某市出发遍历各城市,使之旅费最少(即找出一条旅费最少的路径)。

例13:

背包问题。

从n件不同价值、不同重量的物品中选取一部

分,在不超过规定重量的原则下,使该部分价值最大。

例14:

第三届初中组一、8;第七届高中组四、2

5.分治法

是应用十分广泛的一种算法设计方法,其基本思想是把一个规模为n的问题分成若干个规模较小的问题,使得从这些较小问题的解易于构造出整个问题的解。

例15:

找一个集合的极大元和极小元。

集合S含有n个元素,其中n=2k(k>1)。

算法思路如下:

procedureMAXIM(S);

begin

1.if||S||=2{集合S的元素个数为2}thenbegin

2.设S={a,b};

3.return(MAX(a,b),MIN(a,b))

end

elsebegin

4.把S分为两个子集Si和S2,各有一半元素;

5.(max1,min1)—MAXMIN(Si);

6.(max2,min2)—MAXMIN(S2);

7.return(MAX(max1,max2),MIN(min1,min2))

end

end;

注意到,需要在集合S的元素间进行比较的步骤只是步骤3(在此比较两个元素)及步骤7(在此把max1与max2及min1与min2进行比较),设T(n)是用MAXMIN在一个具有n个元素的集合中找极大元和极小元时,需要在S的元素间进行比较的次数。

显然,T

(2)=1,如果n>2,则T(n)是在大小为n/2的集合上两次调用MAXMIN(第5、6步所需的比较次数加上第7步的两次比较所得的总次数,即

元素间进行比较的次数来说,这种算法是最优的。

例16:

设有n个选手的循环比赛(n=2m),要求每名选手要与其他n-1名选手都赛一次。

每名选手每天比赛一次,循环赛共进行n-1天,要求每天没有选手轮空。

例如m=3,见下表,用分治法将(2m*2m)矩阵

AB

分成四块,每块是(2m-1*2m-1)的矩阵,它应是对称的(),再对A

BA

与B均是(2m-1*2m-1)的矩阵分成四块,直至(2*2)的矩阵定出每个元素的值,再按对称关系构造出比赛表。

算法程序略。

、送

第一

第二

第三

第四

第五

第六

第七

1

2

3

4

5

6

7

8

2

1

4

3

6

5

8

7

3

4

1

2

7

8

5

6

4

3

2

1

8

7

6

5

5

6

7

8

1

2

3

4

6

5

8

7

2

1

4

3

7

8

5

6

3

4

1

2

8

7

6

5

4

3

2

1

四•排序

1.插入排序

设待排序的记录为(Ri,R2,…,Rn),插入排序的基本思想是把记录

Ri(2

图4.1直接樋人推序

得长度为I的一系列记录也是排好序的。

(1).直接插入排序

若记录Ri,R2,…,Ri-i已按关键码有序,即对应的关键码有KgK2«y

Ki-i,将K与Ki-i,Ki-2,…,Ki依次比较,一旦Ki大于或等于某个Kj(Kjw

i-1)时,把Rj+1,Rj+2,…,Ri-1后移一一个位置,并将Rj插在第j+1个位置上。

在直接插入排序中,若待排序的记录已有序,总共比较C=n-1

 

次。

直接插入排序可用顺序存储和链接存储。

 

囲乳2链接存储的直接捕人排序

例17:

清华版《PASCAL程序设计》P171习题7.8

(2).二分法插入排序

在直接插入算法中,确定Ri(i=2,…,n)插入位置的方法是将它

与前面i-1个记录依次比较,由于前i-1个记录已按关键码有序,

可以用二分法较快地找到Ri的插入点。

首先取m

1i1

2

比较Rm与Ri的关键码。

若Ri的关键码小于Rm的关键码,则在

[R1,R2,…,Rm-l]范围内再用二分法,否则在[Rm+1,…,Rn]范围内再用二分法。

如此反复,直至最后找到Ri的插入位置。

当n较大时,二分法插入排序比较次数比直接插入排序的最多比

较次数丄」少得多,但比直接插入排序的最少比较次数

2

(n-1)大。

二分法插入排序只能采用顺序存储。

2.选择排序

又称为直接选择排序。

在待排序的n个记录中先选出关键码最大的记录,将它送到第n个位置上,然后再从其余n-1个记录中选出关键

码最大的记录送到第n-1个位置上,…,直至选择了n-1个记录。

选择排序比较次数共有C=(n-1)+…+2=n(n-1)/2(详见清华版

《PASCAL程序设计》P145-147)

3.冒泡排序

这种排序方法从表的一端开始,依次比较相邻两个记录的关键码

R[i].key和R[I=1].key,若R[i].key>R[l+1].key,则交换R[i]和R[i+1]。

假设从表的左端开始,当i从0到n-2对表扫描一趟后,具有最大关

键码的记录将被移到最右边的位置上。

作n-1趟扫描将完成对n个记录的排序,但完成n个记录的排序不一定都要进行n-1趟扫描,如果在某趟扫描中没有发生交换,则排序工作已完成,此后的扫描便不必进行。

如果待排序的诸记录在排序前已按关键码排好序,贝U用冒泡排序算法只需一趟扫描便完成排序,比较次数为C=n-1。

如果待排序的记录完全反序,即已由大至小排序,则比较次数C=n(n-1)/2(详见清华版《PASCAL程序设计》P148-150)

4.希尔排序

在直接插入排序和冒泡排序中,只比较相邻的记录,一次比较至多

将记录移动一个位置。

希尔排序是对此两种排序的推广。

算法先将记录按某个增量d分成若干组,每组中记录的下标相差d。

对每组中的

记录用某种方法(前两种)进行排序,然后再用一个较小的增量对记录进行分组,在每组中再进行排序,…,当增量减至1时,整个记录

被分成一组,排序完成。

例如:

设待排序的记录的关键码为:

9432409099804621692864738554

取增量序列为:

5,3,1,当增量d=5时,整个记录被分成五组:

擁纽中的元累分别为匕

第一组194*90*64

第二组戲・46占3

翳三组r40t2US5

第四组;90,仙,54

第五组*9,48各组摆呼后”结集为:

若d=3血牛记录被分就三组倍组排序后的结果孙_

t—}—rI—I—Innf~1tI

4:

26215412抽M須738590肌畀94

再取增量为1,排序结果为:

2128324046546469738085909499

5.快速排序

选取表中某个记录的关键码K作为基准,将表划分成左、右两个

子表:

左子表中各记录的关键码都小于等于K,右子表中各记录的关

键码都大于等于K,然后用同样的方法递归地处理这两个子表。

比较次数C

(1)=0,C

(2)=2+C

(1)=2,C(3)=3+C

(2)=5,…,

C(n)=n+C(n-1)=(n+2)(n-1)/2

 

170

+

&03

061

512

908

0«7

Z75

653

4Z6

B12

765

i

170

503

1X.

061

512

908

0B7

275

esa

426

612

J

703

j

j

503

170

IM

061

512

908

OS7

275

6&3

426

«12

?

65

703

170

061

T*

r

0B7

j

512

503

«12

765

703

[170

061

375

C$7

][S08

512

653

426

S03

612

765

70S]

ffiA-3快議排序的划井过稈

上图说明了13个记录的表进行第1次划分的过程。

取表的中间一个记录的关键码275作为基准,划分时用两个指针变量i和j扫描表,

变量i从表头向右扫描,直至遇到一个关键码大于或等于基准的记录;变量j从表尾向左扫描,直至遇到一个关键码小于或等于基准的记录;接着交换Ri和Rj。

指针i和j继续向两端前进,进行比较、交换。

当i和j交叉(即i处于j的右边)时,表中各记录都与基准比较过,表被分成左、右两部分,左边各记录的关键码小于或等于右边各记录的关键码。

6.堆排序

是对选择排序的改进。

为了避免在选择排序中出现的每趟选择最大关键码的记录时的某些重复的比较,可以采用树形选择方法。

设待排

记录的关键码)都大于或等于它的子女结点的值,因此堆的根在树中具有最大的关键码。

这样得到的序列将是非递减的。

7.归并排序

是把两个或两个以上已排好序的表组合在一起,产生一个新的排好

序的表。

方法如下:

(1).若两个表有一个为空,则无须归并

(2).若两个表都非空,则比较p和q(两个表的头指针)所指结点

的关键码,将较小者插入第三个表中,并前进相应的指针。

重复这一步;

(3).若有一个表先到达表尾,则把另一个表的剩余部分插入到第

三个表中。

例18:

第五届初中组五

8.各种排序方法的比较

直接插入排序在记录数目较少且是基本有序时是最佳的;选择排序是比较次数不依赖记录的初始排列,且记录移动较少;冒泡排序的性能较差;希尔排序是对插入排序和冒泡排序的推广,在记录移动时可能消去多个反序,算法时间可能较短;快速排序是目前所有排序中平均性能最好的方法,但在最坏情况下年耗时间最多;堆排序在n较大时非常有效;归并排序可以看成是插入排序的扩充。

例19:

第六届初中组1、10

9.其它排序方法

例20:

第七届初中组四、1

五.查找

查找又称为检索,它往往是程序中最耗费时间的操作,使用何种存储结构和查找算法对程序的性能有本质的差别,因此,在讨论各种查找算法时都应指明所用的存储结构。

{定义记录类型}

{值为关键字的域}

{记录的其它域}

END;sqlist=ARRAY[0..n]OFelement;

1.顺序查找又称为线性查找,对给定的关键码值K,从表的一端开始,依次检查表中每个记录的关键码,直至找到所需灌到达表的另一端。

FUNCTIONseqsrch(r:

sqlist;K:

keytype):

integer;

Beginr[0].key:

=K;i:

=n;whiler[I].key<>Kdoi:

=i-1return(i)

end;

{K为给定值,函数seqsrch值为关键码等于K的记录在表r中的序号,值为零时表明查找不成功}

(参考清华版《PASCAL程序设计习题与选解》P35习题7.23)

2.二分查找

又称为折半查找。

当表中记录按关键码有序时(有序表),可以采

用二分查找法。

先确定待查记录的范围(区间),然后逐步缩小范围直

到找到或找不到该记录为止。

用两个指针low和hig分别指示待查元

素所在范围的下界和上界,并用指针mid指示中间元素

lowhig

mid。

在开始进行查找时,low和hig的初值分别指向

2

第1个和第n个元素。

FUNCTIONbinsrch(r:

sqlist;K:

keytype):

integer;

Begin

low:

=1;hig:

=n;

whilelow<=higdo{判别区间大小}

begin

mid:

=(low+hig)div2;

case

k>r[mid].key:

low:

=mid+1;

k=r[mid].key:

return(mid);{查找成功}

k

hig:

=mid-1

end;return(O)

end;

(参考清华版《PASCAL程序设计习题与选解》P35习题7.24)例21:

第七届初中组一、19;第六届初中组一、14

3.分块查找

又称为索引顺序查找,是顺序查找的改进方法。

是把表分成若干块,

每块中记录的存储顺序是任意的,但块与块之间必须按关键码有序,

4.14并块杳掳的减段累引

即第一块中任一记录的关键码都小于第二块中各记录的关键码,如此类推。

这种查找方法要求除表本身外,尚需建立一个索引表,索引表中的一项对应于表的一块,它含有这一块中的最大关键码的指向块内第一个记录位置的指针,索引表中各项按关键码有序。

分块查找的过程分两步进行:

先查找索引表(可以用上述两种方法)确定要找的记录在哪一块;然后再在相应的块中查找。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1