SICP · Yr ail argraffiad · Scheme
1.2 Gweithdrefnau a'r Prosesau a Gynhyrchant
Rydym bellach wedi ystyried elfennau rhaglennu: defnyddiasom weithrediadau rhifyddol cyntefig, cyfunasom y gweithrediadau hyn, a haniaethasom y gweithrediadau cyfansawdd hyn drwy eu diffinio fel gweithdrefnau cyfansawdd. Ond nid yw hynny'n ddigon i'n galluogi i ddweud ein bod yn gwybod sut i raglennu. Mae ein sefyllfa'n debyg i sefyllfa rhywun sydd wedi dysgu'r rheolau ar gyfer symud y darnau mewn gwyddbwyll ond nad yw'n gwybod dim am agoriadau nodweddiadol, tactegau na strategaeth. Fel y chwaraewr gwyddbwyll newydd, nid ydym eto'n gwybod y patrymau defnydd cyffredin yn y maes. Nid oes gennym y wybodaeth am ba symudiadau sy'n werth eu gwneud (pa weithdrefnau sy'n werth eu diffinio). Nid oes gennym y profiad i ragweld canlyniadau gwneud symudiad (gweithredu gweithdrefn).
Mae'r gallu i ddychmygu canlyniadau'r gweithredoedd dan ystyriaeth yn hanfodol i ddod yn rhaglennydd arbenigol, fel y mae mewn unrhyw weithgaredd creadigol sy'n cyfuno elfennau. Wrth ddod yn ffotograffydd arbenigol, er enghraifft, rhaid dysgu sut i edrych ar olygfa a gwybod pa mor dywyll y bydd pob rhan yn ymddangos ar brint ar gyfer pob dewis posibl o amodau dinoethi a datblygu. Dim ond wedyn y gellir rhesymu'n ôl, gan gynllunio fframio, goleuo, dinoethi a datblygu i gael yr effeithiau a ddymunir. Felly hefyd gyda rhaglennu, lle rydym yn cynllunio'r trywydd gweithredu y bydd proses yn ei ddilyn ac yn rheoli'r broses drwy raglen. I ddod yn arbenigwyr, rhaid inni ddysgu dychmygu'r prosesau a gynhyrchir gan amrywiol fathau o weithdrefnau. Dim ond ar ôl datblygu'r sgìl hwn y gallwn ddysgu adeiladu rhaglenni sy'n arddangos yr ymddygiad a ddymunir yn ddibynadwy.
Patrwm ar gyfer esblygiad lleol proses gyfrifiadurol yw gweithdrefn. Mae'n pennu sut yr adeiladir pob cam o'r broses ar y cam blaenorol. Hoffem allu gwneud gosodiadau am ymddygiad cyffredinol, neu fyd-eang, proses y mae gweithdrefn wedi pennu ei hesblygiad lleol. Mae hyn yn anodd iawn yn gyffredinol, ond gallwn o leiaf geisio disgrifio rhai patrymau nodweddiadol yn esblygiad prosesau.
Yn yr adran hon byddwn yn archwilio rhai “siapiau” cyffredin ar gyfer prosesau a gynhyrchir gan weithdrefnau syml. Byddwn hefyd yn ymchwilio i'r cyfraddau y mae'r prosesau hyn yn defnyddio'r adnoddau cyfrifiadurol pwysig, amser a gofod. Mae'r gweithdrefnau y byddwn yn eu hystyried yn syml iawn. Mae eu rôl yn debyg i rôl patrymau prawf mewn ffotograffiaeth: patrymau prototeip sydd wedi'u gorsymleiddio ydynt, yn hytrach nag enghreifftiau ymarferol ynddynt eu hunain.
1.2.1Dychweliad Llinol ac Iteru
Dechreuwn drwy ystyried y ffwythiant ffactoraidd, a ddiffinnir gan
(define (factorial n)
(if (= n 1)
1
(* n (factorial (- n 1)))))Gallwn ddefnyddio model amnewid 1.1.5 i wylio'r weithdrefn hon ar waith yn cyfrifiannu 6!, fel y dangosir yn Ffigur 1.3.
Ffigur 1.3: Proses ddychweliadol linol ar gyfer cyfrifiannu 6!.
Gadewch inni bellach edrych ar gyfrifiannu ffactorialau o safbwynt gwahanol. Gallem ddisgrifio rheol ar gyfer cyfrifiannu
productcounter * product counter counter + 1
a phennu mai
Unwaith eto, gallwn ail-lunio ein disgrifiad fel gweithdrefn ar gyfer cyfrifiannu ffactorialau:29
(define (factorial n)
(fact-iter 1 1 n))
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product)
(+ counter 1)
max-count)))Fel o'r blaen, gallwn ddefnyddio'r model amnewid i ddelweddu'r broses o gyfrifiannu 6!, fel y dangosir yn Ffigur 1.4.
Ffigur 1.4: Proses iteru linol ar gyfer cyfrifiannu 6!.
Cymharwch y ddwy broses. O un safbwynt, prin y maent yn ymddangos yn wahanol o gwbl. Mae'r ddwy'n cyfrifiannu'r un ffwythiant mathemategol ar yr un parth, ac mae angen nifer o gamau sy'n gyfrannol ag
Ystyriwch y broses gyntaf. Mae'r model amnewid yn datgelu siâp o ehangu ac yna grebachu, fel y mae'r saeth yn Ffigur 1.3 yn ei ddangos. Mae'r ehangu'n digwydd wrth i'r broses adeiladu cadwyn o weithrediadau gohiriedig (cadwyn o luosiadau yn yr achos hwn). Mae'r crebachu'n digwydd wrth i'r gweithrediadau gael eu cyflawni mewn gwirionedd. Gelwir proses o'r math hwn, a nodweddir gan gadwyn o weithrediadau gohiriedig, yn broses ddychweliadol. Mae cyflawni'r broses hon yn ei gwneud yn ofynnol i'r dehonglydd gadw cofnod o'r gweithrediadau sydd i'w cyflawni'n ddiweddarach. Wrth gyfrifiannu
Mewn cyferbyniad, nid yw'r ail broses yn tyfu ac yn crebachu. Ar bob cam, y cyfan y mae angen inni gadw cofnod ohono, ar gyfer unrhyw product, counter, a max-count. Galwn hyn yn broses iteru. Yn gyffredinol, proses iteru yw un y gellir crynhoi ei chyflwr gan nifer sefydlog o newidynnau cyflwr, ynghyd â rheol sefydlog sy'n disgrifio sut y dylid diweddaru'r newidynnau cyflwr wrth i'r broses symud o gyflwr i gyflwr, a phrawf terfynu (dewisol) sy'n pennu'r amodau y dylai'r broses derfynu oddi tanynt. Wrth gyfrifiannu
Gellir gweld y cyferbyniad rhwng y ddwy broses mewn ffordd arall. Yn yr achos iteru, mae newidynnau'r rhaglen yn rhoi disgrifiad cyflawn o gyflwr y broses ar unrhyw adeg. Pe baem yn atal y cyfrifiad rhwng camau, y cyfan y byddai angen inni ei wneud i ailddechrau'r cyfrifiad fyddai rhoi gwerthoedd tri newidyn y rhaglen i'r dehonglydd. Nid felly gyda'r broses ddychweliadol. Yn yr achos hwn, ceir rhywfaint o wybodaeth “gudd” ychwanegol, a gedwir gan y dehonglydd ac nad yw wedi'i chynnwys yn newidynnau'r rhaglen, sy'n dangos “ble mae'r broses” wrth fynd drwy'r gadwyn o weithrediadau gohiriedig. Po hiraf y gadwyn, mwyaf o wybodaeth y mae'n rhaid ei chadw.30
Wrth gyferbynnu iteru a dychweliad, rhaid inni fod yn ofalus i beidio â chymysgu'r syniad o broses ddychweliadol â'r syniad o weithdrefn ddychweliadol. Pan ddisgrifiwn weithdrefn yn ddychweliadol, rydym yn cyfeirio at y ffaith gystrawennol fod diffiniad y weithdrefn yn cyfeirio (naill ai'n uniongyrchol neu'n anuniongyrchol) at y weithdrefn ei hun. Ond pan ddisgrifiwn broses fel un sy'n dilyn patrwm sydd, er enghraifft, yn ddychweliadol linol, rydym yn sôn am sut mae'r broses yn esblygu, nid am gystrawen y ffordd yr ysgrifennir gweithdrefn. Gall ymddangos yn annifyr ein bod yn cyfeirio at weithdrefn ddychweliadol megis fact-iter fel un sy'n cynhyrchu proses iteru. Fodd bynnag, proses iteru yw'r broses mewn gwirionedd: mae ei thri newidyn cyflwr yn cofnodi ei chyflwr yn llwyr, a dim ond tri newidyn y mae angen i ddehonglydd gadw cofnod ohonynt er mwyn cyflawni'r broses.
Un rheswm pam y gall y gwahaniaeth rhwng proses a gweithdrefn fod yn ddryslyd yw bod y rhan fwyaf o weithrediadau ieithoedd cyffredin (gan gynnwys Ada, Pascal, a C) wedi'u dylunio fel bod dehongli unrhyw weithdrefn ddychweliadol yn defnyddio swm o gof sy'n tyfu gyda nifer y galwadau gweithdrefn, hyd yn oed pan fo'r broses a ddisgrifir, mewn egwyddor, yn broses iteru. O ganlyniad, dim ond drwy ddefnyddio “cystrawennau dolennu” pwrpasol megis do, repeat, until, for, a while y gall yr ieithoedd hyn ddisgrifio prosesau iteru. Nid yw gweithrediad Scheme y byddwn yn ei ystyried ym Mhennod 5 yn rhannu'r diffyg hwn. Bydd yn cyflawni proses iteru mewn gofod cyson, hyd yn oed os disgrifir y broses iteru gan weithdrefn ddychweliadol. Gelwir gweithrediad â'r briodwedd hon yn ddychweliadol yn y gynffon. Gyda gweithrediad sy'n ddychweliadol yn y gynffon, gellir mynegi iteru drwy fecanwaith arferol galwad gweithdrefn, fel mai dim ond fel siwgr cystrawennol y mae cystrawennau iteru arbennig yn ddefnyddiol.31
Ymarfer 1.9: Mae pob un o'r ddwy weithdrefn ganlynol yn diffinio dull ar gyfer adio dau gyfanrif positif yn nhermau'r gweithdrefnau
inc, sy'n cynyddu ei harg 1, adec, sy'n lleihau ei harg 1.(define (+ a b) (if (= a 0) b (inc (+ (dec a) b)))) (define (+ a b) (if (= a 0) b (+ (dec a) (inc b))))Gan ddefnyddio'r model amnewid, dangoswch y broses a gynhyrchir gan bob gweithdrefn wrth werthuso
(+ 4 5). Ai prosesau iteru neu brosesau dychweliadol yw'r rhain?
Ymarfer 1.10: Mae'r weithdrefn ganlynol yn cyfrifiannu ffwythiant mathemategol o'r enw ffwythiant Ackermann.
(define (A x y) (cond ((= y 0) 0) ((= x 0) (* 2 y)) ((= y 1) 2) (else (A (- x 1) (A x (- y 1))))))Beth yw gwerthoedd y mynegiadau canlynol?
(A 1 10) (A 2 4) (A 3 3)Ystyriwch y gweithdrefnau canlynol, lle mai
Ayw'r weithdrefn a ddiffiniwyd uchod:(define (f n) (A 0 n)) (define (g n) (A 1 n)) (define (h n) (A 2 n)) (define (k n) (* 5 n n))Rhowch ddiffiniadau mathemategol cryno o'r ffwythiannau a gyfrifiannir gan y gweithdrefnau
f,g, ahar gyfer gwerthoedd cyfanrif positif o. Er enghraifft, mae (k n)yn cyfrifiannu.
1.2.2Dychweliad Coeden
Gelwir patrwm cyfrifiannu cyffredin arall yn ddychweliad coeden. Er enghraifft, ystyriwch gyfrifiannu dilyniant rhifau Fibonacci, lle mae pob rhif yn swm y ddau sy'n ei ragflaenu:
Yn gyffredinol, gellir diffinio rhifau Fibonacci drwy'r rheol
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))Ystyriwch batrwm y cyfrifiad hwn. I gyfrifiannu (fib 5), rydym yn cyfrifiannu (fib 4) a (fib 3). I gyfrifiannu (fib 4), rydym yn cyfrifiannu (fib 3) a (fib 2). Yn gyffredinol, mae'r broses sy'n esblygu yn edrych fel coeden, fel y dangosir yn Ffigur 1.5. Sylwch fod y canghennau'n rhannu'n ddwy ar bob lefel (heblaw ar y gwaelod); mae hyn yn adlewyrchu'r ffaith fod y weithdrefn fib yn ei galw ei hun ddwywaith bob tro y'i gelwir.
Ffigur 1.5: Y broses ddychweliadol goeden a gynhyrchir wrth gyfrifiannu (fib 5).
Mae'r weithdrefn hon yn addysgiadol fel prototeip o ddychweliad coeden, ond mae'n ffordd ofnadwy o gyfrifiannu rhifau Fibonacci oherwydd ei bod yn gwneud cymaint o gyfrifiannu diangen. Sylwch yn Ffigur 1.5 fod cyfrifiad cyfan (fib 3)—bron hanner y gwaith—yn cael ei ddyblygu. Yn wir, nid yw'n anodd dangos mai nifer yr adegau y bydd y weithdrefn yn cyfrifiannu (fib 1) neu (fib 0) (nifer y dail yn y goeden uchod, yn gyffredinol) yw
Gallwn hefyd lunio proses iteru ar gyfer cyfrifiannu rhifau Fibonacci. Y syniad yw defnyddio pâr o gyfanrifau
Nid yw'n anodd dangos, ar ôl cymhwyso'r trawsffurfiad hwn
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))Iteriad llinol yw'r ail ddull hwn ar gyfer cyfrifiannu
Ni ddylid casglu o hyn fod prosesau dychweliadol coeden yn ddiwerth. Pan ystyriwn brosesau sy'n gweithredu ar ddata wedi'u strwythuro'n hierarchaidd yn hytrach nag ar rifau, byddwn yn gweld bod dychweliad coeden yn arf naturiol a phwerus.32 Ond hyd yn oed mewn gweithrediadau rhifol, gall prosesau dychweliadol coeden fod yn ddefnyddiol i'n helpu i ddeall a dylunio rhaglenni. Er enghraifft, er bod y weithdrefn fib gyntaf yn llawer llai effeithlon na'r ail, mae'n fwy uniongyrchol, gan nad yw ond ychydig mwy na throsi diffiniad dilyniant Fibonacci i Lisp. Er mwyn llunio'r algorithm iteru, roedd angen sylwi y gellid ail-lunio'r cyfrifiad fel iteriad â thri newidyn cyflwr.
Enghraifft: Cyfrif ffyrdd o roi newid
Dim ond ychydig o ddyfeisgarwch sydd ei angen i feddwl am yr algorithm Fibonacci iteru. Mewn cyferbyniad, ystyriwch y broblem ganlynol: mewn sawl ffordd wahanol y gallwn roi newid am $1.00, o gael darnau arian hanner doler, chwarter doler, deg sent, pum sent, ac un sent? Yn fwy cyffredinol, a allwn ysgrifennu gweithdrefn i gyfrifiannu nifer y ffyrdd o newid unrhyw swm penodol o arian?
Mae ateb syml i'r broblem hon ar ffurf gweithdrefn ddychweliadol. Tybiwch ein bod yn meddwl am y mathau o ddarnau arian sydd ar gael fel rhai sydd wedi'u trefnu mewn rhyw drefn. Yna mae'r berthynas ganlynol yn dal:
Mae nifer y ffyrdd o newid swm
- nifer y ffyrdd o newid swm
gan ddefnyddio pob math o ddarn arian heblaw'r cyntaf, ynghyd â - nifer y ffyrdd o newid swm
gan ddefnyddio pob un o'r math o ddarnau arian, lle mai yw gwerth y math cyntaf o ddarn arian.
I weld pam mae hyn yn wir, sylwch y gellir rhannu'r ffyrdd o roi newid yn ddau grŵp: y rhai nad ydynt yn defnyddio unrhyw ddarn o'r math cyntaf, a'r rhai sydd yn gwneud hynny. Felly, mae cyfanswm nifer y ffyrdd o roi newid am ryw swm yn hafal i nifer y ffyrdd o roi newid am y swm heb ddefnyddio unrhyw ddarn o'r math cyntaf, ynghyd â nifer y ffyrdd o roi newid gan dybio ein bod yn defnyddio'r math cyntaf o ddarn arian. Ond mae'r ail nifer yn hafal i nifer y ffyrdd o roi newid am y swm sy'n weddill ar ôl defnyddio un darn o'r math cyntaf.
Felly, gallwn leihau'r broblem o newid swm penodol yn ddychweliadol i'r broblem o newid symiau llai gan ddefnyddio llai o fathau o ddarnau arian. Ystyriwch y rheol leihau hon yn ofalus, ac argyhoeddwch eich hun y gallwn ei defnyddio i ddisgrifio algorithm os pennwn yr achosion dirywiedig canlynol:33
- Os yw
yn union 0, dylem gyfrif hynny fel 1 ffordd o roi newid. - Os yw
yn llai na 0, dylem gyfrif hynny fel 0 ffordd o roi newid. - Os yw
yn 0, dylem gyfrif hynny fel 0 ffordd o roi newid.
Gallwn drosi'r disgrifiad hwn yn hawdd yn weithdrefn ddychweliadol:
(define (count-change amount)
(cc amount 5))
(define (cc amount kinds-of-coins)
(cond ((= amount 0) 1)
((or (< amount 0)
(= kinds-of-coins 0))
0)
(else
(+ (cc amount (- kinds-of-coins 1))
(cc (- amount (first-denomination
kinds-of-coins))
kinds-of-coins)))))
(define (first-denomination kinds-of-coins)
(cond ((= kinds-of-coins 1) 1)
((= kinds-of-coins 2) 5)
((= kinds-of-coins 3) 10)
((= kinds-of-coins 4) 25)
((= kinds-of-coins 5) 50)))(Mae'r weithdrefn first-denomination yn cymryd nifer y mathau o ddarnau arian sydd ar gael yn fewnbwn ac yn dychwelyd gwerth y math cyntaf. Yma rydym yn meddwl am y darnau arian fel rhai sydd wedi'u trefnu o'r mwyaf i'r lleiaf, ond byddai unrhyw drefn yr un mor addas.) Gallwn bellach ateb ein cwestiwn gwreiddiol am newid doler:
(count-change 100)
292
Mae Count-change yn cynhyrchu proses ddychweliadol goeden sydd ag ailadroddiadau diangen tebyg i'r rhai yn ein gweithrediad cyntaf o fib. (Bydd yn cymryd cryn dipyn o amser i gyfrifiannu'r 292 hwnnw.) Ar y llaw arall, nid yw'n amlwg sut i ddylunio algorithm gwell ar gyfer cyfrifiannu'r canlyniad, a gadawn y broblem hon fel her. Mae'r sylw y gall proses ddychweliadol goeden fod yn aneffeithlon iawn ond yn aml yn hawdd ei phennu a'i deall wedi arwain pobl i awgrymu y gellid cael y gorau o'r ddau fyd drwy ddylunio “crynhoydd clyfar” a allai drawsffurfio gweithdrefnau dychweliadol coeden yn weithdrefnau mwy effeithlon sy'n cyfrifiannu'r un canlyniad.34
Ymarfer 1.11: Diffinnir ffwythiant
gan y rheol fod os yw , a os yw . Ysgrifennwch weithdrefn sy'n cyfrifiannu drwy broses ddychweliadol. Ysgrifennwch weithdrefn sy'n cyfrifiannu drwy broses iteru.
Ymarfer 1.12: Gelwir y patrwm rhifau canlynol yn driongl Pascal.
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 . . .Mae'r rhifau ar ymyl y triongl i gyd yn 1, ac mae pob rhif y tu mewn i'r triongl yn swm y ddau rif uwch ei ben.35 Ysgrifennwch weithdrefn sy'n cyfrifiannu elfennau triongl Pascal drwy broses ddychweliadol.
Ymarfer 1.13: Profwch mai
yw'r cyfanrif agosaf at , lle mae . Awgrym: gosodwch . Defnyddiwch anwythiad a diffiniad rhifau Fibonacci (gweler 1.2.2) i brofi bod .
1.2.3Trefnau Twf
Mae'r enghreifftiau blaenorol yn dangos y gall prosesau amrywio'n sylweddol yn y cyfraddau y maent yn defnyddio adnoddau cyfrifiadurol. Un ffordd gyfleus o ddisgrifio'r gwahaniaeth hwn yw defnyddio'r syniad o drefn twf i gael mesur bras o'r adnoddau sydd eu hangen ar broses wrth i'r mewnbynnau fynd yn fwy.
Gadewch i
Dywedwn fod gan
Er enghraifft, gyda'r broses ddychweliadol linol ar gyfer cyfrifiannu ffactorial a ddisgrifiwyd yn 1.2.1, mae nifer y camau'n tyfu'n gyfrannol â'r mewnbwn
Disgrifiad bras yn unig o ymddygiad proses a ddarperir gan drefnau twf. Er enghraifft, mae gan broses sydd angen
Ymarfer 1.14: Lluniwch y goeden sy'n dangos y broses a gynhyrchir gan weithdrefn
count-change1.2.2 wrth roi newid am 11 sent. Beth yw trefnau twf y gofod a nifer y camau a ddefnyddir gan y broses hon wrth i'r swm sydd i'w newid gynyddu?
Ymarfer 1.15: Gellir cyfrifiannu sin ongl (a bennir mewn radianau) drwy ddefnyddio'r brasamcan
os yw yn ddigon bach, a'r unfathiant trigonometrig i leihau maint arg sin. (At ddibenion yr ymarfer hwn, ystyrir ongl yn “ddigon bach” os nad yw ei maint yn fwy na 0.1 radian.) Mae'r gweithdrefnau canlynol yn ymgorffori'r syniadau hyn: (define (cube x) (* x x x)) (define (p x) (- (* 3 x) (* 4 (cube x)))) (define (sine angle) (if (not (> (abs angle) 0.1)) angle (p (sine (/ angle 3.0)))))
- Sawl gwaith y cymhwysir y weithdrefn
pwrth werthuso(sine 12.15)?- Beth yw trefn twf y gofod a nifer y camau (fel ffwythiant o
) a ddefnyddir gan y broses a gynhyrchir gan y weithdrefn sinewrth werthuso(sine a)?
1.2.4Esbonyddu
Ystyriwch y broblem o gyfrifiannu pŵer rhif penodol. Hoffem weithdrefn sy'n cymryd bôn
(define (expt b n)
(if (= n 0)
1
(* b (expt b (- n 1)))))Proses ddychweliadol linol yw hon, sy'n gofyn am
(define (expt b n)
(expt-iter b n 1))
(define (expt-iter b counter product)
(if (= counter 0)
product
(expt-iter b
(- counter 1)
(* b product))))Mae angen
Gallwn gyfrifiannu pwerau mewn llai o gamau drwy sgwario'n olynol. Er enghraifft, yn hytrach na chyfrifiannu
(define (fast-expt b n)
(cond ((= n 0)
1)
((even? n)
(square (fast-expt b (/ n 2))))
(else
(* b (fast-expt b (- n 1))))))lle diffinnir y traethiad i brofi a yw cyfanrif yn eilrif yn nhermau'r weithdrefn gyntefig remainder gan
(define (even? n)
(= (remainder n 2) 0))Mae'r broses a gynhyrchir gan fast-expt yn tyfu'n logarithmig ag fast-expt. Felly mae maint yr esbonydd y gallwn ei gyfrifiannu yn dyblu (yn fras) gyda phob lluosiad newydd a ganiateir inni. Felly, mae nifer y lluosiadau sydd eu hangen ar gyfer esbonydd o
Daw'r gwahaniaeth rhwng twf fast-expt ar gyfer
Ymarfer 1.16: Dyluniwch weithdrefn sy'n cynhyrchu proses esbonyddu drwy iteru, sy'n defnyddio sgwario olynol a nifer logarithmig o gamau, fel
fast-expt. (Awgrym: gan ddefnyddio'r sylw fod, cadwch, ynghyd â'r esbonydd a'r bôn , newidyn cyflwr ychwanegol , a diffiniwch y trawsffurfiad cyflwr fel nad yw'r lluoswm yn newid o gyflwr i gyflwr. Ar ddechrau'r broses cymerir mai 1 yw , a rhoddir yr ateb gan werth ar ddiwedd y broses. Yn gyffredinol, mae'r dechneg o ddiffinio maint annewidiol sy'n aros yr un fath o gyflwr i gyflwr yn ffordd bwerus o feddwl am ddylunio algorithmau iteru.)
Ymarfer 1.17: Mae'r algorithmau esbonyddu yn yr adran hon yn seiliedig ar gyflawni esbonyddu drwy luosi dro ar ôl tro. Mewn ffordd debyg, gellir lluosi cyfanrifau drwy adio dro ar ôl tro. Mae'r weithdrefn luosi ganlynol (lle tybir mai dim ond adio, ac nid lluosi, y gall ein hiaith ei wneud) yn cyfateb i'r weithdrefn
expt:(define (* a b) (if (= b 0) 0 (+ a (* a (- b 1)))))Mae'r algorithm hwn yn cymryd nifer o gamau sy'n llinol ag
b. Nawr tybiwch ein bod yn cynnwys, ynghyd ag adio, y gweithrediadaudouble, sy'n dyblu cyfanrif, ahalve, sy'n rhannu cyfanrif (eilrif) â 2. Gan ddefnyddio'r rhain, dyluniwch weithdrefn luosi sy'n cyfateb ifast-exptac sy'n defnyddio nifer logarithmig o gamau.
Ymarfer 1.18: Gan ddefnyddio canlyniadau Ymarfer 1.16 ac Ymarfer 1.17, dyfeisiwch weithdrefn sy'n cynhyrchu proses iteru ar gyfer lluosi dau gyfanrif yn nhermau adio, dyblu, a haneru, ac sy'n defnyddio nifer logarithmig o gamau.40
Ymarfer 1.19: Mae algorithm clyfar ar gyfer cyfrifiannu rhifau Fibonacci mewn nifer logarithmig o gamau. Cofiwch drawsffurfiad y newidynnau cyflwr
a ym mhroses fib-iter1.2.2:a . Galwch y trawsffurfiad hwn yn , a sylwch fod cymhwyso dro ar ôl tro gwaith, gan ddechrau ag 1 a 0, yn cynhyrchu'r pâr a . Mewn geiriau eraill, cynhyrchir rhifau Fibonacci drwy gymhwyso , sef pŵer y trawsffurfiad , gan ddechrau â'r pâr (1, 0). Nawr ystyriwch yn achos arbennig ac mewn teulu o drawsffurfiadau , lle mae yn trawsffurfio'r pâr yn ôl a . Dangoswch, os cymhwyswn drawsffurfiad o'r fath ddwywaith, fod yr effaith yr un fath â defnyddio un trawsffurfiad o'r un ffurf, a chyfrifiannwch a yn nhermau a . Mae hyn yn rhoi ffordd benodol inni sgwario'r trawsffurfiadau hyn, ac felly gallwn gyfrifiannu drwy sgwario olynol, fel yn y weithdrefn fast-expt. Rhowch hyn i gyd at ei gilydd i gwblhau'r weithdrefn ganlynol, sy'n rhedeg mewn nifer logarithmig o gamau:41(define (fib n) (fib-iter 1 0 0 1 n)) (define (fib-iter a b p q count) (cond ((= count 0) b) ((even? count) (fib-iter a b ⟨??⟩ ;compute p' ⟨??⟩ ;compute q' (/ count 2))) (else (fib-iter (+ (* b q) (* a q) (* a p)) (+ (* b p) (* a q)) p q (- count 1)))))
1.2.5Rhannwyr Cyffredin Mwyaf
Diffinnir rhannwr cyffredin mwyaf (GCD) dau gyfanrif
Mae syniad yr algorithm yn seiliedig ar y sylw, os mai
GCD(a,b) = GCD(b,r)
i leihau'r broblem o gyfrifiannu GCD yn olynol i'r broblem o gyfrifiannu GCD parau llai a llai o gyfanrifau. Er enghraifft, mae
GCD(206,40) = GCD(40,6)
= GCD(6,4)
= GCD(4,2)
= GCD(2,0) = 2
yn lleihau GCD(206, 40) i GCD(2, 0), sef 2. Gellir dangos y bydd dechrau ag unrhyw ddau gyfanrif positif a lleihau dro ar ôl tro bob amser yn cynhyrchu, yn y pen draw, bâr lle mae'r ail rif yn 0. Yna'r rhif arall yn y pâr yw'r GCD. Gelwir y dull hwn o gyfrifiannu'r GCD yn Algorithm Euclid.42
Mae'n hawdd mynegi Algorithm Euclid fel gweithdrefn:
(define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b))))Mae hyn yn cynhyrchu proses iteru y mae nifer ei chamau'n tyfu fel logarithm y rhifau dan sylw.
Mae perthynas ddiddorol rhwng y ffaith fod gan nifer y camau sydd eu hangen ar Algorithm Euclid dwf logarithmig a rhifau Fibonacci:
Theorem Lamé: Os oes angen
o gamau ar Algorithm Euclid i gyfrifiannu GCD rhyw bâr, yna rhaid i'r rhif lleiaf yn y pâr fod yn fwy na neu'n hafal i rif Fibonacci rhif .43
Gallwn ddefnyddio'r theorem hon i gael amcangyfrif o drefn twf Algorithm Euclid. Gadewch i
Ymarfer 1.20: Mae'r broses a gynhyrchir gan weithdrefn, wrth gwrs, yn dibynnu ar y rheolau a ddefnyddir gan y dehonglydd. Er enghraifft, ystyriwch y weithdrefn iteru
gcda roddwyd uchod. Tybiwch ein bod yn dehongli'r weithdrefn hon drwy werthuso yn y drefn arferol, fel y trafodwyd yn 1.1.5. (Disgrifir rheol gwerthuso yn y drefn arferol ar gyferifyn Ymarfer 1.5.) Gan ddefnyddio'r dull amnewid (ar gyfer y drefn arferol), dangoswch y broses a gynhyrchir wrth werthuso(gcd 206 40)a nodwch y gweithrediadauremaindera gyflawnir mewn gwirionedd. Sawl gweithrediadremaindera gyflawnir mewn gwirionedd wrth werthuso(gcd 206 40)yn y drefn arferol? Ac wrth werthuso yn y drefn gymhwysol?
1.2.6Enghraifft: Profi a yw Rhif yn Gysefin
Mae'r adran hon yn disgrifio dau ddull ar gyfer gwirio a yw cyfanrif
Chwilio am rannwyr
Ers yr hen oesoedd, mae problemau ynghylch rhifau cysefin wedi swyno mathemategwyr, ac mae llawer o bobl wedi gweithio ar y broblem o bennu ffyrdd o brofi a yw rhifau'n gysefin. Un ffordd o brofi a yw rhif yn gysefin yw canfod rhannwyr y rhif. Mae'r rhaglen ganlynol yn canfod rhannwr cyfanrif lleiaf (mwy nag 1) rhif penodol
(define (smallest-divisor n)
(find-divisor n 2))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n)
n)
((divides? test-divisor n)
test-divisor)
(else (find-divisor
n
(+ test-divisor 1)))))
(define (divides? a b)
(= (remainder b a) 0))Gallwn brofi a yw rhif yn gysefin fel a ganlyn: mae
(define (prime? n)
(= n (smallest-divisor n)))Mae'r prawf terfynu ar gyfer find-divisor yn seiliedig ar y ffaith, os nad yw
Prawf Fermat
Mae'r prawf cysefinrwydd
Theorem Fach Fermat: Os yw
yn rhif cysefin ac os yw yn unrhyw gyfanrif positif sy'n llai nag , yna mae wedi'i godi i'r pŵer yn gyfath ag modwlo .
(Dywedir bod dau rif yn gyfath modwlo
Os nad yw
I weithredu prawf Fermat, mae angen gweithdrefn sy'n cyfrifiannu pŵer rhif modwlo rhif arall:
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(remainder
(square (expmod base (/ exp 2) m))
m))
(else
(remainder
(* base (expmod base (- exp 1) m))
m))))Mae hyn yn debyg iawn i weithdrefn fast-expt 1.2.4. Mae'n defnyddio sgwario olynol, fel bod nifer y camau'n tyfu'n logarithmig gyda'r esbonydd.46
Cyflawnir prawf Fermat drwy ddewis ar hap rif random, y tybiwn ei bod wedi'i chynnwys yn Scheme fel gweithdrefn gyntefig. Mae Random yn dychwelyd cyfanrif annegyddol sy'n llai na'i mewnbwn cyfanrif. Felly, i gael rhif ar hap rhwng 1 ac random â mewnbwn o
(define (fermat-test n)
(define (try-it a)
(= (expmod a n n) a))
(try-it (+ 1 (random (- n 1)))))Mae'r weithdrefn ganlynol yn rhedeg y prawf nifer penodol o weithiau, fel y pennir gan baramedr. Mae ei gwerth yn wir os yw'r prawf yn llwyddo bob tro, ac yn anwir fel arall.
(define (fast-prime? n times)
(cond ((= times 0) true)
((fermat-test n)
(fast-prime? n (- times 1)))
(else false)))Dulliau tebygolrwyddol
Mae prawf Fermat yn wahanol ei natur i'r rhan fwyaf o algorithmau cyfarwydd, lle cyfrifiannir ateb y gwarentir ei fod yn gywir. Yma, dim ond yn debygol o fod yn gywir y mae'r ateb a geir. Yn fwy manwl, os bydd
Yn anffodus, nid yw'r haeriad hwn yn hollol gywir. Mae rhifau sy'n twyllo prawf Fermat yn bodoli: rhifau
Mae amrywiadau ar brawf Fermat na ellir eu twyllo. Yn y profion hyn, fel yn null Fermat, profir cysefinrwydd cyfanrif
Mae bodolaeth profion y gellir profi bod eu tebygolrwydd o wall yn mynd mor fach ag y mynnir wedi ennyn diddordeb mewn algorithmau o'r math hwn, a elwir bellach yn algorithmau tebygolrwydd. Mae llawer iawn o waith ymchwil yn y maes hwn, a chymhwyswyd algorithmau tebygolrwydd yn llwyddiannus i lawer o feysydd.48
Ymarfer 1.21: Defnyddiwch y weithdrefn
smallest-divisori ganfod rhannydd lleiaf pob un o'r rhifau canlynol: 199, 1999, 19999.
Ymarfer 1.22: Mae'r rhan fwyaf o weithrediadau Lisp yn cynnwys gweithdrefn gyntefig o'r enw
runtimesy'n dychwelyd cyfanrif sy'n pennu faint o amser y mae'r system wedi bod yn rhedeg (wedi'i fesur, er enghraifft, mewn microeiliadau). Pan elwir y weithdrefntimed-prime-testganlynol â chyfanrif, mae'n argraffu ac yn gwirio a yw yn gysefin. Os yw yn gysefin, mae'r weithdrefn yn argraffu tair seren ac yna faint o amser a ddefnyddiwyd i gyflawni'r prawf. (define (timed-prime-test n) (newline) (display n) (start-prime-test n (runtime)))(define (start-prime-test n start-time) (if (prime? n) (report-prime (- (runtime) start-time))))(define (report-prime elapsed-time) (display " *** ") (display elapsed-time))Gan ddefnyddio'r weithdrefn hon, ysgrifennwch weithdrefn
search-for-primessy'n gwirio cysefinrwydd odrifau olynol mewn amrediad penodol. Defnyddiwch eich gweithdrefn i ganfod y tri rhif cysefin lleiaf sy'n fwy na 1000; yn fwy na 10,000; yn fwy na 100,000; ac yn fwy na 1,000,000. Nodwch yr amser sydd ei angen i brofi pob rhif cysefin. Gan fod gan yr algorithm profi drefn twf, dylech ddisgwyl i brofi rhifau cysefin o gwmpas 10,000 gymryd tua gwaith cymaint o amser â phrofi rhifau cysefin o gwmpas 1000. A yw eich data amseru yn cadarnhau hyn? Pa mor dda y mae'r data ar gyfer 100,000 a 1,000,000 yn cefnogi'r rhagfynegiad ? A yw eich canlyniad yn gyson â'r syniad fod rhaglenni ar eich peiriant yn rhedeg mewn amser sy'n gyfrannol â nifer y camau sydd eu hangen ar y cyfrifiad?
Ymarfer 1.23: Mae'r weithdrefn
smallest-divisora ddangoswyd ar ddechrau'r adran hon yn gwneud llawer o brofi diangen: ar ôl gwirio a yw'r rhif yn rhanadwy â 2, nid oes diben gwirio a yw'n rhanadwy ag unrhyw eilrifau mwy. Mae hyn yn awgrymu na ddylai'r gwerthoedd a ddefnyddir ar gyfertest-divisorfod yn 2, 3, 4, 5, 6, …, ond yn hytrach yn 2, 3, 5, 7, 9, …. I weithredu'r newid hwn, diffiniwch weithdrefnnextsy'n dychwelyd 3 os yw ei mewnbwn yn hafal i 2, ac sydd fel arall yn dychwelyd ei mewnbwn ynghyd â 2. Addaswch y weithdrefnsmallest-divisori ddefnyddio(next test-divisor)yn lle(+ test-divisor 1). Gydatimed-prime-testyn cynnwys y fersiwn addasedig hon osmallest-divisor, rhedwch y prawf ar gyfer pob un o'r 12 rhif cysefin a ganfuwyd yn Ymarfer 1.22. Gan fod yr addasiad hwn yn haneru nifer y camau profi, dylech ddisgwyl iddo redeg tua dwywaith mor gyflym. A gadarnheir y disgwyliad hwn? Os na, beth yw'r gymhareb a welir rhwng cyflymderau'r ddau algorithm, a sut rydych yn egluro'r ffaith ei bod yn wahanol i 2?
Ymarfer 1.24: Addaswch weithdrefn
timed-prime-testYmarfer 1.22 i ddefnyddiofast-prime?(dull Fermat), a phrofwch bob un o'r 12 rhif cysefin a ganfuwyd gennych yn yr ymarfer hwnnw. Gan fod gan brawf Fermat dwf, sut y byddech yn disgwyl i'r amser i brofi rhifau cysefin ger 1,000,000 gymharu â'r amser sydd ei angen i brofi rhifau cysefin ger 1000? A yw eich data'n cadarnhau hyn? A allwch egluro unrhyw anghysondeb a ganfyddwch?
Ymarfer 1.25: Mae Alyssa P. Hacker yn cwyno inni wneud llawer o waith ychwanegol wrth ysgrifennu
expmod. Wedi'r cyfan, meddai, gan ein bod eisoes yn gwybod sut i gyfrifiannu pwerau, gallem fod wedi ysgrifennu'n syml(define (expmod base exp m) (remainder (fast-expt base exp) m))A yw hi'n gywir? A fyddai'r weithdrefn hon yr un mor addas ar gyfer ein prawf cysefinrwydd cyflym? Eglurwch.
Ymarfer 1.26: Mae Louis Reasoner yn cael cryn anhawster wrth wneud Ymarfer 1.24. Mae ei brawf
fast-prime?i'w weld yn rhedeg yn arafach na'i brawfprime?. Mae Louis yn galw ei ffrind Eva Lu Ator draw i helpu. Wrth archwilio cod Louis, maent yn canfod ei fod wedi ailysgrifennu'r weithdrefnexpmodi ddefnyddio lluosiad penodol, yn hytrach na galwsquare:(define (expmod base exp m) (cond ((= exp 0) 1) ((even? exp) (remainder (* (expmod base (/ exp 2) m) (expmod base (/ exp 2) m)) m)) (else (remainder (* base (expmod base (- exp 1) m)) m))))“Nid wyf yn gweld pa wahaniaeth y gallai hynny ei wneud,” meddai Louis. “Rwyf i'n gweld.” meddai Eva. “Drwy ysgrifennu'r weithdrefn fel yna, rwyt wedi trawsffurfio'r broses
yn broses .” Eglurwch.
Ymarfer 1.27: Dangoswch fod y rhifau Carmichael a restrir yn Nhroednodyn 47 yn twyllo prawf Fermat mewn gwirionedd. Hynny yw, ysgrifennwch weithdrefn sy'n cymryd cyfanrif
ac yn profi a yw yn gyfath ag modwlo ar gyfer pob , a rhowch gynnig ar eich gweithdrefn gyda'r rhifau Carmichael a roddwyd.
Ymarfer 1.28: Gelwir un amrywiad ar brawf Fermat na ellir ei dwyllo yn brawf Miller–Rabin (Miller 1976; Rabin 1980). Mae hwn yn dechrau â ffurf amgen ar Theorem Fach Fermat, sy'n datgan, os yw
yn rhif cysefin ac os yw yn unrhyw gyfanrif positif sy'n llai nag , yna bod wedi'i godi i'r pŵer yn gyfath ag 1 modwlo . I brofi cysefinrwydd rhif drwy brawf Miller–Rabin, dewiswn rif ar hap a chodwn i'r pŵer modwlo gan ddefnyddio'r weithdrefn expmod. Fodd bynnag, pryd bynnag y cyflawnwn y cam sgwario ynexpmod, gwiriwn a ydym wedi darganfod “gwreiddyn sgwâr o 1 nad yw’n ddibwys modwlo,” hynny yw, rhif nad yw'n hafal i 1 nac y mae ei sgwâr yn hafal i 1 modwlo . Gellir profi, os oes gwreiddyn sgwâr o 1 nad yw’n ddibwys o'r fath yn bodoli, nad yw yn gysefin. Gellir hefyd brofi, os yw yn odrif nad yw'n gysefin, yna, ar gyfer o leiaf hanner y rhifau , y bydd cyfrifiannu fel hyn yn datgelu gwreiddyn sgwâr o 1 nad yw’n ddibwys modwlo . (Dyma pam na ellir twyllo prawf Miller–Rabin.) Addaswch y weithdrefn expmodi roi signal os yw'n darganfod gwreiddyn sgwâr o 1 nad yw’n ddibwys, a defnyddiwch hyn i weithredu prawf Miller–Rabin gyda gweithdrefn sy'n cyfateb ifermat-test. Gwiriwch eich gweithdrefn drwy brofi amrywiol rifau y gwyddys eu bod yn gysefin neu'n anghysefin. Awgrym: un ffordd gyfleus o wneud iexpmodroi signal yw gwneud iddi ddychwelyd 0.
Troednodiadau
29 Mewn rhaglen go iawn, mae'n debyg y byddem yn defnyddio'r strwythur blociau a gyflwynwyd yn yr adran ddiwethaf i guddio'r diffiniad o fact-iter:
(define (factorial n)
(define (iter product counter)
(if (> counter n)
product
(iter (* counter product)
(+ counter 1))))
(iter 1 1))Osgowyd gwneud hyn yma er mwyn lleihau nifer y pethau i feddwl amdanynt ar yr un pryd.
30 Pan drafodwn weithredu gweithdrefnau ar beiriannau cofrestri ym Mhennod 5, byddwn yn gweld y gellir gwireddu unrhyw broses iteru “mewn caledwedd” fel peiriant sydd â set sefydlog o gofrestri a dim cof ategol. Mewn cyferbyniad, mae gwireddu proses ddychweliadol yn gofyn am beiriant sy'n defnyddio strwythur data ategol a elwir yn bentwr.
31 Mae dychweliad cynffon wedi bod yn hysbys ers tro fel tric optimeiddio crynhoydd. Darparwyd sail semantig gydlynol i ddychweliad cynffon gan Carl Hewitt (1977), a'i heglurodd yn nhermau'r model cyfrifiannu “trosglwyddo negeseuon” y byddwn yn ei drafod ym Mhennod 3. Wedi'u hysbrydoli gan hyn, adeiladodd Gerald Jay Sussman a Guy Lewis Steele Jr. (gweler Steele a Sussman 1975) ddehonglydd ar gyfer Scheme a oedd yn ddychweliadol yn y gynffon. Dangosodd Steele yn ddiweddarach sut mae dychweliad cynffon yn ganlyniad i'r ffordd naturiol o grynhoi galwadau gweithdrefn (Steele 1977). Mae safon IEEE ar gyfer Scheme yn mynnu bod gweithrediadau Scheme yn ddychweliadol yn y gynffon.
32 Awgrymwyd enghraifft o hyn yn 1.1.3. Mae'r dehonglydd ei hun yn gwerthuso mynegiadau gan ddefnyddio proses ddychweliadol goeden.
33 Er enghraifft, gweithiwch yn fanwl drwy sut mae'r rheol leihau yn berthnasol i'r broblem o roi newid am 10 sent gan ddefnyddio darnau un sent a phum sent.
34 Un dull o ymdopi â chyfrifiadau diangen yw trefnu pethau fel ein bod yn adeiladu tabl o werthoedd yn awtomatig wrth eu cyfrifiannu. Bob tro y gofynnir inni gymhwyso'r weithdrefn i ryw arg, edrychwn yn gyntaf i weld a yw'r gwerth eisoes wedi'i storio yn y tabl; os ydyw, osgowyd cyflawni'r cyfrifiad diangen. Gellir gweithredu'r strategaeth hon, a elwir yn dablio neu'n gofio canlyniadau, mewn ffordd uniongyrchol. Weithiau gellir defnyddio tablio i drawsffurfio prosesau sy'n gofyn am nifer esbonyddol o gamau (megis count-change) yn brosesau y mae eu gofynion gofod ac amser yn tyfu'n llinol gyda'r mewnbwn. Gweler Ymarfer 3.27.
35 Gelwir elfennau triongl Pascal yn gyfernodau binomaidd, oherwydd bod rhes
36 Mae'r gosodiadau hyn yn cuddio llawer iawn o orsymleiddio. Er enghraifft, os cyfrifwn gamau proses fel “gweithrediadau peiriant,” rydym yn tybio bod nifer y gweithrediadau peiriant sydd eu hangen i gyflawni, dyweder, lluosiad yn annibynnol ar faint y rhifau sydd i'w lluosi; mae hynny'n anwir os yw'r rhifau'n ddigon mawr. Mae sylwadau tebyg yn berthnasol i'r amcangyfrifon o ofod. Fel dylunio a disgrifio proses, gellir dadansoddi proses ar amrywiol lefelau haniaethu.
37 Yn fwy manwl, mae nifer y lluosiadau sydd eu hangen yn hafal i 1 yn llai na logarithm bôn 2 o
38 Efallai eich bod yn pendroni pam y byddai gan unrhyw un ddiddordeb mewn codi rhifau i'r 1000fed pŵer. Gweler 1.2.6.
39 Mae'r algorithm iteru hwn yn hynafol. Mae'n ymddangos yn y Chandah-sutra gan Áchárya Pingala, a ysgrifennwyd cyn 200 C.C. Gweler Knuth 1981, adran 4.6.3, am drafodaeth a dadansoddiad llawn o hwn a dulliau esbonyddu eraill.
40 Mae'r algorithm hwn, a elwir weithiau yn “ddull y gwerinwr Rwsiaidd” o luosi, yn hynafol. Ceir enghreifftiau o'i ddefnydd ym Mhapyrws Rhind, un o'r ddwy ddogfen fathemategol hynaf sydd mewn bodolaeth, a ysgrifennwyd tua 1700 C.C. (ac a gopïwyd o ddogfen hŷn fyth) gan ysgrifennydd Eifftaidd o'r enw A’h-mose.
41 Awgrymwyd yr ymarfer hwn inni gan Joe Stoy, yn seiliedig ar enghraifft yn Kaldewaij 1990.
42 Gelwir Algorithm Euclid felly oherwydd ei fod yn ymddangos yn Elements Euclid (Llyfr 7, tua 300 C.C.). Yn ôl Knuth (1973), gellir ei ystyried yr algorithm hynaf nad yw’n ddibwys y gwyddys amdano. Mae dull lluosi'r hen Eifftiaid (Ymarfer 1.18) yn sicr yn hŷn, ond, fel yr eglura Knuth, algorithm Euclid yw'r hynaf y gwyddys iddo gael ei gyflwyno fel algorithm cyffredinol, yn hytrach na set o enghreifftiau eglurhaol.
43 Profwyd y theorem hon ym 1845 gan Gabriel Lamé, mathemategydd a pheiriannydd Ffrengig a adnabyddir yn bennaf am ei gyfraniadau at ffiseg fathemategol. I brofi'r theorem, ystyriwn barau
44 Os yw
45 Ystyrir Pierre de Fermat (1601-1665) yn sylfaenydd damcaniaeth rhifau fodern. Cafodd lawer o ganlyniadau pwysig mewn damcaniaeth rhifau, ond fel arfer dim ond y canlyniadau a gyhoeddai, heb ddarparu ei brofion. Datganwyd Theorem Fach Fermat mewn llythyr a ysgrifennodd ym 1640. Rhoddwyd y prawf cyhoeddedig cyntaf gan Euler ym 1736 (a darganfuwyd prawf cynharach, union yr un fath, yn llawysgrifau anghyhoeddedig Leibniz). Ysgrifennwyd yr enwocaf o ganlyniadau Fermat—a elwir yn Theorem Olaf Fermat—ar frys ym 1637 yn ei gopi o'r llyfr Arithmetic (gan y mathemategydd Groegaidd Diophantus o'r drydedd ganrif) gyda'r sylw “Rwyf wedi darganfod prawf gwirioneddol ryfeddol, ond mae'r ymyl hon yn rhy fach i'w gynnwys.” Daeth canfod prawf o Theorem Olaf Fermat yn un o'r heriau enwocaf mewn damcaniaeth rhifau. Rhoddwyd ateb cyflawn o'r diwedd ym 1995 gan Andrew Wiles o Brifysgol Princeton.
46 Mae'r camau lleihau yn yr achosion lle mae'r esbonydd
47 Gelwir rhifau sy'n twyllo prawf Fermat yn rhifau Carmichael, ac ychydig a wyddys amdanynt heblaw eu bod yn hynod brin. Ceir 255 o rifau Carmichael o dan 100,000,000. Y rhai lleiaf yw 561, 1105, 1729, 2465, 2821, a 6601. Wrth brofi cysefinrwydd rhifau mawr iawn a ddewisir ar hap, mae'r tebygolrwydd o ddod ar draws gwerth sy'n twyllo prawf Fermat yn llai na'r tebygolrwydd y bydd ymbelydredd cosmig yn peri i'r cyfrifiadur wneud gwall wrth gyflawni algorithm “cywir.” Mae ystyried algorithm yn annigonol am y rheswm cyntaf ond nid am yr ail yn dangos y gwahaniaeth rhwng mathemateg a pheirianneg.
48 Un o gymwysiadau mwyaf trawiadol profi cysefinrwydd yn debygolrwyddol fu ym maes cryptograffeg. Er ei bod ar hyn o bryd yn anymarferol yn gyfrifiadurol i ffactorio rhif mympwyol o 200 digid, gellir gwirio cysefinrwydd rhif o'r fath mewn ychydig eiliadau gyda phrawf Fermat. Mae'r ffaith hon yn sail i dechneg ar gyfer adeiladu “codau na ellir eu torri” a awgrymwyd gan Rivest et al. (1977). Mae'r algorithm RSA a ddeilliodd o hynny wedi dod yn dechneg a ddefnyddir yn eang i wella diogelwch cyfathrebu electronig. Oherwydd hyn a datblygiadau cysylltiedig, mae astudio rhifau cysefin, a ystyrid ar un adeg yn esiampl berffaith o bwnc mewn mathemateg “bur” i'w astudio er ei fwyn ei hun yn unig, bellach yn troi allan i fod â chymwysiadau ymarferol pwysig mewn cryptograffeg, trosglwyddo arian yn electronig, ac adalw gwybodaeth.