Öğretici: Q# içinde bir kuantum rastgele sayı oluşturucusu gerçekleştirme

Bu öğreticide Q# , rastgele bir sayı üretmek için kuantum mekaniğinin doğasından yararlanan temel bir kuantum programı yazmayı öğreneceksiniz.

Bu öğreticide şunları yapacaksınız:

  • Bir Q# program oluşturun.
  • Bir Q# programın ana bileşenlerini gözden geçirin.
  • Bir sorunun mantığını tanımlayın.
  • Bir sorunu çözmek için klasik ve kuantum işlemlerini birleştirin.
  • Kübitler ve süperpozisyon ile çalışarak bir kuantum rastgele sayı oluşturucu oluşturun.

Önkoşullar

Visual Studio Code (VS Code) ve Jupyter Notebook'ta kod örneğini geliştirmek ve çalıştırmak için aşağıdakileri yükleyin:

Sorunu tanımlama

Klasik bilgisayarlar rastgele sayı üretmez, bunun yerine sözde rastgele sayılar üretir. Sözde rastgele sayı üreteci, tohum olarak adlandırılan bazı başlangıç değerlerine göre belirleyici bir sayı dizisi oluşturur. Bu çekirdek, rastgele değerleri daha iyi tahmin etmek için genellikle CPU saatinin geçerli zamanıdır.

Öte yandan kuantum bilgisayarlar gerçekten rastgele sayılar oluşturabilir. Bunun nedeni, bir kubitin süper pozisyondaki ölçümünün olasılıksal bir süreç olmasıdır. Ölçümün sonucu rastgeledir ve sonucu tahmin etmenin bir yolu yoktur. Bu, kuantum rastgele sayı oluşturucularının temel ilkesidir.

Kubit, süper pozisyonda olabilecek kuantum bilgilerinden oluşan bir birimdir. Ölçüldüyse kubit yalnızca 0 durumunda veya 1 durumunda olabilir. Ancak, ölçümden önce kubitin durumu, ölçümle 0 veya 1 okuma olasılığını temsil eder.

Başlangıç olarak temel bir durumdaki kubiti (örneğin, sıfır) alırsınız. Rastgele sayı oluşturucusunun ilk adımı, kubiti eşit bir süper pozisyona yerleştirmek için hadamard işlemi kullanmaktır. Bu durumun ölçümü, her sonucun %50 olasılığına sahip bir sıfır veya bir sonuç verir. Bu, gerçekten rastgele bir bittir.

Kubitin süper pozisyondaki ölçümünden sonra ne elde edeceğinizi bilmenin hiçbir yolu yoktur ve kod her çağrıldığında sonuç farklı bir değerdir. Ancak bu davranışı daha büyük rastgele sayılar oluşturmak için nasıl kullanabilirsiniz?

Şu ikili sayı dizisini oluşturarak işlemi dört kez yinelediğinizi varsayalım:

$${0, 1, 1, 0}$$

Bu bitleri bir bit dizesine ekler veya birleştirirseniz, daha büyük bir sayı oluşturabilirsiniz. Bu örnekte, ${0110}$ bit dizisi ondalık sayı sisteminde altıya eşdeğerdir.

$${0110_{\ binary} \equiv 6_{\ decimal}}$$

Bu işlemi birçok kez yinelerseniz, birden çok biti birleştirerek büyük bir sayı oluşturabilirsiniz. Bu yöntemi kullanarak, güvenlik parolası olarak kullanılacak bir sayı oluşturabilirsiniz, çünkü hiçbir korsanın ölçüm dizisinin sonuçlarını belirleyemediğinden emin olabilirsiniz.

Rastgele sayı oluşturucu mantığını tanımlama

Şimdi rastgele bir sayı oluşturucunun mantığının ne olması gerektiğini özetleyelim:

  1. Oluşturmak istediğiniz maksimum sayı olarak tanımlayın max .
  2. Oluşturmanız gereken rastgele bit sayısını tanımlayın. Bu işlem, nBits’e kadar olan tamsayıları ifade etmek için gereken bit sayısını (max) hesaplayarak yapılır.
  3. nBits uzunluğunda rastgele bir bit dizesi oluşturun.
  4. Bit dizesi max üst sınırından yüksek bir sayıyı temsil ediyorsa üçüncü adıma geri dönün.
  5. Aksi takdirde işlem tamamlanır. Oluşturulan sayıyı tamsayı olarak döndürün.

Örnek olarak max, 12 olarak ayarlandığında: Yani 12, parola olarak kullanmak istediğiniz en büyük sayıdır.

${\lfloor ln(12) / ln(2) + 1 \rfloor}$ veya 0 ile 12 arasında bir sayıyı temsil etmek için 4 bit gerekir. Yerleşik işlevini kullanabiliriz. Bu işlev BitSizeIherhangi bir tamsayıyı alır ve bunu temsil etmek için gereken bit sayısını döndürür.

${13_{\ decimal}}$ denklemine eşdeğer olan ${1101_{\ binary}}$ bit dizesini oluşturduğunuzu varsayalım. 13, 12'den büyük olduğu için işlemi tekrarlamanız gerekir.

Daha sonra, ${6_{\ decimal}}$ denklemine eşdeğer olan ${0110_{\ binary}}$ bit dizesini oluşturuyorsunuz. 6, 12'den küçük olduğu için işlem tamamlanır.

Kuantum rastgele sayı oluşturucu, parolanız olarak 6 sayısını döndürür. Pratikte, mümkün olan tüm parolaları deneyerek daha düşük sayıların kolayca kırılabildiğinden, en yüksek sayı olarak daha büyük bir sayı ayarlayın. Aslında, parolanızı tahmin etme veya kırma zorluğunu artırmak için, ikiliyi metne dönüştürmek ve sayılar, simgeler ve karışık harf kullanarak parola oluşturmak için ASCII kodu kullanabilirsiniz.

Rastgele bit oluşturucu yazma

İlk adım, rastgele bir bit oluşturan bir Q# işlem yazmaktır. Bu işlem, rastgele sayı oluşturucunun yapı taşları arasında yer alır.

operation GenerateRandomBit() : Result {
    // Allocate a qubit.
    use q = Qubit();

    // Set the qubit into superposition of 0 and 1 using the Hadamard 
    H(q);

    // At this point the qubit `q` has 50% chance of being measured in the
    // |0〉 state and 50% chance of being measured in the |1〉 state.
    // Measure the qubit value using the `M` operation, and store the
    // measurement value in the `result` variable.
    let result = M(q);

    // Reset qubit to the |0〉 state.
    // Qubits must be in the |0〉 state by the time they are released.
    Reset(q);

    // Return the result of the measurement.
    return result;
}

Şimdi yeni koda göz atın.

  • Girdi almayan ve GenerateRandomBit türünde bir değer üreten Result işlemini tanımlarsınız. Türü Result bir ölçümün sonucunu temsil eder ve iki olası değere sahip olabilir: Zero veya One.
  • Anahtar sözcüğüyle use tek bir kubit ayırırsınız. Tahsis edildiğinde, bir kubit her zaman |0〉 durumunda olur.
  • Kubiti eşit bir süperpozisyona yerleştirmek için H işlemini kullanırsınız.
  • kubiti M ölçmek, ölçülen değeri (Zero veya One) döndürmek için işlemini kullanırsınız.
  • Kubiti Reset |0〉 durumuna sıfırlamak için işlemini kullanırsınız.

Kubiti H işlemiyle süperpozisyona getirip M işlemiyle ölçtüğünüzde, kod her çağrıldığında sonuç her seferinde farklı bir değer olur.

Bloch küresi Q# ile kodu görselleştirme

Bloch küresinde kuzey kutbu klasik 0 değerini, güney kutbu ise klasik 1 değerini temsil eder. Herhangi bir süperpozisyon, küre üzerinde bir nokta olarak temsil edilebilir (küre bir okla gösterilir). Okun ucu kutba ne kadar yakın olursa kubitin ölçüm sonrasında o kutba atanmış olan klasik değeri alma ihtimali o kadar yüksek olur. Örneğin, aşağıdaki şekildeki okla temsil edilen kubit durumunun, ölçerseniz 0 değerini verme olasılığı daha yüksektir.

Yüksek sıfır ölçme olasılığına sahip kubit durumunu gösteren diyagram.

Kodun ne yaptığını görselleştirmek için bu gösterimi kullanabilirsiniz:

  1. İlk olarak, |0〉 durumunda başlatılan bir kubitle başlayın ve 0 ve 1 olasılıklarının aynı olduğu eşit bir süper konum oluşturmak için bir H işlem uygulayın.

    Hadamard kapısı uygulanarak süper pozisyondaki bir kubitin hazırlanmasını gösteren diyagram.
  2. Ardından kubiti ölçün ve çıkışı kaydedin:

    Kubitin ölçülerek çıkışın kaydedildiği diyagram.

Ölçümün sonucu rastgele olduğundan ve 0 ile 1'i ölçme olasılıkları aynı olduğundan, tamamen rastgele bir bit elde etmişsinizdir. Tamsayılar oluşturmak için bu işlemi birkaç kez çağırabilirsiniz. Örneğin, üç rastgele bit elde etmek için işlemi üç kez çağırırsanız, rastgele 3 bit sayılar (0 ile 7 arasında rastgele bir sayı) oluşturabilirsiniz.

Tam bir rastgele sayı oluşturucu yazma

  1. İlk olarak, gerekli ad alanlarını standart kitaplıktan Q# programa aktarmanız gerekir. Derleyici Q# birçok yaygın işlevi ve işlemi otomatik olarak yükler, ancak tam rastgele sayı oluşturucu için iki Q# ad alanından bazı ek işlevlere ve işlemlere ihtiyacınız vardır: Std.Mathve Std.Convert.

    import Std.Convert.*;
    import Std.Math.*;
    
  2. Ardından işlemi tanımlarsınız GenerateRandomNumberInRange . Bu işlem bir bit dizesi derlemek için GenerateRandomBit işlemini tekrar tekrar çağırır.

    /// Generates a random number between 0 and `max`.
    operation GenerateRandomNumberInRange(max : Int) : Int {
        // Determine the number of bits needed to represent `max` and store it
        // in the `nBits` variable. Then generate `nBits` random bits which will
        // represent the generated random number.
        mutable bits = [];
        let nBits = BitSizeI(max);
        for idxBit in 1..nBits {
            bits += [GenerateRandomBit()];
        }
        let sample = ResultArrayAsInt(bits);
    
        // Return random number if it is within the requested range.
        // Generate it again if it is outside the range.
        return sample > max ? GenerateRandomNumberInRange(max) | sample;
    }
    
    

    Yeni kodu kısaca gözden geçirelim.

    • 'a kadar maxolan tamsayıları ifade etmek için gereken bit sayısını hesaplamanız gerekir. BitSizeI ad alanındaki Std.Math işlevi, bir tamsayıyı temsil etmek için gereken bit sayısını verir.
    • SampleRandomNumberInRange işlemi, for'e eşit veya ondan küçük bir sayı oluşturana kadar rastgele sayılar oluşturmak için bir max döngüsü kullanır. Döngü, for diğer programlama dillerindeki bir for döngüyle tam olarak aynı şekilde çalışır.
    • değişken bits , değiştirilebilir bir değişkendir. Değiştirilebilir değişken, hesaplama sırasında değişebilen değişkendir. Değiştirilebilir bir değişkenin değerini değiştirmek için set yönergesini kullanın.
    • İşlev ResultArrayAsInt , varsayılan Std.Convert ad alanından bit dizesini pozitif bir tamsayıya dönüştürür.
  3. Son olarak, programa bir giriş noktası eklersiniz. Varsayılan olarak, Q# derleyici bir Main işlemi arar ve burada işlemeye başlar. 0 ile 100 arasında rastgele bir sayı oluşturmak için işlemini çağırır GenerateRandomNumberInRange .

    operation Main() : Int {
        let max = 100;
        Message($"Sampling a random number between 0 and {max}: ");
    
        // Generate random number in the 0..max range.
        return GenerateRandomNumberInRange(max);
    }
    

    let yönergesi, hesaplama sırasında değişmeyen değişkenleri bildirir. Burada maksimum değeri 100 olarak tanımlarsınız.

    İşlem hakkında Main daha fazla bilgi için bkz . Giriş Noktaları.

  4. Rastgele sayı oluşturucunun tam kodu aşağıdaki gibidir:

import Std.Convert.*;
import Std.Math.*;

operation Main() : Int {
    let max = 100;
    Message($"Sampling a random number between 0 and {max}: ");

    // Generate random number in the 0..max range.
    return GenerateRandomNumberInRange(max);
}

/// Generates a random number between 0 and `max`.
operation GenerateRandomNumberInRange(max : Int) : Int {
    // Determine the number of bits needed to represent `max` and store it
    // in the `nBits` variable. Then generate `nBits` random bits which will
    // represent the generated random number.
    mutable bits = [];
    let nBits = BitSizeI(max);
    for idxBit in 1..nBits {
        bits += [GenerateRandomBit()];
    }
    let sample = ResultArrayAsInt(bits);

    // Return random number if it is within the requested range.
    // Generate it again if it is outside the range.
    return sample > max ? GenerateRandomNumberInRange(max) | sample;
}

operation GenerateRandomBit() : Result {
    // Allocate a qubit.
    use q = Qubit();

    // Set the qubit into superposition of 0 and 1 using a Hadamard operation
    H(q);

    // At this point the qubit `q` has 50% chance of being measured in the
    // |0〉 state and 50% chance of being measured in the |1〉 state.
    // Measure the qubit value using the `M` operation, and store the
    // measurement value in the `result` variable.
    let result = M(q);

    // Reset qubit to the |0〉 state.
    // Qubits must be in the |0〉 state by the time they are released.
    Reset(q);

    // Return the result of the measurement.
    return result;
}

Rastgele sayı oluşturucu programını çalıştırma

TERCIH ettiğiniz geliştirme ortamını (VS Code'daki QDK uzantısını veya Jupyter Notebook QDK Python paketini) seçin.

  1. VS Code'da Dosya menüsünü açın ve Yeni Metin Dosyası'nı seçerek yeni bir dosya oluşturun.

  2. Dosyayı RandomNumberGenerator.qs olarak kaydedin. Bu dosya, programınızın kodunu içerir Q# .

  3. Aşağıdaki kodu RandomNumberGenerator.qs dosyasına kopyalayın.

    import Std.Convert.*;
    import Std.Math.*;
    
    operation Main() : Int {
        let max = 100;
        Message($"Sampling a random number between 0 and {max}: ");
    
        // Generate random number in the 0..max range.
        return GenerateRandomNumberInRange(max);
    }
    
    /// # Summary
    /// Generates a random number between 0 and `max`.
    operation GenerateRandomNumberInRange(max : Int) : Int {
        // Determine the number of bits needed to represent `max` and store it
        // in the `nBits` variable. Then generate `nBits` random bits which will
        // represent the generated random number.
        mutable bits = [];
        let nBits = BitSizeI(max);
        for idxBit in 1..nBits {
            bits += [GenerateRandomBit()];
        }
        let sample = ResultArrayAsInt(bits);
    
        // Return random number if it is within the requested range.
        // Generate it again if it is outside the range.
        return sample > max ? GenerateRandomNumberInRange(max) | sample;
    }
    
    /// # Summary
    /// Generates a random bit.
    operation GenerateRandomBit() : Result {
        // Allocate a qubit.
        use q = Qubit();
    
        // Set the qubit into superposition of 0 and 1 using the Hadamard 
        // operation `H`.
        H(q);
    
        // At this point the qubit `q` has 50% chance of being measured in the
        // |0〉 state and 50% chance of being measured in the |1〉 state.
        // Measure the qubit value using the `M` operation, and store the
        // measurement value in the `result` variable.
        let result = M(q);
    
        // Reset qubit to the |0〉 state.
        // Qubits must be in the |0〉 state by the time they are released.
        Reset(q);
    
        // Return the result of the measurement.
        return result;
    
        // Note that Qubit `q` is automatically released at the end of the block.
    }
    
  4. Programınızı çalıştırmak için, yukarıdaki komut listesinden Main() seçin veya Ctrl + F5 tuşlarına basın. Program, Main() işlemi varsayılan simülatörde çalıştırır.

    Kod Merceği'nde Çalıştır komutunun nerede bulunacağını gösteren Visual Studio Code ekran görüntüsü.

  5. Çıkışınız hata ayıklama konsolunda görünür.

  6. Farklı bir sonuç görmek için programı yeniden çalıştırın.

Not

QIR target profili Sınırsız olarak ayarlanmamışsa, programı çalıştırdığınızda bir hata alırsınız. Bu program için, siz profili kendiniz ayarlamadığınız sürece derleyici profili otomatik target olarak Kısıtlanmamış olarak ayarlar.

Sıklık histogramını çizme

Şimdi kuantum programını birden çok kez çalıştırarak elde edilen sonuçların dağılımını görselleştirelim. Sıklık histogramı bu sonuçların olasılık dağılımını görselleştirmeye yardımcı olur.

  1. Görünüm -> Komut Paleti'ni seçin ve histogram yazın. Bu, QDK: Dosyayı çalıştır ve histogramı göster komutunu getirir. Ayrıca, öncesindeki komutlar listesinden Main()'ı seçebilirsiniz. Histogram penceresini açmak Q# için bu seçeneği belirleyin.

    CodeLens'te histogram komutunun nerede bulunacağını gösteren Visual Studio Code ekran görüntüsü.

  2. Programı çalıştırmak için, örneğin 100 çekim gibi bir çekim sayısı girin ve Enter tuşuna basın. Histogram, Q# histogram penceresinde görüntülenecektir.

  3. Histogramdaki her çubuk olası bir sonuca karşılık gelir ve yüksekliği sonucun kaç kez gözlemlendiğini gösterir. Histogramı her çalıştırdığınızda farklı sonuçların sayısı farklılık gösterebilir.

    Visual Studio Code'da histogram penceresinin Q# ekran görüntüsü.

    İpucu

    Fare kaydırma tekerleğini veya izleme yüzeyi hareketini kullanarak histogramı yakınlaştırabilirsiniz. Yakınlaştırdığınızda, kaydırma sırasında 'Alt' tuşuna basarak grafiği kaydırabilirsiniz.

  4. Bu sonucun yüzdesini görüntülemek için bir çubuk seçin.

  5. Seçenekleri görüntülemek için sol üst ayarlar simgesini seçin. İlk 10 sonucu, ilk 25 sonucu veya tüm sonuçları görüntüleyebilirsiniz. Ayrıca sonuçları yüksekten düşüeğe veya düşükten yükseğe sıralayabilirsiniz.

    Ayarların nasıl görüntüleneceğini gösteren Visual Studio Code Q# histogram penceresinin ekran görüntüsü.

Not

Çağrılabilen targets tam ResultArrayAsInt sahip bir QPU gerektirdiğinden, bu kod parçacığı şu anda kullanılabilir Azure Quantum donanımlarında çalışmaz.

Diğer Q# öğreticileri keşfedin: