Langkau ke kandungan utama

Mengukur kos pengiraan

Seterusnya, kita akan bincangkan rangka kerja matematik untuk mengukur kos pengiraan, yang difokuskan khusus kepada keperluan kursus ini. Analisis algoritma dan kerumitan pengiraan adalah bidang kajian tersendiri, dan mempunyai banyak lagi perkara untuk diperkatakan mengenai konsep-konsep ini.

Sebagai titik permulaan, perhatikan rajah berikut dari pelajaran sebelumnya, yang mewakili abstraksi peringkat tinggi bagi sebuah pengiraan.

Ilustrasi pengiraan standard.

Pengiraan itu sendiri boleh dimodelkan atau dihuraikan dengan pelbagai cara, seperti program komputer yang ditulis dalam Python, mesin Turing, Circuit Boolean, atau Circuit kuantum. Fokus kita akan tertumpu pada Circuit (kedua-dua Boolean dan kuantum).

Pengekodan dan panjang input

Mari mulakan dengan input dan output bagi masalah pengiraan, yang kita andaikan sebagai rentetan binari. Simbol-simbol lain boleh digunakan, tetapi kita akan memudahkan perkara dengan membataskan perhatian pada input dan output berupa rentetan binari. Melalui rentetan binari, kita boleh mengekod pelbagai objek menarik yang berkaitan dengan masalah yang ingin kita selesaikan, seperti nombor, vektor, matriks, dan graf, serta senarai objek-objek ini dan yang lain.

Sebagai contoh, untuk mengekod integer bukan negatif, kita boleh menggunakan notasi binari. Jadual berikut menyenaraikan pengekodan binari bagi sembilan integer bukan negatif pertama, bersama panjang (bermaksud jumlah bilangan bit) bagi setiap pengekodan.

NomborPengekodan binariPanjang
001
111
2102
3112
41003
51013
61103
71113
810004

Kita boleh dengan mudah memperluaskan pengekodan ini untuk menangani integer positif dan negatif dengan menambahkan bit tanda pada perwakilan jika kita mahu. Kadang-kadang juga mudah untuk membenarkan perwakilan binari bagi integer bukan negatif mempunyai sifar pendahulu, yang tidak mengubah nilai yang dikodkan tetapi membolehkan perwakilan memenuhi rentetan atau perkataan bersaiz tetap.

Menggunakan notasi binari untuk mewakili integer bukan negatif adalah perkara biasa dan cekap, tetapi jika kita mahu, kita boleh memilih cara lain untuk mewakili integer bukan negatif menggunakan rentetan binari, seperti yang dicadangkan dalam jadual berikut. Butiran khusus bagi alternatif-alternatif ini tidak penting dalam perbincangan ini — tujuannya hanyalah untuk menjelaskan bahawa kita memang mempunyai pilihan untuk pengekodan yang kita gunakan.

NomborPengekodan unariPengekodan leksikografi
0ε\varepsilonε\varepsilon
100
2001
300000
4000001
50000010
600000011
70000000000
800000000001

(Dalam jadual ini, simbol ε\varepsilon mewakili rentetan kosong, yang tidak mempunyai sebarang simbol dan panjangnya sama dengan sifar. Secara semula jadi, untuk mengelakkan kekeliruan yang jelas, kita menggunakan simbol khas seperti ε\varepsilon untuk mewakili rentetan kosong dan bukannya benar-benar tidak menulis apa-apa.)

Jenis input lain, seperti vektor dan matriks, atau objek yang lebih rumit seperti huraian molekul, juga boleh dikodkan sebagai rentetan binari. Sama seperti yang kita lakukan untuk integer bukan negatif, pelbagai skim pengekodan yang berbeza boleh dipilih atau dicipta. Untuk sebarang skim yang kita reka untuk mengekod input bagi masalah tertentu, kita mentafsirkan panjang suatu rentetan input sebagai mewakili saiz contoh masalah yang sedang diselesaikan.

Sebagai contoh, bilangan bit yang diperlukan untuk menyatakan integer bukan negatif NN dalam notasi binari, yang kadang-kadang dilambangkan lg(N),\operatorname{lg}(N), diberikan oleh formula berikut.

lg(N)={1N=01+log2(N)N1\operatorname{lg}(N) = \begin{cases} 1 & N = 0\\ 1 + \lfloor \log_2 (N) \rfloor & N \geq 1 \end{cases}

Dengan mengandaikan kita menggunakan notasi binari untuk mengekod input kepada masalah pemfaktoran integer, panjang input untuk nombor NN ialah lg(N).\operatorname{lg}(N). Perlu diperhatikan, khususnya, bahawa panjang (atau saiz) input NN bukanlah NN itu sendiri; apabila NN besar, kita tidak memerlukan bilangan bit sebanyak itu untuk menyatakan NN dalam notasi binari.

Dari sudut pandang formal yang ketat, setiap kali kita mempertimbangkan masalah atau tugas pengiraan, hendaklah difahami bahawa skim khusus telah dipilih untuk mengekod objek-objek yang diberikan sebagai input atau dihasilkan sebagai output. Ini membolehkan pengiraan yang menyelesaikan masalah menarik dilihat secara abstrak sebagai transformasi daripada input rentetan binari kepada output rentetan binari.

Butiran tentang cara objek dikodkan sebagai rentetan binari semestinya penting untuk pengiraan-pengiraan ini pada suatu tahap. Namun biasanya, kita tidak terlalu risau tentang butiran-butiran ini apabila menganalisis kos pengiraan, supaya kita dapat mengelakkan diri daripada terperangkap dalam butiran yang kurang penting. Pemikiran asasnya ialah kita menjangkakan kos pengiraan untuk menukar antara skim pengekodan yang "munasabah" adalah tidak signifikan berbanding dengan kos menyelesaikan masalah sebenar. Dalam situasi di mana ini tidak berlaku, butiran tersebut boleh (dan sepatutnya) dijelaskan.

Sebagai contoh, pengiraan yang sangat mudah menukarkan antara perwakilan binari integer bukan negatif dan pengekodan leksikografinya (yang tidak kita jelaskan secara terperinci, tetapi boleh disimpulkan daripada jadual di atas). Atas sebab ini, kos pengiraan pemfaktoran integer tidak akan berbeza secara signifikan jika kita memutuskan untuk beralih daripada menggunakan salah satu pengekodan ini kepada yang lain untuk input N.N. Sebaliknya, mengekod integer bukan negatif dalam notasi unari mengakibatkan peningkatan eksponen dalam jumlah simbol yang diperlukan, dan kita tidak akan menganggapnya sebagai skim pengekodan yang "munasabah" atas sebab ini.

Operasi asas

Sekarang mari kita pertimbangkan pengiraan itu sendiri, yang diwakili oleh segi empat biru dalam rajah di atas. Cara kita mengukur kos pengiraan adalah dengan mengira bilangan operasi asas yang diperlukan oleh setiap pengiraan. Secara intuitif, operasi asas adalah operasi yang melibatkan bilangan kecil dan tetap bit atau Qubit, yang boleh dilakukan dengan cepat dan mudah — seperti mengira AND bagi dua bit. Sebaliknya, menjalankan fungsi factorint tidak boleh dianggap secara munasabah sebagai operasi asas.

Secara formal, terdapat pilihan berbeza untuk apa yang merupakan operasi asas bergantung pada model pengiraan yang digunakan. Fokus kita akan tertumpu pada model Circuit, khususnya Circuit kuantum dan Boolean.

Set Gate sejagat

Untuk model pengiraan berasaskan Circuit, adalah lazim bahawa setiap Gate dilihat sebagai operasi asas. Ini membawa kepada persoalan tentang Gate yang mana yang kita benarkan dalam Circuit kita. Fokus buat masa ini pada Circuit kuantum, kita telah melihat beberapa Gate setakat ini dalam siri ini, termasuk Gate X,X, Y,Y, Z,Z, H,H, S,S, dan T,T, Gate swap, versi terkawal Gate (termasuk controlled-NOT, Toffoli, dan Fredkin), serta Gate yang mewakili pengukuran asas standard. Dalam konteks permainan CHSH kita juga melihat beberapa Gate putaran tambahan.

Kita juga membincangkan Gate pertanyaan dalam konteks model pertanyaan, dan kita juga melihat bahawa sebarang operasi unitari U,U, yang bertindak ke atas sebarang bilangan Qubit, boleh dilihat sebagai Gate jika kita mahu — tetapi kita akan mengabaikan kedua-dua pilihan ini untuk tujuan perbincangan ini. Kita tidak akan bekerja dalam model pertanyaan (walaupun pelaksanaan Gate pertanyaan menggunakan operasi asas dibincangkan kemudian dalam pelajaran), dan melihat Gate unitari arbitrari, yang berpotensi bertindak ke atas jutaan Qubit, sebagai operasi asas tidak membawa kepada konsep kos pengiraan yang bermakna atau realistik.

Dengan tetap menggunakan Gate kuantum yang beroperasi pada bilangan Qubit yang kecil, satu pendekatan untuk memutuskan mana yang dianggap asas adalah dengan mencari kriteria yang tepat — tetapi ini bukan pendekatan standard atau yang akan kita ambil. Sebaliknya, kita hanya membuat pilihan.

Berikut adalah satu pilihan standard, yang akan kita gunakan sebagai set Gate lalai untuk Circuit kuantum:

  • Gate unitari satu-Qubit daripada senarai ini: X,X, Y,Y, Z,Z, H,H, S,S, S,S^{\dagger}, T,T, dan TT^{\dagger}
  • Gate Controlled-NOT
  • Pengukuran asas standard satu-Qubit

Alternatif umum adalah untuk memandang Gate Toffoli, Hadamard, dan SS sebagai asas, di samping pengukuran asas standard. Kadang-kadang semua Gate satu-Qubit dilihat sebagai asas, walaupun ini memang membawa kepada model yang tidak realistik kuatnya apabila ketepatan pelaksanaan Gate tidak diambil kira dengan betul.

Gate unitari dalam koleksi lalai kita membentuk apa yang dipanggil set Gate sejagat. Ini bermaksud kita boleh menganggarkan sebarang operasi unitari ke atas sebarang bilangan Qubit sehingga sebarang darjah ketepatan yang kita inginkan, menggunakan Circuit yang terdiri daripada Gate-Gate ini sahaja. Untuk lebih jelas, definisi keuniversalan tidak meletakkan sebarang keperluan pada kos penghampiran sedemikian, bermaksud bilangan Gate daripada set kita yang kita perlukan. Memang, hujah yang agak mudah berdasarkan konsep matematik ukuran mendedahkan bahawa kebanyakan operasi unitari mesti mempunyai kos yang sangat tinggi. Membuktikan keuniversalan set Gate kuantum bukan perkara mudah dan tidak akan diliputi dalam kursus ini.

Untuk Circuit Boolean, kita akan menggunakan Gate AND, OR, NOT, dan FANOUT sebagai yang mewakili operasi asas. Sebenarnya kita tidak memerlukan kedua-dua Gate AND dan Gate OR — kita boleh menggunakan hukum De Morgan untuk menukar daripada salah satu kepada yang lain dengan meletakkan Gate NOT pada semua tiga wayar input/output — tetapi bagaimanapun adalah lazim dan mudah untuk membenarkan kedua-dua Gate AND dan OR. Gate AND, OR, NOT, dan FANOUT membentuk set sejagat untuk pengiraan deterministik, bermaksud bahawa sebarang fungsi daripada sebarang bilangan tetap bit input kepada sebarang bilangan tetap bit output boleh dilaksanakan dengan Gate-Gate ini.

Prinsip pengukuran tertangguh

Gate pengukuran asas standard boleh muncul dalam Circuit kuantum, tetapi kadang-kadang mudah untuk menangguhkannya hingga ke penghujung. Ini membolehkan kita melihat pengiraan kuantum sebagai terdiri daripada bahagian unitari (mewakili pengiraan itu sendiri), diikuti oleh fasa pembacaan mudah di mana Qubit diukur dan hasilnya dikeluarkan. Ini sentiasa boleh dilakukan, dengan syarat kita sanggup menambah Qubit tambahan untuk setiap pengukuran asas standard. Dalam rajah berikut, Circuit di sebelah kanan menggambarkan bagaimana ini boleh dilakukan untuk Gate di sebelah kiri.

Menangguhkan pengukuran

Secara khususnya, bit klasik dalam Circuit di sebelah kiri digantikan oleh Qubit di sebelah kanan (dimulakan ke keadaan 0\vert 0\rangle), dan pengukuran asas standard digantikan oleh Gate controlled-NOT, diikuti oleh pengukuran asas standard pada Qubit bawah. Intinya ialah pengukuran asas standard dalam Circuit sebelah kanan boleh ditolak ke penghujung Circuit. Jika bit klasik dalam Circuit di sebelah kiri kemudiannya digunakan sebagai bit kawalan, kita boleh menggunakan Qubit bawah dalam Circuit di sebelah kanan sebagai kawalan, dan kesan keseluruhannya akan sama. (Kita mengandaikan bahawa bit klasik dalam Circuit di sebelah kiri tidak ditimpa selepas pengukuran berlaku oleh pengukuran lain — tetapi jika berlaku, kita sentiasa boleh menggunakan bit klasik baru dan bukannya menimpa yang telah digunakan untuk pengukuran sebelumnya.)

Saiz dan kedalaman Circuit

Saiz Circuit

Jumlah bilangan Gate dalam Circuit dirujuk sebagai saiz Circuit tersebut. Oleh itu, dengan mengandaikan bahawa Gate dalam Circuit kita mewakili operasi asas, saiz Circuit mewakili bilangan operasi asas yang diperlukan — atau, dalam erti kata lain, kos pengiraan nya. Kita tulis size(C)\operatorname{size}(C) untuk merujuk kepada saiz Circuit CC yang diberikan.

Sebagai contoh, pertimbangkan Circuit Boolean berikut untuk mengira XOR bagi dua bit.

Circuit Boolean untuk XOR

Saiz Circuit ini ialah 7 kerana terdapat 7 Gate secara keseluruhannya. (Operasi Fanout tidak selalu dikira sebagai Gate, tetapi bagi tujuan pelajaran ini kita akan mengiranya sebagai Gate.)

Masa, kos, dan kedalaman Circuit

Masa adalah sumber yang sangat penting, atau kekangan yang membatasi, untuk pengiraan. Contoh-contoh di atas, seperti tugas memfaktorkan RSA1024, mengukuhkan pandangan ini. Fungsi factorint tidak gagal memfaktorkan RSA1024 sebenarnya, cuma kita tidak mempunyai masa yang cukup untuk membiarkannya selesai.

Konsep kos pengiraan, sebagai bilangan operasi asas yang diperlukan untuk melaksanakan pengiraan, bertujuan menjadi proksi abstrak untuk masa yang diperlukan untuk melaksanakan pengiraan. Setiap operasi asas memerlukan sejumlah masa untuk dilaksanakan, dan semakin banyak operasi asas yang diperlukan oleh pengiraan, semakin lama masa yang diperlukan, sekurang-kurangnya secara umum. Demi kesederhanaan, kita akan terus membuat kaitan antara kos pengiraan dengan masa yang diperlukan untuk menjalankan algoritma.

Tetapi perhatikan bahawa saiz Circuit tidak semestinya berkoresponden secara langsung dengan berapa lama masa yang diperlukan untuk dijalankan. Dalam Circuit Boolean kita untuk mengira XOR bagi dua bit, misalnya, kedua-dua Gate FANOUT boleh dilakukan serentak, begitu juga kedua-dua Gate NOT, serta kedua-dua Gate AND. Cara lain untuk mengukur kecekapan Circuit, yang mengambil kira kemungkinan pemprosesan selari ini, ialah melalui kedalaman nya. Ini adalah bilangan minimum lapisan Gate yang diperlukan dalam Circuit, di mana Gate dalam setiap lapisan beroperasi pada wayar yang berbeza. Secara setara, kedalaman Circuit ialah bilangan maksimum Gate yang ditemui pada sebarang laluan dari wayar input ke wayar output. Untuk Circuit di atas, misalnya, kedalamannya ialah 4.

Kedalaman Circuit adalah satu cara untuk memformalkan masa larian bagi pengiraan selari. Ini adalah topik lanjutan, dan terdapat pembinaan Circuit yang sangat canggih yang diketahui untuk meminimumkan kedalaman yang diperlukan bagi pengiraan tertentu. Terdapat juga beberapa soalan menarik yang masih belum terjawab berkenaan kedalaman Circuit. (Sebagai contoh, banyak yang masih tidak diketahui tentang kedalaman Circuit yang diperlukan untuk mengira GCD.) Kita tidak akan banyak lagi membicarakan tentang kedalaman Circuit dalam siri ini, selain daripada memasukkan beberapa fakta menarik mengenai kedalaman Circuit sepanjang perjalanan, tetapi hendaklah diakui dengan jelas bahawa pemprosesan selari adalah sumber potensi kelebihan pengiraan.

Menugaskan kos berbeza kepada Gate yang berbeza

Satu nota akhir berkenaan saiz Circuit dan kos pengiraan ialah adalah mungkin untuk menugaskan kos berbeza kepada Gate, dan bukannya memandang setiap Gate menyumbang sama rata kepada jumlah kos.

Sebagai contoh, seperti yang telah disebutkan, Gate FANOUT sering dianggap percuma untuk Circuit Boolean — bermaksud kita boleh memilih Gate FANOUT mempunyai kos sifar. Sebagai contoh lain, apabila kita bekerja dalam model pertanyaan dan mengira bilangan pertanyaan yang dibuat oleh Circuit kepada fungsi input (dalam bentuk kotak hitam), kita secara efektifnya menugaskan kos satu unit kepada Gate pertanyaan dan kos sifar kepada Gate lain, seperti Gate Hadamard. Contoh terakhir ialah kita kadang-kadang menugaskan kos berbeza kepada Gate bergantung pada betapa sukarnya untuk dilaksanakan, yang boleh berbeza-beza bergantung pada perkakasan yang dipertimbangkan.

Walaupun semua pilihan ini munasabah dalam konteks yang berbeza, untuk pelajaran ini kita akan memudahkan dan berpegang pada saiz Circuit sebagai perwakilan kos pengiraan.

Kos sebagai fungsi panjang input

Kita terutamanya berminat dengan bagaimana kos pengiraan berskala apabila input semakin besar dan besar. Ini membawa kita untuk mewakili kos algoritma sebagai fungsi panjang input.

Keluarga Circuit

Input kepada masalah pengiraan tertentu boleh berbeza panjang, berpotensi menjadi sewenang-wenangnya besar. Setiap Circuit, sebaliknya, mempunyai bilangan Gate dan wayar yang tetap. Atas sebab ini, apabila kita memikirkan algoritma dalam istilah Circuit, kita umumnya memerlukan keluarga Circuit yang tidak terhingga besar untuk mewakili algoritma. Dengan keluarga Circuit, kita maksudkan urutan Circuit yang berkembang dalam saiz, membolehkan input yang semakin besar diakomodasi.

Sebagai contoh, bayangkan kita mempunyai algoritma klasik untuk pemfaktoran integer, seperti yang digunakan oleh factorint. Seperti semua algoritma klasik, algoritma ini boleh dilaksanakan menggunakan Circuit Boolean — tetapi untuk melakukannya kita memerlukan Circuit yang berasingan untuk setiap panjang input yang mungkin. Jika kita melihat Circuit yang terhasil untuk panjang input yang berbeza, kita akan melihat bahawa saiznya secara semula jadi berkembang seiring dengan pertumbuhan panjang input — mencerminkan hakikat bahawa memfaktorkan integer 4-bit adalah jauh lebih mudah dan memerlukan operasi asas yang jauh lebih sedikit berbanding memfaktorkan integer 1024-bit, misalnya.

Ini membawa kita untuk mewakili kos pengiraan bagi algoritma dengan fungsi t,t, yang ditakrifkan supaya t(n)t(n) adalah bilangan Gate dalam Circuit yang melaksanakan algoritma untuk input nn bit. Dalam istilah yang lebih formal, algoritma dalam model Circuit Boolean dihuraikan oleh urutan Circuit {C1,C2,C3,},\{C_1, C_2, C_3,\ldots\}, di mana CnC_n menyelesaikan masalah yang kita bicarakan untuk input nn-bit (atau, secara lebih umum, untuk input yang saiznya diparameterkan dalam beberapa cara oleh nn), dan fungsi tt yang mewakili kos algoritma ini ditakrifkan sebagai

t(n)=size(Cn).t(n) = \operatorname{size}(C_n).

Untuk Circuit kuantum keadaannya adalah serupa, di mana Circuit yang semakin besar diperlukan untuk mengakomodasi rentetan input yang semakin panjang.

Contoh: penambahan integer

Untuk menjelaskan lebih lanjut, mari luangkan masa untuk mempertimbangkan masalah penambahan integer, yang jauh lebih mudah berbanding pemfaktoran integer atau bahkan mengira GCD.

Penambahan integer

Input: integer NN dan MM
Output: N+MN+M

Bagaimana kita boleh mereka bentuk Circuit Boolean untuk menyelesaikan masalah ini?

Untuk memudahkan perkara, mari hadkan perhatian kita kepada kes di mana NN dan MM kedua-duanya adalah integer bukan negatif yang diwakili oleh rentetan nn-bit menggunakan notasi binari. Kita akan membenarkan sebarang bilangan sifar pendahulu dalam pengekodan ini, supaya

0N,M2n1.0\leq N,M\leq 2^n - 1.

Output akan menjadi rentetan binari (n+1)(n+1)-bit yang mewakili jumlah, yang merupakan bilangan bit maksimum yang kita perlukan untuk menyatakan hasilnya.

Kita mulakan dengan algoritma — algoritma standard untuk penambahan perwakilan binari — yang merupakan analogi asas 22 kepada cara penambahan diajar di sekolah rendah di seluruh dunia. Algoritma ini boleh dilaksanakan dengan Circuit Boolean seperti berikut.

Bermula daripada bit paling tidak signifikan, kita boleh mengira XOR mereka untuk menentukan bit paling tidak signifikan bagi jumlah. Kemudian kita mengira bit bawa, yang merupakan AND bagi dua bit paling tidak signifikan daripada NN dan M.M. Kadang-kadang kedua-dua operasi ini bersama dikenali sebagai penambah separuh.

Penambah separuh

Menggunakan Circuit XOR yang telah kita lihat beberapa kali bersama dengan Gate AND dan dua Gate FANOUT, kita boleh membina penambah separuh dengan 10 Gate. Jika atas sebab tertentu kita berubah fikiran dan memutuskan untuk memasukkan Gate XOR dalam set operasi asas kita, kita akan memerlukan 1 Gate AND, 1 Gate XOR, dan 2 Gate FANOUT untuk membina penambah separuh.

Beralih kepada bit yang lebih signifikan, kita boleh menggunakan prosedur yang serupa, tetapi kali ini memasukkan bit bawa dari setiap kedudukan sebelumnya ke dalam pengiraan kita. Dengan mengalirkan dua penambah separuh dan mengambil OR daripada bit bawa yang dihasilkannya, kita boleh mencipta apa yang dikenali sebagai penambah penuh.

Penambah penuh

Ini memerlukan 21 Gate secara keseluruhannya: 2 Gate AND, 2 Gate XOR (masing-masing memerlukan 7 Gate untuk dilaksanakan), satu Gate OR, dan 4 Gate FANOUT.

Akhirnya, dengan mengalirkan penambah penuh, kita memperoleh Circuit Boolean untuk penambahan integer bukan negatif. Sebagai contoh, Circuit berikut mengira jumlah dua integer 4-bit.

Circuit untuk penambahan dua integer 4-bit

Secara umum, ini memerlukan

21(n1)+10=21n1121 (n-1) + 10 = 21 n - 11

Gate. Sekiranya kita memutuskan untuk memasukkan Gate XOR dalam set operasi asas kita, kita akan memerlukan 2n12n-1 Gate AND, 2n12n-1 Gate XOR, n1n-1 Gate OR, dan 4n24n-2 Gate FANOUT, untuk jumlah 9n59n-5 Gate. Jika tambahan pula kita memutuskan untuk tidak mengira Gate FANOUT, jumlahnya ialah 5n35n-3 Gate.

Notasi asimptotik

Di satu pihak, memang bagus untuk tahu dengan tepat berapa banyak get yang diperlukan untuk melaksanakan pelbagai pengiraan, seperti dalam contoh penambahan integer di atas. Butiran ini penting untuk benar-benar membina litar.

Di pihak lain, kalau kita buat analisis pada tahap butiran ini untuk semua pengiraan yang kita minati, termasuk yang jauh lebih rumit daripada penambahan, kita akan cepat tenggelam dalam butiran. Untuk memastikan perkara mudah diurus, dan untuk sengaja mengetepikan butiran yang kurang penting, kita biasanya menggunakan notasi Big-O semasa menganalisis algoritma. Melalui notasi ini kita boleh menyatakan tertib pertumbuhan fungsi.

Secara formal, jika kita ada dua fungsi g(n)g(n) dan h(n),h(n), kita tulis bahawa g(n)=O(h(n))g(n) = O(h(n)) jika wujud nombor nyata positif c>0c > 0 dan integer positif n0n_0 sedemikian hingga

g(n)ch(n)g(n) \leq c\cdot h(n)

untuk semua nn0.n \geq n_0. Biasanya h(n)h(n) dipilih sebagai ungkapan yang sesederhana mungkin, supaya notasi boleh digunakan untuk mendedahkan kelakuan had sesuatu fungsi dalam istilah mudah. Contohnya, 17n3257n2+65537=O(n3).17 n^3 - 257 n^2 + 65537 = O(n^3).

Notasi ini boleh dilanjutkan kepada fungsi yang mempunyai beberapa argumen dengan cara yang agak mudah. Sebagai contoh, jika kita ada dua fungsi g(n,m)g(n,m) dan h(n,m)h(n,m) yang ditakrifkan pada integer positif nn dan m,m, kita tulis bahawa g(n,m)=O(h(n,m))g(n,m) = O(h(n,m)) jika wujud nombor nyata positif c>0c > 0 dan integer positif k0k_0 sedemikian hingga

g(n,m)ch(n,m)g(n,m) \leq c\cdot h(n,m)

apabila n+mk0.n+m \geq k_0.

Mengaitkan notasi ini dengan contoh penambahan integer bukan negatif, kita simpulkan bahawa wujud keluarga litar Boolean {C1,C2,,},\{C_1, C_2,\ldots,\}, di mana CnC_n menjumlahkan dua integer bukan negatif nn-bit bersama, sedemikian hingga size(Cn)=O(n).\operatorname{size}(C_n) = O(n). Ini mendedahkan ciri paling penting tentang cara kos penambahan skala dengan saiz input: ia skala secara linear.

Perhatikan juga bahawa ia tidak bergantung pada butiran khusus sama ada kita menganggap get XOR mempunyai kos satu unit atau kos 7.7. Secara umum, menggunakan notasi Big-O membolehkan kita membuat pernyataan tentang kos pengiraan yang tidak sensitif terhadap butiran peringkat rendah sedemikian.

Lebih banyak contoh

Berikut adalah beberapa contoh lagi masalah daripada teori nombor pengiraan, bermula dengan pendaraban.

Pendaraban integer

Input: integer NN dan MM
Output: NMNM

Membuat litar Boolean untuk masalah ini lebih sukar daripada membuat litar untuk penambahan — tetapi dengan memikirkan algoritma pendaraban standard, kita boleh menghasilkan litar bersaiz O(n2)O(n^2) untuk masalah ini (dengan andaian NN dan MM kedua-duanya diwakili oleh perwakilan binari nn-bit). Secara lebih umum, jika NN mempunyai nn bit dan MM mempunyai mm bit, terdapat litar Boolean bersaiz O(nm)O(nm) untuk mendarabkan NN dan M.M.

Sebenarnya ada cara lain untuk membiak yang berskala lebih baik. Sebagai contoh, algoritma pendaraban Schönhage-Strassen boleh digunakan untuk membuat litar Boolean bagi mendarabkan dua integer nn-bit pada kos O(nlg(n)lg(lg(n))).O(n \operatorname{lg}(n) \operatorname{lg}(\operatorname{lg}(n))). Walau bagaimanapun, kerumitan kaedah ini menyebabkan banyak overhed, menjadikannya hanya praktikal untuk nombor yang mempunyai puluhan ribu bit.

Masalah asas lain ialah pembahagian, yang kita tafsirkan bermaksud mengira kedua-dua hasil bagi dan baki dengan diberi pembahagi dan dividen integer.

Pembahagian integer

Input: integer NN dan M0M\neq0
Output: integer qq dan rr yang memenuhi 0r<M0\leq r < |M| dan N=qM+rN = q M + r

Kos pembahagian integer adalah serupa dengan pendaraban: jika NN mempunyai nn bit dan MM mempunyai mm bit, terdapat litar Boolean bersaiz O(nm)O(nm) untuk menyelesaikan masalah ini. Dan seperti pendaraban, kaedah yang lebih unggul secara asimptotik adalah diketahui.

Kita kini boleh membandingkan algoritma yang diketahui untuk mengira GCD dengan algoritma untuk penambahan dan pendaraban. Algoritma Euclid untuk mengira GCD bagi nombor nn-bit NN dan nombor mm-bit MM memerlukan litar Boolean bersaiz O(nm),O(nm), serupa dengan algoritma standard untuk pendaraban dan pembahagian. Juga serupa dengan pendaraban dan pembahagian, terdapat algoritma GCD yang lebih pantas secara asimptotik — termasuk yang memerlukan O(n(lg(n))2lg(lg(n)))O(n(\operatorname{lg}(n))^2 \operatorname{lg}(\operatorname{lg}(n))) operasi asas untuk mengira GCD dua nombor nn-bit.

Satu pengiraan yang agak lebih mahal yang timbul dalam teori nombor ialah pempangkatan modular.

Pempangkatan modular integer

Input: integer N,N, K,K, dan MM dengan K0K\geq 0 dan M1M\geq 1
Output: NK(mod M)N^K \hspace{1mm} (\text{mod }M)

Dengan NK(mod M)N^K\hspace{1mm} (\text{mod }M) kita maksudkan baki apabila NKN^K dibahagikan dengan M,M, bermaksud integer unik rr yang memenuhi 0r<M0\leq r < M dan NK=qM+rN^K = q M + r untuk suatu integer q.q.

Jika NN mempunyai nn bit, MM mempunyai mm bit, dan KK mempunyai kk bit, masalah ini boleh diselesaikan oleh litar Boolean bersaiz O(km2+nm).O(k m^2 + nm). Ini sama sekali tidak jelas. Penyelesaiannya bukan dengan mengira NKN^K dahulu kemudian mengambil baki, yang akan memerlukan penggunaan bit yang terlampau banyak hanya untuk menyimpan nombor NK.N^K. Sebaliknya, kita boleh menggunakan algoritma kuasa (yang dikenali juga sebagai kaedah binari dan kuasa dua berulang), yang menggunakan perwakilan binari KK untuk melaksanakan seluruh pengiraan modulo M.M. Dengan andaian N,N, M,M, dan KK semuanya nombor nn-bit, kita memperoleh algoritma O(n3)O(n^3) — atau algoritma masa kubik. Dan sekali lagi, terdapat algoritma yang diketahui lebih rumit tetapi lebih pantas secara asimptotik.

Kos pemfaktoran integer

Berbeza dengan algoritma yang baru dibincangkan, algoritma yang diketahui untuk pemfaktoran integer jauh lebih mahal — seperti yang kita jangka daripada perbincangan awal pelajaran ini.

Satu pendekatan mudah untuk memfaktor ialah pembahagian percubaan, di mana algoritma mencari melalui senarai 2,,N2,\ldots,\sqrt{N} untuk mencari faktor perdana bagi nombor input N.N. Ini memerlukan O(2n/2)O(2^{n/2}) ulangan dalam kes terburuk apabila NN adalah nombor nn-bit. Setiap ulangan memerlukan pembahagian percubaan, bermakna O(n2)O(n^2) operasi asas untuk setiap ulangan (menggunakan algoritma standard untuk pembahagian integer). Kita akhirnya mendapat litar bersaiz O(n22n/2),O(n^2 2^{n/2}), yang bersifat eksponen dalam saiz input n.n.

Terdapat algoritma untuk pemfaktoran integer yang mempunyai skala lebih baik. Saringan medan nombor yang disebutkan sebelumnya, contohnya, yang merupakan algoritma yang menggunakan rawak, secara amnya dipercayai (tetapi tidak dibuktikan secara ketat) memerlukan

2O(n1/3(lg(n))2/3)2^{O(n^{1/3} (\operatorname{lg}(n))^{2/3})}

operasi asas untuk memfaktor integer nn-bit dengan kebarangkalian tinggi. Walaupun ia sangat ketara bahawa nn dipangkatkan kepada kuasa 1/31/3 dalam eksponen ungkapan ini, hakikat ia muncul dalam eksponen masih menjadi masalah yang menyebabkan skala yang buruk — dan menjelaskan sebahagiannya mengapa RSA1024 masih berada di luar domain kebolehterapannya.

Kos polinomial berbanding eksponen

Algoritma klasik untuk penambahan integer, pendaraban, pembahagian, dan pengiraan pembahagi sepunya terbesar membolehkan kita menyelesaikan masalah ini dalam sekelip mata untuk input dengan ribuan bit. Penambahan mempunyai kos linear manakala tiga masalah lain mempunyai kos kuadratik (atau kos subkuadratik menggunakan algoritma pantas secara asimptotik). Pempangkatan modular lebih mahal tetapi masih boleh dilakukan dengan agak cekap, dengan kos kubik (atau kos sub-kubik menggunakan algoritma pantas secara asimptotik).

Kesemua ini adalah contoh algoritma yang mempunyai kos polinomial, bermakna ia mempunyai kos O(nc)O(n^c) untuk sesetengah pilihan pemalar tetap c>0.c > 0. Sebagai anggaran kasar dan peringkat pertama, algoritma yang mempunyai kos polinomial secara abstrak dilihat sebagai mewakili algoritma yang cekap.

Sebaliknya, algoritma klasik yang diketahui untuk pemfaktoran integer mempunyai kos eksponen. Kadang-kadang kos saringan medan nombor digambarkan sebagai sub-eksponen kerana nn dipangkatkan kepada kuasa 1/31/3 dalam eksponen, tetapi dalam teori kerumitan adalah lebih biasa untuk menempah istilah ini bagi algoritma yang kosnya ialah

O(2nε)O\bigl(2^{n^{\varepsilon}}\bigr)

untuk setiap ε>0.\varepsilon > 0. Masalah yang dipanggil NP-lengkap adalah kelas masalah yang tidak diketahui (dan secara meluas diteorikan tidak) mempunyai algoritma kos polinomial. Satu formulasi berasaskan litar bagi hipotesis masa eksponen mengandaikan sesuatu yang lebih kuat lagi, iaitu tiada masalah NP-lengkap boleh mempunyai algoritma kos sub-eksponen.

Kaitan algoritma kos polinomial dengan algoritma cekap mestilah difahami sebagai satu abstraksi yang longgar. Tentu saja, jika kos sesuatu algoritma skala sebagai n1000n^{1000} atau n1000000n^{1000000} untuk input bersaiz n,n, maka agak berlebihan untuk menggambarkan algoritma itu sebagai cekap. Walau bagaimanapun, walaupun algoritma yang mempunyai kos yang skala sebagai n1000000n^{1000000} pasti melakukan sesuatu yang bijak untuk mengelakkan kos eksponen, yang secara umumnya kita jangkakan daripada algoritma yang berdasarkan "daya kasar" atau "carian menyeluruh." Malah penghalusan canggih saringan medan nombor, contohnya, gagal mengelakkan skala eksponen dalam kos ini. Algoritma kos polinomial, sebaliknya, berjaya mengambil kesempatan daripada struktur masalah dengan cara tertentu yang mengelakkan skala eksponen.

Dalam praktiknya, pengenalpastian algoritma kos polinomial untuk sesuatu masalah hanyalah langkah pertama menuju kecekapan sebenar. Melalui penghalusan algoritma, algoritma kos polinomial dengan eksponen besar kadang-kadang boleh diperbaiki secara dramatik, menurunkan kos kepada skala polinomial yang lebih "munasabah". Kadang-kadang perkara menjadi lebih mudah apabila ia diketahui boleh dilakukan — jadi pengenalpastian algoritma kos polinomial untuk sesuatu masalah juga boleh memberi kesan menginspirasi algoritma baru yang lebih cekap lagi.

Apabila kita mempertimbangkan kelebihan pengkomputeran kuantum berbanding pengkomputeran klasik, pandangan kita biasanya diarahkan pertama sekali kepada kelebihan eksponen, atau sekurang-kurangnya kelebihan super-polinomial — idealnya mencari algoritma kuantum kos polinomial untuk masalah yang tidak diketahui mempunyai algoritma klasik kos polinomial. Kelebihan teoritikal pada peringkat ini mempunyai peluang terbesar untuk membawa kepada kelebihan praktikal sebenar — tetapi mengenal pasti kelebihan sedemikian adalah cabaran yang amat sukar. Hanya beberapa contoh yang diketahui pada masa ini, tetapi pencarian terus berlanjutan.

Kelebihan polinomial (tetapi bukan super-polinomial) dalam kos pengiraan kuantum berbanding klasik juga menarik dan tidak sepatutnya diabaikan — tetapi memandangkan jurang semasa antara teknologi pengkomputeran kuantum dan klasik, ia memang kelihatan agak kurang menarik pada masa ini. Namun suatu hari nanti, ia mungkin menjadi penting. Algoritma Grover, contohnya, yang dibahas dalam pelajaran kemudian, menawarkan kelebihan kuadratik kuantum berbanding klasik untuk apa yang dipanggil carian tidak berstruktur, dan mempunyai potensi untuk aplikasi yang luas.

Kos tersembunyi pengiraan litar

Terdapat satu isu terakhir yang patut disebutkan, walaupun kita tidak akan membimbangkan diri kita tentangnya lagi dalam kursus ini. Terdapat kos pengiraan "tersembunyi" apabila kita bekerja dengan litar, dan ia berkaitan dengan spesifikasi litar itu sendiri. Apabila input semakin panjang, litar yang semakin besar diperlukan — tetapi kita perlu mendapatkan penerangan litar ini entah bagaimana jika kita hendak melaksanakannya.

Untuk semua contoh yang telah kita bincangkan, atau yang akan dibincangkan dalam pelajaran seterusnya, terdapat algoritma asas dari mana litar diterbitkan. Biasanya litar dalam sesebuah keluarga mengikut beberapa corak asas yang mudah untuk diekstrapolasi kepada input yang semakin besar, seperti menggabungkan penjumlah penuh untuk membuat litar Boolean untuk penambahan atau melakukan lapisan get Hadamard dan get lain dalam beberapa corak yang mudah diterangkan.

Tetapi apa yang berlaku jika terdapat kos pengiraan yang menghalang yang berkaitan dengan corak dalam litar itu sendiri? Sebagai contoh, penerangan setiap ahli CnC_n dalam keluarga litar boleh, pada dasarnya, ditentukan oleh beberapa fungsi nn yang amat sukar dikira.

Jawapannya ialah ini memang satu masalah — dan oleh itu kita mesti meletakkan sekatan tambahan pada keluarga litar selain daripada mempunyai kos polinomial agar ia benar-benar mewakili algoritma yang cekap. Sifat keseragaman untuk litar melakukan ini dengan menetapkan bahawa, dalam pelbagai formulasi tepat, ia mestilah mudah dari segi pengiraan untuk mendapatkan penerangan setiap litar dalam keluarga. Semua keluarga litar yang akan kita bincangkan memang mempunyai sifat ini — tetapi ini adalah isu penting yang perlu disedari secara umum apabila mengkaji model litar pengiraan dari sudut pandang formal.

Source: IBM Quantum docs — updated 15 Jan 2026
English version on doQumentation — updated 7 Mei 2026
This translation based on the English version of approx. 26 Mac 2026