管网造价设计分析c语言课程设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
管网造价设计分析c语言课程设计
东南大学
C语言课程设计报告
课程名称:计算机综合课程设计学院:土木工程学院
设计题目:管网造价设计分析
级别:B级
学生姓名:xxxxxx
学号:xxxxxxxxxxxxxxxxx 同组学生:
指导教师:卢瑞华
2014年9月1号
目录
课程设计任务书(功能简介、课程设计要求) (3)
系统设计(包括总体结构、模块、功能等,辅以程序设计组成框图、流程图解释); (4)
模块设计(主要模块功能、源代码、注释(如函数功能、入口及出口参数说明,函数调用关系描述等); (8)
调试及测试:(调试方法,测试结果的分析与讨论,截屏、正确性分析); (11)
设计总结:(编程中遇到的问题及解决方法); (14)
参考文献 (18)
1.C语言课程设计任务书
学生选题说明:
以所发课程设计要求为准,请同学们仔细阅读;
本任务书提供的设计案例仅供选题参考;也可自选,但难易程度需难度相当;
鼓励结合本专业(土木工程、力学)知识进行选题,编制程序解决专业实际问题。
限2人选的题目可由1-2人完成(A级);限1人选的题目只能由1人单独完成(B级);
设计总体要求:
采用模块化程序设计;
鼓励可视化编程;
源程序中应有足够的注释;
学生可自行增加新功能模块(视情况可另外加分);
必须上机调试通过;
注重算法运用,优化存储效率与运算效率;
需提交源程序(含有注释)及相关文件(数据或数据库文件);
提交设计报告书,具体要求见以下说明。
设计报告格式:
目录
课程设计任务书(功能简介、课程设计要求);
系统设计(包括总体结构、模块、功能等,辅以程序设计组成框图、流程图解释);
模块设计(主要模块功能、源代码、注释(如函数功能、入口及出口参数说明,函数调用关系描述等);
调试及测试:(调试方法,测试结果的分析与讨论,截屏、正确性分析);
设计总结:(编程中遇到的问题及解决方法);
心得体会及致谢;
参考文献
程序功能简介:
本程序是用来计算分析关于工程造价中管网单位造价的,而这个数学模型的方程为z
C a b
D =+⋅。
你自己将需要分析的数据手动输入,本程序就可以将这个非线性方程的回归方程给计算出来,其中关于z 的精度和取值范围都可以自己动手输入。
这就是本程序的简要功能介绍。
2.系统要求
2.1功能要求:
对某地给水管网D=200mm 以上的管道进行了单位造价的综合分析计算。
造价构成包括:(1)管材价格;(2)运输管理费用;
(3)施工费用;(4)挖填沟槽费用;(5)路面修复费用;(6)消火栓费用;(7)闸门费用;(8)闸门井、支墩等构筑物;(9)管配件费用;(10)特殊措施费用。
得到管径与单价如表所示。
表2 管径造价表
试采用常规回归分析,通过C 语言编程确定管道造价的数学模
型参数。
管道造价的数学模型:z
bD a C +=
式中:D ——管径(m ); C ——单位造价(元/m );
a,b,z ——系数。
2.2模块设计分析
2.2.1数学模型分析
因为这是一个纯非线性方程,直接运用研究一般的例如y a b x =+⋅方程的方法是行不通的,那么,在这里,就要引入一种数学思想,就是黄金分割与最小二乘法。
黄金分割最小二乘法作为一种迭代的方法,可以获得据怒的最优解,因此可以在这里采用这种方法的。
首先介绍一下最小二乘法,因为在后续的计算中,将会用到最小二乘法。
在研究两个变量的关系时,,通常会用到一系列的点坐标,将这些坐标描绘在坐标轴上时,如若发现这些点是分布在一直线的附近,那么我们可以将之设为一个一元一次的方程:01y a a x =+⋅,其中,01,a a 均为待定的数。
那么,要想求出这些未
知的数,根据《最小二乘法原理》可以知道,通过计算实际值和用设的方程所得到的差的平方和,比较这些和,得到的值最小时所对应的值就是要求的参数。
就根据这种思想,通过运用高等数学的知识,可以得到关于参数的计算方法:
2022
()i i i i i
i i y x x y x a N x x -=-∑∑∑∑∑∑ 01i i
y a N a x -=∑∑
σ=01,a a 为参数,σ为方差)
以上这些是研究的一元一次的线性回归方程,那么,对于题目要求的纯非线性方程来说,也是可以采用这种思路的。
我们可以假
设z 为一个常量,就像一元一次方程中的一次方一样。
那么,我们就可以想研究线性回归方程那样来研究问题了。
所以,就要用到黄金分割法,将z 值分成很多的值,每一个z 值,将会对应一个方差,最后将算到的很多方差进行对比,得到最小的方差对应的就求出了z 值,对应的a,b 值就可以得到了。
同样的道理,在每一个z 值下得到的a,b 值:
222()z z z
i i i i i z
z i i C D C D D a N D D -=-∑∑∑∑∑∑
i
z
i
C aN b
D -=∑∑
σ=;
因此根据这个思路,就可以将程序的思路设计出来:
a. 输入信息:将要计算的管径和对应的单价输入文本文件中,
自己宏定义要输入的数据有多少组,然后输入关于z 的取值范围和精度;
b. 数据计算:设计函数,将单价的和与管径z 次方的和分别计
算出来;设计函数,将管径的z 次方与之对应的单价的成绩计算出来;设计函数,将管径的z 次方的和计算出来;
c. 储存数据:定义数组A[10000],B[10000],K[10000],分别用来记
录每一个z 值得到的a,b,和方差;
d. 比较数据:将得到的数组k[10000]用冒泡法得到最小的值,
并且用一个中间变量记录下来数组中最小的值;
e. 输出结果:将得到的最佳拟合曲线输出。
f.开始循环:系统会给出是否还要继续的提示,这样只需组建
一次,就可以计算很多次,可以用于比较不同精度时的函数曲线了。
2.2.2模块设计分析
系统功能模块图
Mabi
2.2.3程序工作分析
1)将待输入的数按表输入文本文件中:
2)数据求和:根据各个函数将待要计算的数据计算出来;
3)计算公式:根据黄金分割最小二乘法的公式将每一个z值要
求得的a,b计算出来;
4)记录功能:将每一个z值所对应的a,b,及方差都记录在已知的
数组中;
排序功能:对得到的方差数组进行冒泡法排序,就会选出该数组中的最小值,从而得到对应的a,b值;
输出功能:将得到的最佳拟合曲线输出;
循环功能:再次将z的精度改变,比较不同精度时的数据差别。
3.模块设计
#include<stdio.h>--------------------------------------------------------------------------------//编译预处理
#include<math.h>------------------------------//因为程序涉及到次方的计算,所以要用到数学函数#include<stdlib.h>-------------------------------------------------------------------//涉及到文件夹的使用
#define N 5------------------------ --------------------------//宏定义数据的组数,这样方便以后的计算
float add(float a[2][1000],int n,float m) ----//计算单价的和与管径的z次方的和的平均值的函数{float SUM=0;
int i;
if(n==1)----------------------------------------------------------------------------------//这是计算单价的和{for(i=0;i<N;i++)
SUM+=a[n][i];}
else if(n==0) //这是计算管径的z次方的和
for(i=0;i<N;i++)
SUM+=pow(a[0][i],m);
return (SUM/N);}
float product(float b[2][1000],float p)------//计算管径z次方与之对应的单价的乘积的和的函数{float SU=0;
int i;
for(i=0;i<N;i++)
SU+=(pow(b[0][i],p)*b[1][i]);
return (SU);
}
float guanjing(float c[2][1000],float q)-------------------------------//计算管径的2z次方的和的函数
{ float S=0;
int i;
for(i=0;i<N;i++)
S+=pow(c[0][i],2*q);
return (S);}
int main()
{float add(float a[2][1000],int n,float m);
float product(float b[2][1000],float p);
float guanjing(float c[2][1000],float q);
float num[2][1000];
float A[10000],B[10000],k[10000];//定义关于a和b的数组,K[i]表示在每一个z值所得到的方差int i,j,n=0;
float
A1,A2,A3,A4,A5,A6,A7,z;--------------------------//这些数是计算过程的中间值,方便观看
float min,sum;-----------//定义min用来比较方差时的中间变量。
sum是为了计算方差时用到的ifloat
Min,Max;---------------------------------------------------------------//关于z的取值范围定义
FILE
*fp;------------------------------------------------------------------------------------//定义文件夹指针fp=fopen(“数据输
入.txt”,”r”);--------------------------------------//使文件指针指向数据存储的文件
for(i=0;i<2;i++)------------------------------------------------------------------//用循环输入管径和单价{for(j=0;j<N;j++)
fscanf(fp,"%f",&num[i][j]);------------------------------------------------//从文件中读取数据fscanf(fp,”\n”);};
Prinft(“您从文件中读取的数组如下:\n"); For(i=0;i<2;i++)----------------------------------------------------------//将读取的文件向屏幕输出
{if(i==0)
printf(“管径(毫米):”);
If(i==1)
printf(“单价(元):”);
{For(j=0;j<N;j++)
Printf(“%8.2f”.&num[i][j]);
Printf(“\n”);};};
printf("请输入关于z的取值范围(用Min~Max来表示):");
scanf("%f~%f",&Min,&Max);-------------------------------------------//从键盘中得
到z值得范围
A1=add(num,1,0);--------------------------------------------------------------------//求出单价的平均值While(n==0)------------------------------------------------------//开始循环,用n来做
{nt r=0;---------------------------------------//在用冒泡法比较时,用来记录方差最小时的i值scanf("%f~%f",&Min,&Max);
for(z=Min,i=0;z<=Max;z+=0.01,i++)--------------------------//开始循环,,每次z值是增加0.。
01 {float sum=0;
A2=product(num,z);--------------------------------//计算管径z次方与之对应的单价的乘积的和
A3=add(num,0,z);--------------------------------//计算在每一个z值下的管径的z次方的平均值
A4=guanjing(num,z);-------------------------------//计算在每一个z值下的管径的2*z次方的和
A5=N*pow(A3,2);
B[i]=(A2-N*A3*A1)/(A4-A5);--------------------------------------------------//得到管径前面的系数
A[i]=A1-A3*B[i];---------------------------------------
------------------------------------------//得到常量
for(j=0;j<N;j++)----------------------------------------------//开始计算在每一个z值下所得到的方差{
A6=B[i]*(pow(num[0][j],z));----------------------------------------------------------- //计算b*D^z的值
A7=A[i]+A6-num[1][j]; -------------------//计算C(i)与C的平均值的差积,为方差的计算做准备sum+=pow(A7,2);//这里为了提高运算速度,就只运算平方和,不在计算接下来的开方了
};
k[i]=sum;-------------------------------------------------------------------------//将得到的方差赋给k[i]
};
min=k[0];---------------------------------------//开始用冒泡法的到最小的k[i].也就是最小的方差
for(i=0;i<(Max-Min)/10000;i++)
if(min>k[i])
{min=k[i];r=i;};------------------//这里用r来记录下最小的方差是哪个,从而找到最小的方差
printf("您得到的最佳拟合曲线为:C=%f+%f*D^%f。
\n",A[r],B[r],Min+0.01*r);-----------------------------------------------------//输出的到的拟合的曲线
printf("如果继续输入,请按【0】键;否者按【1】键退出:");
scanf("%d",&n);};};------------------------------------------------------------------------------//循环结束return 0;
}
4.调试及测试
①信息存储:
②开始界面:
③输入信息
④开始循环:
⑤程序结束
5.调试中的问题:
1.关于记录系数sum的问题:在本程序的比较模块中,有一个记录方差的中间量sum,在初始程序中,它的定义如下:
也就是说,未对sum的初始值赋值,结果在运行程序的时候,系统就一直提示无法从内存中读取数据。
后来经过检查以后,才发现原来是sum这里出现了问题。
因为如果他没有初始化的话,那么系统会给它赋一个随机的值,它就会影响整个的程序运行。
后来将其赋值为0以后,那么问题就得到解决了。
2.关于从文件中读取数据的错误:一开始,程序建立的结构体数
组,其设
置如下:
结果,用了文件指针后,就无法实现从文件中既读取字符串,又读取了数
组。
虽然通过在网上查找资料,可以做到这一点,但是其运用的是C++,不符合我们的要求。
所以就将此结构体去掉了,而是直接定义了一个数组,在输出数组的时候,就将“管径”和“单价”直接输出,然后再输出这样,就回避了难以解决的问题,也充分运用了自己的知识。
3.在程序中的警告:
这是在程序中出现的警告,程序显示在定义数据类型时,double 和float型之间的转换存在数据可能丢失的警告,经过在同学的帮助下,我才明白对于本题而言,数据不会溢出,因此暂认为可以。
而且在全部定义为double型数据时易出现一些问题。
所以个人在设计程序时将部分不会存在数据溢出的变量定义为float 型。
6.设计总结
当初一看到这个题是首先想到的是平常学习中较为常用的一般
线性回归方程,但经过仔细研究题目,才发现其存在一个次方系数,导致了这个问题的复杂化。
所以就开始查找一些关于此方面的书籍。
在一本关于数据统计的书上边,我知道了这是属于一个纯非线性的回归方程,也就是说它不可以化成一般的回归方程上边。
虽然可以用数学的方法将它计算出来,但是要用到积分的知识,由于种种限制,故无法实现用直接得到结果。
后来,又在关
于管网造价的相关书籍中,查到了如何用程序来计算这种函数的方法,其就是黄金分割最小二乘法。
他可以借助电脑快速的计算能力,很方便的找到最佳拟合的曲线。
后来也经过了老师的认可,说这种方法是正确的。
编写成程序时,为了黄金分割最小二乘法的公式的计算方便定义了3个函数,求取一些在黄金分割最小二乘法的公式中需要用到的值。
此外,本程序还是设定了一些其他的功能,例如可以自己定义z的范围和精度,并且解决了从文件中读取数据的问题,大大的提高了工作效率。
还有值得提的一点就是可以一直使用不同的精度,来得到不同的结果,完全可以满足使用者的要求,可以比较不同精度时的差别,得到自己满意的答案。
在这里,我题外说一下,为什么要设计循环结构呢?其实一开始程序只能计算一个精度,后来,我自己在运行这个程序时发现,不同的精度值所得出来的结果有时候会有很大的差别,我就想,这应该是计算过程中数据的丢失所造成的吧。
那么,为了给使用者提供一个完全自主的模式,我就开始引入这个循环功能,就对一组数据的到很多个不同的曲线,到时候,使用者就会选择自己说要用到的结果。
不过,本程序比较遗憾的地方就是无法将得到的最佳拟合曲线储存在文件中以供使用者以后的读取。
不是不会这么将数据读到文件中,而是不知道怎么将既有字符串,又有数据的一串文字读到文件中,这也是被本程序最为遗憾的地方,希望看到本程序的人,可以帮助我修改或者提出宝贵的意见,本人在这里将不胜感激。
7.心得体会及致谢
课程设计是培养学生综合运用所学知识,发现,提出,分析
和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,当今计算机应用在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握计算机开发技术是十分重要的。
回顾起此次课程设计,至今让我我们仍感慨颇多,的确,从从拿到题目到完成整个编程,从理论到实践,在这一个星期的日子里,可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说结构体……通过这次课程设计之后,一定把以前所学过的知识重新温故。
这次课程设计终于顺利完成了,在设计中遇到了很多编程问题,最后在卢老师的辛勤指导下,终于游逆而解。
同时,在卢老师的身上我学得到很多实用的知识,在次我表示感谢!同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感
谢!
参考文献
1.谭浩强. C程序设计(第四版)[M ]. 北京: 清华大学出
版社, 2010.
2. 谭浩强. C程序设计(第四版)学习指导[M ]. 北京:
清华大学出版社, 2010.
3.王慧文.偏最小二乘法回归的线性与非线性方法.北京:国防工业出版社,2006.9
4.吴坚应用概率统计.北京:高等教育出版社,2007.7
5.刘宝辉. 市政工程管线综合优化研究, 硕士学位论文. 西安建筑科技大学,2010。