| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3422 人关注过本帖
标题:穷举搜索法解方程组(待高手指点)
只看楼主 加入收藏
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

我用楼主的代码编译运行时没反应,有人告诉我什么问题吗?

收回我的话,不是没反应,而是太庞大了,一直在运算!

先来个弱智的修改: double a, radian=pi/180; //radian是弧度 for(a=radian;a<pi/2;a+=radian) //只循环1度到90度就够

[此贴子已经被作者于2004-07-25 10:04:51编辑过]

2004-07-25 08:20
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

#include<iostream.h> #include<math.h> #define pi 3.14159265

void main() { int n=1; double v, t, a; //改类型为double const double radian=pi/180; //radian是弧度的意思 for(v=1.0;v<2.0;v+=0.01) for(t=600;t<1200;t++) //缩短增距到1 for(a=radian;a<pi/2;a+=radian) //精度最高放在最深 { //cout<<v<<" "<<t<<" "<<a<<" "; n++; } cout<<n<<endl; /* if(fabs(v*t*cos(a)-1000)<=0.01) if(fabs(1.89*t-v*t*sin(a)-1160)<=0.01) cout<<v<<" "<<a<<" "<<t<<endl;*/ }

我尝试这段代码,大概两秒内算到有5400001种可能, 还有就是,最好不要printf,否则内存吃不消!

2004-07-25 10:11
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

v*t*cos(a) = 1000 (0<a<90)...(1) 1.89*t-v*t*sin(a) = 1160 (1.0<v<2.0) (600<t<1200)...(2)

(2)-(1) = 1.89t-vtsina-vtcosa = 1160-1000 -> t(1.89-v(sina+cosa)) = 160 -> v(sina+cosa) = 1.89-160/t -> v = (1.89-160/t)/(sina+cosa)

其中(sina+cosa)2 = sin2a+2sinacosa+cos2a = 1+sin2a -> sina+cosa = sqrt(1+sin2a) 因为0<a<90 => 0<2a<180 => 0<sin2a<1 所以取a->1(假设令a=1) 因为600<t<1200, v取minimum, 所以取t->600(假设令t=600) v = (1.89-160/600)/1 = 1.623

雨夜探月老师给出的“v的最小值是1.43或精度更高”是怎么算的呢?我哪里算错了呢?

这里在反省后注意,sina+cosa的求法是错的,详细请看第33楼

[此贴子已经被作者于2004-07-25 15:47:09编辑过]

2004-07-25 12:16
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

续第22楼: #include<iostream.h> #include<math.h> #define pi 3.1415926 //v的最小值是1.43或精度更高 void main() { int n=1; double v, t, a; //改类型为double const double radian=pi/180; //radian是弧度的意思 for(v=1.0;v<2.0;v+=0.01) for(t=600;t<1200;t+=1) //缩短增距到1 for(a=radian;a<pi/2;a+=radian) //精度最高放在最深 if(1.89*t-v*t*(sin(a)+cos(a))-160<=0.01) { //cout<<v<<" "<<t<<" "<<a<<endl; n++; } cout<<n<<endl; }

我在第22楼说了三个循环,用缩短了的addition,总共有5400001种可能, 而我用以上这段代码算出来符合条件的有3466664种可能!shit!!!

what is going on?

2004-07-25 13:09
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 

TO:LIVE41

你的程序结果对不对与程序的语法对错,都不是关键。关键在于算法有问题,你的程序的三for(;;)语句的增量的精度决定了结果精度。所以,不可取,而且还有可能出错(比如:当某一特殊情况,你的for(;;)中的增量的精度并不是最佳的,这个增量的精度只是你自己想当然定的)

我没有仔细看这个贴子,刚才我推导了一下:

v=1890/(1160+1000*sin(a))

当sin(a)为最大值时,V为最小值

象这种的题我是从来不做的,不值得做。让我做,

就 return (1890/(1160+1000*sin(a))); 一句


九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2004-07-25 13:41
神vLinux飘飘
Rank: 13Rank: 13Rank: 13Rank: 13
来 自:浙江杭州
等 级:贵宾
威 望:91
帖 子:6140
专家分:217
注 册:2004-7-17
收藏
得分:0 

其实如果按照live41的计算方法继续下去(当然,他在sina+cosb的最大值问题上搞错了),会得到和我一样的结果:1.14804337576这个答案竟然比雨夜给出的答案还小,马上就被雨夜枪毙了,5555


淘宝杜琨
2004-07-25 14:04
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 
以下是引用神vLinux飘飘在2004-07-25 14:04:26的发言:

其实如果按照live41的计算方法继续下去(当然,他在sina+cosb的最大值问题上搞错了),会得到和我一样的结果:1.14804337576这个答案竟然比雨夜给出的答案还小,马上就被雨夜枪毙了,5555

小弟,我没搞错啊! 这里是sina+cosa而不是sina+cosb,所以…… 根据sin2a+cos2a=1的性质, 我用(sina+cosa)2 = sin2a+2sinacosa+cos2a = 1+2sinacosa 其中2sinacosa = sin2a这个性质你不会说考完高考就忘了吧? 我在三角函数这一part没算错啊!

另外,感谢knocker的支持,您果然是“敲门砖(者)”啊!

2004-07-25 14:25
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

续第27楼:

我用sina+cosa = sqrt(根号开方)(1+sin2a)来求最大值,没问题……

再提供一种方法:

照着这个,就是利用cosa = sin (90-a)的性质, sina+sin(90-a) = 2 sin(a+90-a)/2 * cos(a-90+a)/2

俗话说,hero有所为有所不为,我虽不是hero,但我这人就是固执, 我就是累死我也要干掉这题,tmd!!!

为了想这题我连初中公式手册都从阁楼里翻出来了,誓死保卫钓鱼台!(慢着,好像台词错了)

[此贴子已经被作者于2004-07-25 14:43:24编辑过]

2004-07-25 14:34
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

楼主用了三层循环,算得我的机子都发蒙,我觉得有必要化简一下! 仍旧重新开始:

vtcosa =1000 (0<a<90) ...(1) 1.89t - vtsina = 1160 (1.0<v<2.0) (600<t<1200) ...(2) //我从这里入手吧……

第一步仍旧同第23楼我的帖子: (2) - (1) = 1.89t - vtsina - vtcosa = 1160 - 1000 -> t(1.89 - v(sina + cosa)) = 160

这里开始变化: t = 160 / (1.89 - v(sina + cosa)) //就只是移动过去剩下t 由题意得 600<t<1200 => 600< 160 / (1.89 - v(sina + cosa)) <1200 这样一来剩下两个变量,化简得: 15< 4 / (1.89 - v(sina + cosa)) <30

移项: 1.89*15 - 15v(sina + cosa) < 4 < 1.89*30 - 30v(sina + cosa) 左边: 28.35 - 4 < 15v(sina + cosa) ...(3) 右边: 30v(sina + cosa) < 56.7 - 4 ...(4)

得到: 24.35/15 < v(sina + cosa) < 52.7/30 //余下两个变量 而且其中三角函数可以得到最大值最小值,这样减少一个循环节省好多时间

待续……

2004-07-25 15:00
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 
以下是引用live41在2004-07-25 12:16:19的发言:

v*t*cos(a) = 1000 (0<a<90)...(1) 1.89*t-v*t*sin(a) = 1160 (1.0<v<2.0) (600<t<1200)...(2)

(2)-(1) = 1.89t-vtsina-vtcosa = 1160-1000 -> t(1.89-v(sina+cosa)) = 160 -> v(sina+cosa) = 1.89-160/t -> v = (1.89-160/t)/(sina+cosa)

其中(sina+cosa)2 = sin2a+2sinacosa+cos2a = 1+sin2a -> sina+cosa = sqrt(1+sin2a) 因为0<a<90 => 0<2a<180 => 0<sin2a<1 所以取a->1(假设令a=1) 因为600<t<1200, v取minimum, 所以取t->600(假设令t=600) v = (1.89-160/600)/1 = 1.623

雨夜探月老师给出的“v的最小值是1.43或精度更高”是怎么算的呢?我哪里算错了呢?

我在第29楼得到的式子:24.35/15 < v(sina + cosa) < 52.7/30

用windows自带的计算机粗略算一下1.6233...(循环无穷)< v(sina+cosa) <1.7566...(循环无穷)

这跟我在第23楼的计算的自以为的最后结果不约而同地有1.623这个数字,

这说明了,神vLinux飘飘小弟说得对,我在sina+cosa的最小值方面算错了,不好意思!

2004-07-25 15:14
快速回复:穷举搜索法解方程组(待高手指点)
数据加载中...
 
   



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

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