宋美蕓 謝佐杰
算法是高中數(shù)學(xué)中的重要內(nèi)容,也是計(jì)算機(jī)科學(xué)的基礎(chǔ),是連接問題與計(jì)算機(jī)程序語言之間的橋梁.若一元方程[f(x)=0]的左端函數(shù)[f(x)]不是關(guān)于x的多項(xiàng)式,那么我們就將類方程稱之為超越方程.超越方程一般沒有解析解,而只有數(shù)值解或近似解.求解超越方程近似解的方法有很多,而利用算法或者計(jì)算機(jī)程序語言來求解是最為簡便的一種方法.筆者結(jié)合一個實(shí)際應(yīng)用問題,來談一談算法在求解超越方程中的應(yīng)用.
問題:內(nèi)江某玻璃廠的工人需要切割一塊如圖1所示的玻璃窗.若該窗戶的橫梁長為a、豎梁高為b、圓弧長為[l],為了能準(zhǔn)確切割出這塊玻璃,工人必須知道此圓弧半徑[R].求該圓弧的半徑[R].
解析:如圖2,我們先作輔助線,將扇形擴(kuò)充為一個完整的圓,連接AB、AO、BO,其中AO、BO為圓的半徑,[AB]為圓的一條弦,作弦[AB]的中垂線DO,則DO必過圓心且平分[∠AOB],令弧[AB]所對的圓心角∠AOB=θ(θ為弧度角),建立等式[l=θ?R],[sinθ2=a2+b22R],兩式聯(lián)立消去[θ]得[sinl2R=a2+b22R].該方程屬于超越方程,其中R是要求的未知量,該方程無法直接求解.一般,我們會采用常規(guī)方法,利用函數(shù)與方程的思想,令[fR=sinl2R][=a2+b22R],在同一個平面直角坐標(biāo)中分別作出這兩個函數(shù)的圖象,于是兩圖象交點(diǎn)的橫坐標(biāo)即為方程的解.此方法在理論上可行,但在實(shí)際操作中存在很大的困難.因?yàn)橐话阄覀兒茈y作出準(zhǔn)確的圖形,并且通過畫圖得出的結(jié)果必然存在很大的誤差,所以這種方法并不是解答這個問題的最好方法.
我們可以轉(zhuǎn)換思路,利用算法來求解.首先,我們需要確保數(shù)據(jù)的準(zhǔn)確性,將數(shù)據(jù)的單位設(shè)置為毫米,這樣可以將誤差控制在0.01毫米內(nèi).然后,我們可以從0.01毫米開始取值,讓R的值逐次遞增0.01,分別將其代入方程左邊和右邊的兩個等式[M=sinl2R]、[N=a2+b22R]中,并算出M和N的值,判斷|M-N|是否小于或等于0.001,其程序框圖如圖3所示.如果該值小于或等于0.001,我們就可以近似認(rèn)為m=n,此時R的值就是方程的解.人工計(jì)算肯定需要很長的時間,但計(jì)算機(jī)可以以每秒上億次的計(jì)算速度來進(jìn)行計(jì)算,得出結(jié)果所花的時間不足一秒,所以此方法可行.
該算法的關(guān)鍵是在R值遞增的過程中,判斷等式兩邊的差值是否小于或等于0.001.由于三角函數(shù)的正弦值不會大于1,我們可以將程序設(shè)計(jì)為:當(dāng)?shù)仁絻蛇叺牟钪荡笥诨虻扔?時,R每次遞增1;當(dāng)?shù)仁絻蛇叺牟钪敌∮?時,R每次遞增0.01,這樣可以有效地提高運(yùn)算的效率,并且使最終計(jì)算出的結(jié)果誤差在0.01內(nèi).如果我們想提高計(jì)算的精確度,就可以把當(dāng)差值小于1時,R每次遞增的值設(shè)置得更小,這樣可以按照我們的需要來設(shè)置算法.
該算法的程序如下:
$(function ( ) {
var $a = $("#input-a");
var $b = $("#input-b");
var $l = $("#input-l");
$("#getResult").on("click", function (? ? ? ) {
var l = parseFloat($l.val( )); //弧長
var a = parseFloat($a.val( )); //長
var b = parseFloat($b.val( )); //高
if (isNaN(l) || isNaN(a) || isNaN(b))
{ alert("只能輸入數(shù)字");
return; }
var r = 1; var d = null;//差值小于0.001
var count = 0; //計(jì)算次數(shù)
var c = Math.sqrt(a * a + b * b);
do { var nd = Math.abs(Math.sin(l / (2 * r)) * (2 * r) - c);
if (nd <= 1) { //差值小于1
r += 0.01;? }
else { r += 1;? }
count++;? ? d = nd;
if (count > 200000) { alert('無法計(jì)算出結(jié)果');
return;? ?}
} while (d > 0.001);
alert("r=" + r.toFixed(2));
return false;? })});
其程序架構(gòu)過程如圖4所示,其運(yùn)算過程如圖5所示.
如果所輸入的參數(shù)不合要求,出現(xiàn)如[l≤a2+b2]的情況,則計(jì)算結(jié)果會提示“無法計(jì)算出結(jié)果”.為了防止程序進(jìn)入死循環(huán),我們需要增加內(nèi)容:在計(jì)算200000次后,仍然沒有找到滿足條件的解,則為無解.此方法還可以推廣到解答其它不易直接求解的方程中.
(作者單位:四川省內(nèi)江市第一中學(xué))