| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5623 人关注过本帖
标题:很复杂的计算公式如何实现
只看楼主 加入收藏
lzxagy
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-8-28
结帖率:66.67%
收藏
 问题点数:0 回复次数:11 
很复杂的计算公式如何实现

a=(k0+k1*p)/(p*p) ,b=p*e的幂(a+a*a) ,其中k0、k1、b为已知数。 麻烦问下用迭代法求出p的代码如何实现啊?
搜索更多相关主题的帖子: 计算 如何 
2012-01-31 23:11
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:652
专家分:3402
注 册:2008-5-7
收藏
得分:0 
简化和代入后的公式在vb里的写法为:b=p*2.71828^(k0/p^2+k1/p+(k0/p^2+k1/p)^2),其中2.71828就是常数e,现在只需要确定p的取值范围即可用二分迭代法逼近b值了,当误差小于0.00001时即可认为求得p值。

[ 本帖最后由 lowxiong 于 2012-2-1 11:49 编辑 ]
2012-02-01 11:48
lzxagy
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-8-28
收藏
得分:0 
感谢楼上的帮助。我自己大概测试了一下代码,可是跟计算出的结果不正确,不知道哪里出了问题?
Dim k0, k1, pt, p15, p155, p20, a As Double
k0 = 186.9696
k1 = 0.4862
pt = 845 * (1 - 2.3 * 10 ^ (-5) * (36 - 20) - 2 * 10 ^ (-8) * (36 - 20) * (36 - 20))

p15 = pt
Do

p155 = p15
a = k0 / (p15 * p15) + k1 / p15
p15 = pt / Exp(-a * 21 * (1 + a * 16.8))
p155 = pt / Exp(-a * 21 * (1 + a * 16.8))
Loop Until Abs(p15 - p155) < 0.005
p20 = p155 / Exp(-a * 10 * (1 + a * 8))
Print p155
2012-02-01 12:46
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:652
专家分:3402
注 册:2008-5-7
收藏
得分:0 
实话实说,我没看懂你的程序,好像和你的题意不同啊。在你的循环里,计算a的公式和你题意相同,但第二个式子怎么会有-a?21、16.8都是哪里来的?你原题意是p乘以自然对数的幂,怎么现在又变成除了?到Loop Util Abs(p15 - p155) < 0.005语句时,p15和p155的值会有区别么?这样做根本就没循环,这不是迭代算法,我理解的迭代算法怎么的要把误差叠加进去嘛,要通过循环无限逼近被比较值嘛。
2012-02-01 15:49
lzxagy
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-8-28
收藏
得分:0 
回复 4楼 lowxiong
因为昨天主要是那个公式怎么转换成代码遇到了麻烦,我就将实际的公式进行了简化,所以代码中的a和我提出的问题中的a不一样。现在主要的麻烦就是我不会用这个迭代法,我是按资料上给出的步骤来编写代码的:
1、将pt的值赋值给p15
2、将p15的值赋值给P155
3、p15=pt / Exp(-a * 21 * (1 + a * 16.8))   ''''''''21和16.8是我验算的数据
4、p155 = pt / Exp(-a * 21 * (1 + a * 16.8))
5、就p15和p155之差,如果差的绝对值小于给定的误差限,如0.0005,则p155为计算所得的结果。如果误差绝对值超过0.005,则转第二步重新计算,直到差值的绝对值小于0.005.

Dim k0, k1, pt, p15, p155, p20, a As Double
k0 = 186.9696
k1 = 0.4862
pt = 845 * (1 - 2.3 * 10 ^ (-5) * (36 - 20) - 2 * 10 ^ (-8) * (36 - 20) * (36 - 20))
p15 = pt
Do
p155 = p15
a = k0 / (p15 * p15) + k1 / p15
p15 = pt / Exp(-a * 21 * (1 + a * 16.8))
p155 = pt / Exp(-a * 21 * (1 + a * 16.8))
Loop Until Abs(p15 - p155) < 0.005
p20 = p155 / Exp(-a * 10 * (1 + a * 8))
Print p155
2012-02-01 16:46
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:652
专家分:3402
注 册:2008-5-7
收藏
得分:0 
回复 5楼 lzxagy
我也说了,你对a的计算是没问题的,那个简化我看的出来,问题是你3、4中,p15和p155使用的公式一模一样(至少我反复都没看出差别),都是pt / Exp(-a * 21 * (1 + a * 16.8)),通过计算,他们的差怎么算都应该是0啊,哪有误差。

[ 本帖最后由 lowxiong 于 2012-2-1 17:12 编辑 ]
2012-02-01 17:10
lzxagy
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-8-28
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册

我是根据这个做的
2012-02-01 17:18
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:652
专家分:3402
注 册:2008-5-7
收藏
得分:0 
Dim k0, k1, pt, p15, p155, p20, a As Double
k0 = 186.9696
k1 = 0.4862
pt = 845 * (1 - 2.3 * 10 ^ (-5) * (36 - 20) - 2 * 10 ^ (-8) * (36 - 20) * (36 - 20))
p15 = pt
Do
p15 = p155
a = k0 / (p15 * p15) + k1 / p15
p155 = pt / Exp(-a * 21 * (1 + a * 16.8))
Loop Until Abs(pt - p155) < 0.005
Print p155
我觉得可能是这样的,如果你把图片资料给全就好了,里面还有个Δt你根本就没理,资料给全我应该写的出过程
2012-02-01 19:38
lzxagy
Rank: 1
等 级:新手上路
帖 子:69
专家分:0
注 册:2007-8-28
收藏
得分:0 
回复 8楼 lowxiong
a = k0 / (p15 * p15) + k1 / p15显示除数为0的错误
我改了一下
pt = p * (1 - 2.3 * 10 ^ (-5) * (t1 - 20) - 2 * 10 ^ (-8) * (t1 - 20) * (t1 - 20))

p15 = pt
Do

p155 = p15
a = k0 / (p155 * p155) + k1 / p155
p15 = pt / Exp(-a * (t1 - 15) * (1 + a * (t1 - 15) * 0.8))


Loop Until Abs(p15 - p155) < 0.005

a = k0 / (p15 * p15) + k1 / p15
p20 = p15 / Exp(-a * 16 * (1 + a * 12.8))

[ 本帖最后由 lzxagy 于 2012-2-2 12:47 编辑 ]
2012-02-02 08:30
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:652
专家分:3402
注 册:2008-5-7
收藏
得分:0 
由于对你所提供的式子的来龙去脉我不清楚,我写了个简单的迭代法求平方根的程序,看能否作为参考,牛顿迭代法有很多参考,二分迭代法参考我没找到,就想当然地理解了,不知道正确与否,还望甄别!不过计算结果是正确的。
程序代码:
Private Sub Command1_Click()
  '牛顿迭代法是个高效的算法,他利用函数点的切线(函数倒数)不断逼近实际值
  '求平方根的公式为x=(x+a/x)/2,其中a即为要求平方根的数
  '同样求2的平方根,牛顿迭代法只需循环5次,而二分迭代法却要47次,可见牛顿迭代的效率
  Dim c As Long, a As Double, x As Double
  If Val(Text1) = 0 Then Exit Sub
  d = 0.00000000000001 '设置精度
  a = Val(Text1)       '取出要开平方的数
  x = a                '初始值设置
  c = 0
  Do
    c = c + 1
    x = (x + a / x) / 2
  Loop Until Abs(a - x ^ 2) < d or c>100  '直到误差小于规定的误差即停止循环
  Text2 = x  '输出结果
  Label3.Caption = "牛顿迭代法所用次数为" & c
End Sub

Private Sub Command2_Click()
  '二分迭代法求平方根,所谓二分就是区间距离的平分
  '比如求2的平方根,第一次赋值j为2,j1为0,j-j1=2,平分后为1,因此j调整为2-1=1
  '第二次因为区间变成了1到2之间,所以平分即为(2-1)/2=0.5,由于1的平方小于2,因此至此j=1+0.5=1.5
  '第三次区间变成了1到1.5之间,平分值为(1.5-1)/2=0.25,由于上次计算的1.5平方大于2,因此这次调整为1.5-0.25=1.25
  '第四次区间变成了1.25到1.5之间,平分值为0.125,上次1.25的平方小于2,这次j调整为1.25+0.125=1.375
  '第五次区间为1.375到1.25,平分为0.0625,由于1.375平凡小于2,就调整为1.375+0.0625=1.4375
  '第六次区间为1.4375到1.375,平分为0.03125,上次1.4375平方大于2,就调整为1.4375-0.03125=1.40625
  '如此不断调整区间的平分数,并根据上次误差是大于0还是小于0来加减平分数,逐渐逼近实际数值
  Dim c As Long, i As Double, j As Double, j1 As Double, d As Double, k As Double, f As Integer
  If Val(Text1) = 0 Then Exit Sub
  d = 0.00000000000001 '设置精度
  i = Val(Text1)  '取出要开平方的数
  j = i
  j1 = 0          'j和j1是第一次二分的区间
  f = -1          '第一次给的数肯定是大于目标数的,必定是减去二分数
  c = 0           '计数器清零
  Do
    c = c + 1  '记录迭代次数
    k = Abs(j - j1) / 2 '变量j和j1是确定二分的区间,以此计算二分调整值
    j1 = j
    j = j + k * f
    f = 1  '默认为下次调整为加上二分值
    If i - j ^ 2 < 0 Then f = -1  '如果j的平方大于实际值则下次调整为减去二分值
  Loop Until Abs(i - j ^ 2) < d Or k < d '直到误差或二分调整值小于规定的误差即停止循环
  Text2 = j  '输出结果
  Label3.Caption = "二分法迭代次数为" & c
End Sub


图片附件: 游客没有浏览图片的权限,请 登录注册

迭代法.rar (2.69 KB)



[ 本帖最后由 lowxiong 于 2012-2-3 15:59 编辑 ]
2012-02-03 15:40
快速回复:很复杂的计算公式如何实现
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015560 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved