1  x := 1
2  while n > 0 do
3      if n mod 2 = 1 then
4          n := n − 1
5          x := x · a
6      n := n div 2
7      a := a · a
AN = xan

Teh­tä­vä:
Bi­nää­ri­po­tens­si

Ly­hyt Math­Check-oh­je (uu­teen vä­li­leh­teen)

Tur­val­li­nen asioin­ti verk­ko­pan­kis­sa edel­lyt­tää tie­don sa­laus­ta. Yk­si las­ku­toi­mi­tus, jo­ta ny­ky­ai­kai­sis­sa sa­laus­me­ne­tel­mis­sä tar­vi­taan, on an mod M, mis­sä kaik­ki kol­me lu­kua ovat iso­ja (esi­mer­kik­si 300-nu­me­roi­sia). Sen suo­rit­ta­mi­nen las­ke­mal­la n − 1 eli noin 10300 ker­to­las­kua ja mo­du­lo-ope­raa­tio­ta vei­si ai­kaa mel­ko mon­ta maail­man­kaik­keu­den ikää. Täs­sä teh­tä­väs­sä tu­tus­tu­taan kei­noon suo­rit­taa las­ku tar­peek­si no­peas­ti. Yk­sin­ker­tai­suu­den vuok­si mo­du­lon ot­ta­mi­nen jä­te­tään näyt­tä­mät­tä, mut­ta se on help­po li­sä­tä al­go­rit­min jo­ka kier­rok­sel­le.

Ker­ra­taan aluk­si pa­ri asiaa.

Ko­ko­nais­lu­ku n on pa­ri­ton, jos ja vain jos mod = . Päin­vas­tai­ses­sa ta­pauk­ses­sa n on pa­ril­li­nen.
tai

Jos n on pa­ril­li­nen, niin n div 2 = , ja jos n on pa­ri­ton, niin n div 2 = (il­mai­se vas­tauk­set il­man sym­bo­lei­ta div ja mod). Vih­jeLi­sää tai vä­hen­nä en­nen ja­ko­las­kua sel­lai­nen lu­ku, et­tä ja­ko tu­lee me­ne­mään ta­san mut­ta alas­päin pyö­ris­tet­ty tu­los ei muu­tu.
tai

Bi­nää­ri­po­tens­si näyt­tää täl­tä. Har­maal­la kir­joi­tet­tua ri­viä 4 ei oi­keas­ti tar­vi­ta, mut­ta sen li­sää­mi­nen hel­pot­taa al­go­rit­mis­ta päät­te­le­mis­tä. Sen li­sää­mi­nen ei muu­ta si­tä ar­voa, mi­kä ri­vil­lä 6 si­joi­te­taan n:ään, kos­ka ri­vin 3 eh­don vuok­si se suo­ri­te­taan vain kun n on pa­ri­ton, ja sil­loin n div 2 = Tä­män näim­me edel­lä. (n − 1) / 2 = Kun ja­ko me­nee ta­san, / tuot­taa sa­man tu­lok­sen kuin div.(n − 1) div 2. (Mik­si yh­tä­suu­ruu­det pä­te­vät?)  Mi­tään muu­ta­kaan vai­ku­tus­ta sen pois jät­tä­mi­sel­lä ei ole jat­koon, kos­ka ri­vien 4 ja 6 vä­lis­sä n:n ar­voa ei käy­te­tä mi­hin­kään.

1  x := 1
2  while n > 0 do
3      if n mod 2 = 1 then
4          n := n − 1
5          x := x · a
6      n := n div 2
7      a := a · a

Al­go­rit­mi on ko­pioi­tu oi­keal­le alas, jot­ta se oli­si kä­sil­lä myös kun yl­lä ole­va ko­pio on ka­don­nut ruu­dun ylä­reu­nan ylä­puo­lel­le.

Mer­ki­tään muut­tu­jien n ja a ar­vo­ja al­go­rit­min alus­sa sym­bo­leil­la N ja A. Al­go­rit­min teh­tä­vä­nä on siis las­kea AN, mis­sä N on luon­nol­li­nen lu­ku. To­dis­tam­me, et­tä al­go­rit­mi las­kee oi­kean lop­pu­tu­lok­sen ja sel­vi­täm­me, kuin­ka no­peas­ti se toi­mii.

Käy­täm­me sil­mu­koi­den to­dis­ta­mi­ses­sa hy­vin yleis­tä päät­te­ly­ta­paa, jos­sa on vii­si vai­het­ta:

  1. Va­li­taan jo­kin väi­te, jol­la päät­te­ly saa­daan on­nis­tu­maan. Si­tä kut­su­taan in­va­rian­tik­si. Bi­nää­ri­po­tens­sin in­va­riant­ti on yh­tä­lö AN = xan.
  2. Osoi­te­taan, et­tä in­va­riant­ti pä­tee sil­mu­kan alus­sa eli kun ri­vil­le 2 tul­laan en­sim­mäi­sen ker­ran.
  3. Osoi­te­taan, et­tä sil­mu­kan var­ta­lon suo­ri­tus ei voi saa­da in­va­riant­tia pois voi­mas­ta (pait­si ken­ties ti­la­päi­ses­ti kes­ken var­ta­lon suo­ri­tuk­sen). Siis osoi­te­taan, et­tä jos AN = xan pä­tee ri­vin 3 alus­sa ja sil­mu­kan eh­to n > 0 pä­tee, niin AN = x­an pä­tee ri­vin 7 lo­pus­sa. Täs­tä, edel­li­ses­tä ja sii­tä, et­tä ri­vil­lä 2 ei muu­te­ta min­kään muut­tu­jan ar­voa seu­raa, et­tä AN = x­an on voi­mas­sa ai­na ri­vin 2 alus­sa.
  4. Osoi­te­taan, et­tä sil­mu­kan suo­ri­tus lop­puu jos­kus.
  5. Osoi­te­taan, et­tä jos in­va­riant­ti pä­tee ja sil­mu­kan eh­to ei pä­de, niin sil­mu­kan lop­pu­tu­lok­sel­ta ha­lut­tu asia pä­tee, eli et­tä al­go­rit­mi on las­ke­nut oi­kean lop­pu­tu­lok­sen.

Kos­ka po­tens­si­las­ku ei ole mää­ri­tel­ty esi­mer­kik­si sil­loin kun kan­ta­lu­ku on nol­la ja eks­po­nent­ti ne­ga­tii­vi­nen, mei­dän on pi­det­tä­vä tark­kaan huol­ta, et­tä väit­teis­säm­me eks­po­nen­tit ovat ai­na ei-ne­ga­tii­vi­sia.

Me­ne­tel­män koh­ta 2 on täl­lä ker­taa mel­ko help­po. Kun ri­vil­le 2 tul­laan en­sim­mäi­sen ker­ran x = , a = ja n = , jo­ten xan = . Il­mai­se vas­tauk­set sym­bo­lien N ja A avul­la.
tai

Koh­dan 3 hoi­ta­mi­sek­si ole­tam­me, et­tä in­va­riant­ti ja sil­mu­kan eh­to pä­te­vät ri­vin 3 alus­sa, ja to­dis­tam­me, et­tä in­va­riant­ti pä­tee ri­vin 7 lo­pus­sa. Tä­män teh­däk­sem­me alam­me käy­dä sil­muk­kaa lä­pi.

Ri­vin 3 alus­sa tie­de­tään var­mas­ti, et­tä n, kos­ka n on ko­ko­nais­lu­ku ja sil­mu­kan eh­to lu­paa n > 0. Tä­män tie­don an­sios­ta ri­vin 4 lo­pus­sa (jos sin­ne jou­du­taan) n.
tai

Kos­ka n muut­tuu ri­vil­lä 4, ri­vin 5 alus­sa in­va­riant­ti ei pä­de sel­lai­se­naan, vaan muu­te­tus­sa muo­dos­sa:
AN = .
tai

Vas­ta­tes­sa­si edel­li­seen koh­taan huo­ma­sit eh­kä, et­tä tä­män muo­don voi pää­tel­lä suo­raan, mut­ta voi ol­la vai­keaa miet­tiä pi­tää­kö si­joi­tuk­sen n := n − 1 vai­ku­tus ot­taa huo­mioon li­sää­mäl­lä vai vä­hen­tä­mäl­lä in­va­rian­tis­sa n:ään yk­kö­nen. Jos si­joi­tus­lau­seen oi­keal­la puo­lel­la on jo­tain mo­ni­mut­kai­sem­paa, vai­keus kas­vaa. Sik­si opet­te­lem­me ki­kan. En­nen si­joi­tus­lau­set­ta pä­te­vä kaa­va kan­nat­taa muut­taa muo­toon, jos­sa si­joi­tus­lau­seen oi­kea puo­li esiin­tyy sel­lai­se­naan. Tyy­pil­li­ses­ti se esiin­tyy yh­den ker­ran, mut­ta muut­kin mää­rät ovat mah­dol­li­sia. Si­joi­tuk­sen koh­tee­na ole­va muut­tu­ja ei saa esiin­tyä muual­la kuin näis­sä oi­keis­sa puo­lis­sa. Si­joi­tus­lau­seen jäl­kei­nen ti­lan­ne saa­daan kor­vaa­mal­la ne muut­tu­jal­la, jo­hon si­joi­te­taan.

Si­joi­tus­lau­seen n := 2n + 1 ja kaa­van 4n = k ta­pauk­ses­sa se tar­koit­taa, et­tä en­sin kaa­va muu­te­taan muo­toon 2(2n + 1) − 2 = k. Tä­mä on loo­gi­ses­ti yh­tä­pi­tä­vä al­ku­pe­räi­sen kaa­van kans­sa, kos­ka 2(2n + 1) − 2 = 4n. Sit­ten 2n + 1 kor­va­taan n:llä, jol­loin saa­daan 2n − 2 = k. Tu­lok­sek­si saa­tiin, et­tä jos en­nen si­joi­tus­ta n := 2n + 1 pä­ti 4n = k, niin si­joi­tuk­sen jäl­keen pä­tee 2n − 2 = k.

Ri­vin 4 ta­pauk­ses­sa tä­mä tar­koit­taa, et­tä AN = xan muu­te­taan muo­toon, jos­sa n esiin­tyy vain osa­kaa­vois­sa muo­toa n − 1. Töi­hin! Olen li­sän­nyt ko­vat su­lut osa­kaa­van n − 1 ym­pä­ril­le ha­vain­nol­li­suu­den vuok­si, mut­ta oi­keas­ti se ei ole tar­peen jos kaa­van si­säl­tö säi­lyy eh­jä­nä il­man­kin. Eh­kä huo­maat, et­tä a voi­daan ot­taa te­ki­jäk­si, mut­ta älä vie­lä tee niin.
AN = .
Kun osa­kaa­van n − 1 pai­kal­le lai­te­taan si­joi­tuk­sen koh­tee­na ole­va muut­tu­ja n, saa­daan se min­kä toi­vot­ta­vas­ti sait edel­lä:
AN = .
tai

Ri­vin 5 kä­sit­te­lyä var­ten muu­tam­me tä­män muo­toon, jos­sa x · a on te­ki­jä­nä ja x ei esiin­ny muu­ten:
AN = .
Ri­vin 5 mu­kai­ses­ti x · a kor­va­taan x:llä, jo­ten ri­vin 5 lo­pus­sa AN = .
tai

Seu­raa­vak­si tar­kas­te­lem­me ti­lan­net­ta ri­vin 6 alus­sa. Vaik­ka ri­vin 4 mu­ka­na- tai pois­sa­olo ei muu­ta­kaan al­go­rit­min tu­los­ta, al­la ole­viin väit­tei­siin se vai­kut­taa. Ole­tam­me, et­tä ri­vi 4 on mu­ka­na. Näim­me, et­tä jos men­tiin then-haa­ran kaut­ta, niin in­va­riant­ti oli vä­lil­lä pois voi­mas­ta mut­ta as­tui uu­del­leen voi­maan then-haa­ran lo­pus­sa. Jos then-haa­ra ohi­tet­tiin, min­kään muut­tu­jan ar­vo ei muut­tu­nut, jo­ten in­va­riant­ti pä­tee kos­ka se pä­ti ri­vin 3 alus­sa. Muut­tu­jan n ar­vos­ta ri­vin 6 alus­sa tie­de­tään seu­raa­vaa (va­lit­se oi­keat):
n > 0
n ≥ 0
n ≥ −1
Jos men­tiin then-haa­ran kaut­ta, niin n on pa­ri­ton.
Jos men­tiin then-haa­ran kaut­ta, niin n on pa­ril­li­nen.
Jos ei men­ty then-haa­ran kaut­ta, niin n on pa­ri­ton.
Jos ei men­ty then-haa­ran kaut­ta, niin n on pa­ril­li­nen.
n on pa­ri­ton.
n on pa­ril­li­nen.
tai

Ri­vin 6 kä­sit­te­le­mi­sek­si muun­nam­me ri­vin 6 alun ti­lan­teen sel­lai­sek­si, et­tä n esiin­tyy sii­nä vain muo­dos­sa n div 2. Kos­ka n on pa­ril­li­nen, voim­me so­vel­taa aiem­min hok­saa­maam­me yh­tä­suu­ruut­ta se­kä si­tä, et­tä n = 2 n / 2.
AN =
tai

Edel­lä ole­van pe­rus­teel­la ti­lan­ne on seu­raa­va ri­vin 7 alus­sa:
AN = = So­vel­la so­pi­vaa po­tens­si­las­kun la­kia. Nii­tä löy­dät vaik­ka tääl­tä..
tai

Tie­ten­kin a2 = a · a. Niin­pä ri­vin 7 lo­pus­sa AN = , ku­ten pi­tää­kin.
tai

Olem­me to­dis­ta­neet, et­tä jos in­va­riant­ti on voi­mas­sa sil­mu­kan var­ta­lon alus­sa, se on voi­mas­sa myös sil­mu­kan var­ta­lon lo­pus­sa. Siis koh­ta 3 on val­mis.

Koh­das­sa 4 pi­tää to­dis­taa, et­tä al­go­rit­mi lo­pet­taa jos­kus. Täs­sä ei ole muu­ta vai­keaa kuin et­tä huo­li­mat­to­muus­vir­hei­tä voi sat­tua se­kä oh­jel­moi­jil­le et­tä oh­jel­mis­ta miet­ti­jöil­le. Ote­taan sik­si toi­sen­lai­nen ai­het­ta si­vua­va ky­sy­mys. Py­säh­tyi­si­kö tä­mä al­go­rit­mi, jos sil­muk­ka­eh­to­na oli­si­kin n ≥ 0?
kyl­lä
ei
ky­sy­mys on huo­nos­ti mää­ri­tel­ty
Sil­muk­ka­eh­to­na on kui­ten­kin n > 0, jo­ten al­go­rit­mi py­säh­tyy, kos­ka kun n > 0 pä­tee n div 2 ≤ n / 2 < n, jo­ten n pie­ne­nee sil­mu­kan jo­kai­sel­la kier­rok­sel­la kun­nes se on 0. tai

Kun al­go­rit­mi on lo­pet­ta­nut, sil­mu­kan eh­dos­ta ja sii­tä, et­tä n on luon­nol­li­nen lu­ku, voi­daan pää­tel­lä, et­tä n = , jo­ten xan = (il­mai­se pien­ten kir­jain­ten avul­la). Toi­saal­ta in­va­rian­tin vuok­si xan = (il­mai­se suur­ten kir­jain­ten avul­la).
tai

Kos­ka kum­pi­kin kah­teen edel­li­seen laa­tik­koon kir­joit­ta­mis­ta­si lau­sek­keis­ta on yh­tä­suu­ri lau­sek­keen xan kans­sa, ne ovat yh­tä­suu­ret myös kes­ke­nään, jo­ten al­go­rit­min tuot­ta­ma vas­taus on oi­kein. Koh­ta 5 ja si­tä myö­ten ko­ko to­dis­tus on val­mis.

Tä­mä al­go­rit­mi mo­ti­voi­tiin lu­pauk­sel­la no­peu­des­ta, jo­ten nyt on ai­ka kat­soa kuin­ka no­pea se on. Al­go­rit­min käyt­tä­mis­sä pe­rus­ope­raa­tiois­sa ei ole mi­tään ker­to­las­kua mo­ni­mut­kai­sem­paa. Kol­me­sa­taa­nu­me­rois­ten lu­ku­jen ker­to­las­ku ei ole yh­tä pie­ni hom­ma kuin kym­men­nu­me­rois­ten, jo­ten tar­kas­sa las­kel­mas­sa kiin­ni­tet­täi­siin huo­mio­ta pe­rus­ope­raa­tioi­den hin­taan. Nyt em­me kui­ten­kaan ole niin tark­ko­ja, vaan kat­som­me ai­noas­taan sil­mu­kan kier­ros­ten mää­rää.

Kuin­ka mon­ta kier­ros­ta al­go­rit­mi suo­rit­taa? Jot­ta si­nun ei tar­vit­si­si miet­tiä ja kir­joit­taa hie­man han­ka­laa tark­kaa kaa­vaa, Math­Check tar­kas­taa vain po­si­tii­vi­sil­la n:n ar­voil­la ja hy­väk­syy kai­ken mi­kä poik­keaa vä­hem­män kuin 1 tar­kas­ta ar­vos­ta.
tai

Ai ha­luat yrit­tää tark­kaa­kin kaa­vaa? Ei oli­si tar­peen, mut­ta tot­ta kai se so­pii, jos in­toa riit­tää!
tai

Ai ha­luat vain näh­dä tar­kan lau­sek­keen ja sen se­li­tyk­sen? Se­kin so­pii. Saat sa­maan hin­taan kak­si vaih­to­eh­tois­ta lau­se­ket­ta.
tai

Kol­me­sa­taa­nu­me­roi­sil­la lu­vuil­la tu­lee siis hiu­kan al­le tu­hat kier­ros­ta. Tie­to­ko­neel­le se on koh­tuul­li­nen työ­mää­rä sii­tä­kin huo­li­mat­ta, et­tä pe­rus­las­ku­toi­mi­tuk­set teh­dään 300-nu­me­roi­sil­la lu­vuil­la.