陳凱
查閱文獻資料,可以發(fā)現(xiàn)“計算思維”這一名詞時常和“抽象”“建?!钡让~有密切的聯(lián)系,或許相當多的老師認可這種說法:“運用計算思維來解決問題的過程中可能涉及到抽象、建模等方法?!钡舴催^來說“當解決某問題過程中用到了抽象、建模的方法,則體現(xiàn)出了計算思維的運用”,這樣的觀點就很值得懷疑了。那么問題是,在什么樣的情況下,我們在解決問題的過程中用到了抽象、建模的方法,并且也能同時說,問題解決方案的產(chǎn)生運用到了計算思維?
● 用數(shù)學模型模擬日常事件
考慮現(xiàn)實中這樣一個常見的簡單問題:假設有三人通過舉手投票來做出某個決定(如決定是玩還是學習?),每人1票,當多數(shù)人投贊成票,即有兩人或兩人以上舉手時,某決定(那就去玩吧!)被通過。要求學生們設計一個算法:根據(jù)三人舉手投票情況,判斷某決定是否被通過。圖1是使用Raptor軟件制作的既可用于算法描述又可直接按流程執(zhí)行的流程圖。當學生們學習了分支結(jié)構(gòu)的流程后,針對該任務所繪制出來的流程圖有不少與圖1類似。
不妨在頭腦中想象一下投票的場景:如果您不是這三位投票者中的一位,那么您究竟是如何知道這項表決是否通過呢?如果投票人數(shù)非常多,或許就不得不去做加1計數(shù)的工作;然而,如果僅僅只有三位投票者,大部分人并不會真的去做加1的數(shù)學運算,而只是簡單地看一下是否有兩位或三位舉手。這也說明,對于三人投票的場景,算法中的方法不一定如實地反映人頭腦中的方法,之所以大部分學生在算法中用到了數(shù)學上的加法,是因為他們將普遍的涉及數(shù)字、符號以及相關數(shù)學運算的模型,很自然地應用到了這一特定場景中。
當人們提到“抽象”的時候,一般是指從一組事物中抽取共相的過程。那么,通過數(shù)學加法結(jié)合不等式判斷來確定表決結(jié)果,與人頭腦通過直觀觀察來確定表決結(jié)果,兩者是否存在可抽取的共相?僅就三人投票的事件而言,如果共相存在,那應該只是存在于系統(tǒng)(將人的頭腦和計算裝置都視作系統(tǒng))輸入值和輸出值的對應關系上,也就是說,就表決過程的外在效果而言,現(xiàn)實場景和模擬場景這兩者的過程是一致的,但具體的內(nèi)在判斷過程卻是不同的。對整個事件輸入和輸出過程的模擬,借助數(shù)學抽象和建模,完美模擬出系統(tǒng)表象上的功能,而流程圖只是將用數(shù)學已經(jīng)完成了的模型給描繪出來。那么問題是,學生將簡單的數(shù)學模型運用在模擬表決過程中,這雖然可以說是數(shù)學思維的運用,但計算思維的運用又從何體現(xiàn)?
● 與計算思維相關的抽象與建模,和數(shù)學中的抽象與建模不同
接著考慮另一種情況,假設投票問題場景中的投票者人數(shù)有很大程度的增加,在現(xiàn)實中,這樣的情況是難以用直觀的方法來判斷投票結(jié)果的。如果讓一個沒有學習過算法的學生來試著用流程圖模擬此過程,很有可能會繪制出如圖2所示的模樣;或者,也會有學生繪制出一個類似循環(huán)結(jié)構(gòu)的流程,但這個流程沒有控制進出循環(huán)語句塊的條件,而是直接標注有“問詢所有人”的語句。雖然人的頭腦很容易把握這些非標準的流程圖的實質(zhì)過程,但計算機并不具有直觀地理解這些非標準的流程圖中所要表達的“要向所有人搜集投票結(jié)果”這一意圖的智慧。
從數(shù)學的角度看,“對集合中的所有元素進行某種一致的操作”是一個相當合理的要求。然而將這個要求轉(zhuǎn)換為標準的流程圖,卻不得不增加許多細節(jié)。一個學習過算法的學生能比較像模像樣地繪制出模擬投票場景的循環(huán)結(jié)構(gòu)的標準流程圖來,如使用某個變量來控制循環(huán)次數(shù);使用諸如i=i+1這種通過將增加的值來覆蓋變量自身值的方法來計數(shù);在循環(huán)結(jié)構(gòu)外對某個變量清零,在循環(huán)結(jié)構(gòu)中用累加的方法統(tǒng)計投贊成票的數(shù)量。如果追問一下,這位學生是如何知道應當這樣去做的,答案大概率是因為在學習時被告知要如此,或者是被軟件(如Raptor)所限定而只能如此。
規(guī)范的流程圖繪制方法有著相當統(tǒng)一的模式,但這種模式之所以是現(xiàn)在人們所看到的樣子,其背后隱藏了模式形成的原因,而這個原因和機器實施計算的能力和方式是密切相關的。筆者認為,這些流程結(jié)構(gòu)實際上是對機器底層的計算過程的封裝和抽象,而并非是對某個現(xiàn)實事件的抽象。盡管可以將繪制流程圖本身視作抽象和建模,但學生在學習用流程圖描繪算法時,在將數(shù)學語言轉(zhuǎn)化為規(guī)范的流程圖時,只是運用了與計算思維有關的抽象和建模的已有成果,而并沒有運用到計算思維本身;如果說學生們在問題解決過程中的確運用到了抽象與建模,那也僅僅是數(shù)學方法上的抽象和建模,其中不涉及計算機科學特有的方法。關于怎樣的抽象和建模的過程運用到了計算思維,這個問題的答案恐怕非常復雜,可能涉及如何排除人腦的直觀,更是涉及了關于可計算性問題的討論。筆者考慮用一種簡單的方法來判別計算思維運用與否的必要條件:解決問題的過程應當與日常頭腦用數(shù)學方法直接進行計算并得出結(jié)果的過程是有所不同的。否則,便可以認為其運用了數(shù)學思維而非計算思維來解決了問題。
以上討論是筆者設計下面這些流程圖繪制任務的原因。任務是這樣的:讓學生們試著不用分支結(jié)構(gòu)來完成原本需要用到分支結(jié)構(gòu)的判斷的功能。仍然以模擬三人投票為例,可行的方法不止一種,下頁圖3所示的是用序號加調(diào)用數(shù)組元素的方法,將總共8種投票情況按二進制方式計數(shù),并轉(zhuǎn)換為相應十進制數(shù)的索引,便能從數(shù)組中取出對應索引值的表決結(jié)果。而下頁圖4所示的是另一種方法,通過取整運算,將1設置為閾值,凡是大于等于1的情況,最后都顯示1作為表決通過,小于1的情況,最后都顯示0作為表決不通過,當然,同樣可以借助數(shù)組的方法,將0和1作為索引值,調(diào)取文字顯示的表決結(jié)果。在其他設計環(huán)境中,有更多的方法可以使用,如在Python中可以采用限定打印次數(shù)的方法,在邏輯電路中可以結(jié)合與門和或門形成組合邏輯的方法,等等。而不同的計算模型也有其各自頗具特色的方法,如用馬爾可夫算法、標簽系統(tǒng)、圖靈機等都能夠?qū)崿F(xiàn)該任務,這里就不展開了。
本文接下來重點圍繞圖4所示的方法展開討論,這種方法實際上揭示了一種可能性:在算法中,所謂的分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)都不是理所當然存在著的,在程序流程分支判斷的時候,實際上是進行了某個運算,這個運算的結(jié)果就匹配了后續(xù)的某個動作。如果考察某個通用計算機底層的工作過程,就可以看出所謂的判斷和分支,實際上是經(jīng)歷了對后續(xù)所要調(diào)用指令的地址的匹配過程。當學生們面對分支結(jié)構(gòu)本身的時候,就已經(jīng)是面對著一個現(xiàn)成的模型。雖然說基礎教育階段的學生一般不會學習到通用計算機底層實現(xiàn)相關的知識,但通過不用分支結(jié)構(gòu)來完成原本需要用到分支結(jié)構(gòu)的判斷的任務,學生們能夠直觀地感知到,可以用數(shù)學的方法建立一個模型,來模擬出判斷的過程,而不是直接用分支結(jié)構(gòu)的語句來完成判斷。這里必須區(qū)分“用分支結(jié)構(gòu)完成數(shù)學判斷”和“用數(shù)學方法完成分支結(jié)構(gòu)的判斷”兩者的區(qū)別,后者的過程與日常頭腦中用數(shù)學方法直接進行計算并得出結(jié)果的過程是不同的。如果用筆者提出的判別計算思維運用與否的必要條件,對于“用分支結(jié)構(gòu)完成數(shù)學判斷”這一過程是否運用了計算思維的結(jié)論是否定的,后者“用數(shù)學方法完成分支結(jié)構(gòu)的判斷”這一過程作為候選項存活了下來,但若說后者的過程確實運用到了計算思維,論據(jù)仍然是不充分的。
● 設計活動體現(xiàn)出為計算裝置的能行而進行抽象和建模的過程
那么,何種情況下的抽象和建模,可以認為與計算思維的運用有關?對于這個問題,筆者遍查文獻資料而未得,甚至很少有人將其作為問題來提出。筆者認為,是否考慮到一個計算裝置的能行,是判斷計算思維運用與否的一個充分條件。
關于三人投票表決的例子,除了通過對三人投贊成票總數(shù)除以2再取整的數(shù)學方法來實現(xiàn)模擬,還有另一種方法(大概是更接近現(xiàn)實的方法),即觀察是否存在a和b同時舉手,或a和c同時舉手,或b和c同時舉手,或a、b和c同時舉手的任意一種情況。但因為a、b和c同時舉手的情況已經(jīng)包含了前三種情況,所以并不需要單獨加以判斷。如果寫成邏輯運算式,就是r=a*b+a*c+b*c,其中所有變量都是布爾值的,若計算結(jié)果r為True,則當作表決通過,若計算結(jié)果r為False,則當作表決不通過。這樣一來,算法流程也變得非常簡單,只要輸入三個投票數(shù)據(jù)(用1代表舉手,0代表不舉手)后,計算并輸出r值就可以了。
十分遺憾的是,或者說很幸運的是,Raptor這個流程圖模擬軟件只支持在判斷框中進行邏輯運算,而不支持在處理語句框中進行邏輯運算。之所以說遺憾,是因為在教學中不得不放棄Raptor而改用其他工具來描繪通過邏輯運算模擬投票表決過程的算法。之所以說幸運,是因為Raptor軟件能力的不足,恰恰提供了討論計算裝置“能行”問題的入口。
怎樣讓Raptor邏輯運算能力的“不可行”變?yōu)椤澳苄小??考慮到Raptor中數(shù)學運算的能力是比較充分,所以可以試著用數(shù)學運算來模擬邏輯運算(計算機的真實運行過程恰恰反過來:用邏輯運算模擬數(shù)學運算,而計算機自身的邏輯運算是依靠硬件電路實現(xiàn)的)??梢园l(fā)現(xiàn),邏輯的與運算可以簡單地用乘法來模擬,但邏輯的或運算卻不能簡單地用數(shù)學中的加法來替代。因此,希望能創(chuàng)設某個數(shù)學公式,當兩個輸入均為0的時候運算結(jié)果也為0,當兩個輸入有一個1,或兩個都是1的時候,運算結(jié)果都為1。
有沒有這樣的公式呢?人工智能中的感知器概念提供了解決思路,那就是為輸入值設置權重和偏置。在Raptor軟件中可使用以下公式:
r=floor(a*0.8+b*0.8+0.2)
當a和b變量的輸入值限定為0或1的時候,計算r值的過程就模擬了邏輯或門的運算過程。在該公式中,0.8是權重,而0.2是偏置。如果在Python環(huán)境中,使用公式r=int(a*0.8+b*0.8+0.2) 也能實現(xiàn)同樣的效果。雖然說Python具備了完整的邏輯運算功能,并不需要用這樣的辦法來進行模擬,但也可以在教學中故意限制邏輯運算符的使用,讓學生思考如何找到替代邏輯運算的方法。
當前,計算機底層的邏輯運算是依靠晶體管或場效應管來實現(xiàn)的,但人的頭腦中神經(jīng)元的運作方式,相對而言卻與設置權重和偏置的方法更為接近。這讓人聯(lián)想到在關于計算思維內(nèi)涵的討論中,認為計算思維包含了運用計算機科學的基礎概念對人類行為進行理解的思維活動的觀點。
根據(jù)用數(shù)學方法模擬出的或門,再結(jié)合用乘法模擬的與門,可以將Raptor的流程圖描繪成圖5所示的樣子。
該算法首先通過某種特定的數(shù)學計算來模擬邏輯門的功能,使得數(shù)學模型的輸入和輸出與邏輯運算的輸入和輸出具有一致性,然后再利用模型的功能來實現(xiàn)更高層次上的功能。這就體現(xiàn)出了為計算裝置的能行而進行抽象和建模的過程。