iT邦幫忙

2

C++ for loop 不能動

我是想要找一個橢圓的面積 但不能用pi
precision我想要的準確率 當我輸入0.0001 它能顯示答案 但0.0000001時等多一個多小時也沒結果..

在上圖中,通過查看小網格的中心是否在圓內,我們算出應該為圓的面積考慮20個小正方形。 因此,該圓的估計面積為4 * 20 * 0.2 ^ 2 , 這是我的思路。


查看小網格的中心是否在圓內是利用了這個公式

#include <iomanip>
#include <iostream>
using namespace std;
#include <math.h>
double precision;
double  xaxis;
double  yaxis;
unsigned long long int squares=0;
double powa;
double powb;

main(){


cout << "Please enter the precision: " << endl;
cin >> precision;
cout << "Please enter the width and height of the ellipse: " << endl;
cin >> xaxis >> yaxis;
powa = pow(xaxis,2);
powb = pow(yaxis,2);

double i;
for (i= precision / 2;i < xaxis ;i = i + precision){
double j;
for( j = precision / 2;j <= yaxis ;j = j + precision){
	if(pow(i,2) / powa  + pow(j,2) / powb <= 1){
		 ++squares;
	}}}

long double area = 4.0*squares*precision*precision;
cout << setprecision(9) << area << endl;

    return 0;


}
看更多先前的討論...收起先前的討論...
外迴圈加上 判斷, 當 i 是 xaxis 比率每10%, 就丟個訊息出來.
你可以等看看一天能不能執行完 看起來會跑很久
lam814 iT邦新手 5 級 ‧ 2020-03-06 16:19:18 檢舉
不能跑太久 要課上展示給老師
fillano iT邦超人 1 級 ‧ 2020-03-06 18:27:19 檢舉
那你就把橢圓半徑跟精確度降低,自然跑不久。
fillano iT邦超人 1 級 ‧ 2020-03-06 18:40:51 檢舉
這個做法是O(n^2),會隨著精確度跟橢圓半徑快速增加跑的時間。你可以看看怎樣減少計算量,例如橢圓與XY軸交點畫一個三角形,三角形內的點一定在橢圓裡面所以可以用常數時間算完,然後看看怎改迴圈可以達成減少一半計算量之類。(另外,這個直角三角形的斜邊跟橢圓的某條平行的切線中間,才是你要計算的點,這樣可以再少一點計算量)
lam814 iT邦新手 5 級 ‧ 2020-03-06 19:03:49 檢舉
0.0000001是作業的要求
http://www.opencoarrays.org/
用這個會比較快. Fortran 效率高,這又能夠多核.
搭配前面 fillano 說的先算三角形內的.然後遞迴切割.
froce iT邦大師 1 級 ‧ 2020-03-06 21:53:43 檢舉
橢圓的面積是(pi)ab,這實際上是要你求Pi吧?
找比較快速求pi的演算法。
另外你可以把橢圓當成是半徑為a(或b)的正圓的投影,會比較好處理吧。
這樣只需要算一個軸。

線性代數的基本觀念

2 個回答

0
海綿寶寶
iT邦大神 1 級 ‧ 2020-03-07 08:54:23

就式論式
試試看

#include <iostream>
#include <math.h>

using namespace std;

double precision;
double  xaxis;
double  yaxis;
unsigned long long int squares=0;
unsigned long long int loopcnt=0;
double powa;
double powb;
double divi;

int main()
{
    cout << "Please enter the precision: " << endl;
    cin >> precision;
    cout << "Please enter the width and height of the ellipse: " << endl;
    cin >> xaxis >> yaxis;
    powa = pow(xaxis,2);
    powb = pow(yaxis,2);

    double i, j;
    for (i= precision / 2;i < xaxis ;i = i + precision){
        divi = pow(i,2) / powa;
        for( j = precision / 2;j <= yaxis ;j = j + precision) {
            loopcnt++;
	        if ((divi  + (pow(j,2) / powb)) <= 1){
		        ++squares;
	        }
            else {
                break;
            }
       }
    }

    long double area = 4.0*squares*precision*precision;
    cout << "xaxis:" << xaxis << " yaxis:" << yaxis << " precision:" << precision << " area:" << area << endl;
    cout << "Loopcnt:" << loopcnt << " squares:" << squares << " ratio:" << (double)squares/loopcnt << endl;
 
   return 0;
}

如果過得去的話
再來計較細節

2
fillano
iT邦超人 1 級 ‧ 2020-03-07 20:19:51

換個思路,可以用矩形面積來逼近,這樣複雜度會降到O(n)。

我用javascript寫,不過意思一樣。第一個是你的解法,第二個是用矩形逼近:

//let preci = 0.00000001
let preci = 0.0001;
let a = 5;
let b = 3;
let sq = 0;
for(let y=0; y<b; y+=preci) {
    for(let x=0; x<a; x+=preci) {
        if(Math.pow(y,2)/Math.pow(b,2)+Math.pow(x,2)/Math.pow(a,2) <= 1) {
            sq++;
        }
    }
}
console.log(4 * sq * Math.pow(preci,2));

sq = 0;
for(x=0; x<a; x+=preci) {
    // x^2/a^2+y^2/b^2=1
    // y^2=(1-x^2/a^2)*b^2
    // y=sqrt((1-x^2/a^2)*b^2)
    let y = Math.sqrt((1-Math.pow(x,2)/Math.pow(a,2))*Math.pow(b,2));
    sq += y * preci;
}
console.log(sq*4);
fillano iT邦超人 1 級 ‧ 2020-03-07 20:27:50 檢舉

改成這樣跑大約一秒就有結果。

我要發表回答

立即登入回答