تمرين الجزء الثاني - إنشاء منشئ رقم عشوائي كمومي
في هذه الوحدة ، يمكنك تنفيذ الجزء الثاني من مولد الأرقام العشوائية الكمومية. يمكنك دمج عدة بتات عشوائية لتشكيل رقم عشوائي أكبر. يعتمد هذا الجزء على مولد البت العشوائي الذي قمت بإنشائه بالفعل في الوحدة السابقة.
دمج وحدات بت عشوائية متعددة لتشكيل عدد أكبر
في الوحدة السابقة ، قمت بإنشاء مولد بت عشوائي يضع الكيوبت في حالة التراكب ثم يقيس هذا الكيوبت لتوليد قيمة بت عشوائية إما 0 أو 1 ، ولكل منها احتمال 50%. قيمة هذه البت عشوائية حقا ، ولا توجد طريقة لمعرفة نتيجة القياس مسبقا. ولكن كيف يمكنك استخدام هذا السلوك لإنشاء أعداد عشوائية أكبر؟
إذا كررت العملية أربع مرات ، فيمكنك إنشاء هذا التسلسل من الأرقام الثنائية:
$${0, 1, 1, 0}$$
إذا قمت بدمج هذه البتات في سلسلة بت ، فيمكنك تكوين رقم أكبر. في هذا المثال ، يعادل تسلسل البتات ${0110} $ في الثنائي الرقم 6 في الرقم العشري.
$${0110_{\ ثنائي} \equiv 6_{\ عشري}}$$
لإنشاء رقم عشوائي كبير بشكل تعسفي ، ما عليك سوى تكرار هذه العملية عدة مرات. بعد ذلك ، اجمع كل البتات في رقم ثنائي وقم بتحويل هذا الرقم الثنائي إلى رقم عشري.
تحديد منطق منشئ عدد عشوائي
قبل كتابة كود Q # الخاص بك ، دعنا نحدد المنطق لإنشاء رقم عشوائي:
- حدد
maxالحد الأقصى للرقم العشري الذي تريد إنشاؤه. - تحديد عدد البتات العشوائية ،
nBitsالمطلوبة لتوليدmax. - إنشاء سلسلة بت عشوائية طولها
nBits. - إذا كانت سلسلة البتات تمثل رقما أكبر من
max، فارجع إلى الخطوة السابقة. - وإلا، فإن العملية قد تكون اكتملت. قم بإرجاع الرقم الذي تم إنشاؤه كعدد عشري صحيح.
على سبيل المثال ، دعنا نحدد max أن يكون 12. أي أن 12 هو أكبر رقم يجب أن ينتجه مولد الأرقام العشوائية.
استخدم المعادلة التالية لتحديد عدد البتات المطلوبة لتمثيل الرقم 12 في شكل ثنائي:
$${\lfloor ln(12) / ln(2) + 1 \rfloor}$$
وفقا لهذه المعادلة ، تحتاج إلى 4 بتات لتمثيل رقم بين 0 و 12.
على سبيل المثال ، لنفترض أنك أنشأت بت عشوائي أربع مرات وحصلت على سلسلة البتات ${1101_{\ binary}}$. هذه القيمة في الملف الثنائي تساوي 13 في الرقم العشري. لأن 13 أكبر من 12، وتكرر العملية.
بعد ذلك ، تقوم بإنشاء سلسلة البتات ${0110_{\ binary}}$ ، والتي تساوي ${6_{\ decimal}}$. لأن 6 أقل من 12، العملية كاملة.
يقوم منشئ الرقم العشوائي الكمومي بإرجاع الرقم 6.
قم بإنشاء مولد أرقام عشوائية كاملة في Q#
هنا ، تقوم بالتوسع في الملف Main.qs من الدرس السابق لإنشاء مولد الأرقام العشوائي الخاص بك.
استيراد المكتبات المطلوبة
أولا ، قم باستيراد مساحات الأسماء من مكتبة Q # القياسية التي تحتوي على الوظائف والعمليات التي تحتاجها لكتابة برنامجك. يقوم مترجم Q# بتحميل العديد من الوظائف والعمليات الشائعة تلقائيا. ولكن بالنسبة لمولد الأرقام العشوائية الكمومية ، فأنت بحاجة إلى بعض الوظائف والعمليات الإضافية من مساحتين لأسماء Q #: Std.Math و Std.Convert.
انسخ التوجيهات التالية import والصقها في بداية ملفك Main.qs :
import Std.Convert.*;
import Std.Math.*;
إعادة تسمية Main العملية إلى GenerateRandomBit
يستخدم برنامج مولد الأرقام العشوائية العملية Main التي كتبتها في الوحدة السابقة لإنشاء بت عشوائي. أعد تسمية Main العملية بحيث GenerateRandomBit يكون لهذه العملية اسم أكثر وصفا وليست نقطة الدخول إلى البرنامج.
انسخ والصق الكود التالي في Main.qs:
import Std.Convert.*;
import Std.Math.*;
operation GenerateRandomBit() : Result {
// Allocate a qubit.
use q = Qubit();
// Set the qubit into superposition of 0 and 1 using the Hadamard
H(q);
// Measure the qubit and store the result.
let result = M(q);
// Reset qubit to the |0〉 state.
Reset(q);
// Return the result of the measurement.
return result;
}
تحديد عملية مولد الأرقام العشوائية
قم بإنشاء عملية جديدة تسمى GenerateRandomNumberInRange. تستدعي GenerateRandomBit هذه العملية العملية بشكل متكرر لإنشاء سلسلة من البتات.
انسخ الكود التالي وضعه مباشرة قبل العملية GenerateRandomBit في ملفك Main.qs :
/// 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 {
set bits += [GenerateRandomBit()];
}
let sample = ResultArrayAsInt(bits);
// Return random number if it's within the requested range.
// Generate it again if it's outside the range.
return sample > max ? GenerateRandomNumberInRange(max) | sample;
}
فيما يلي نظرة عامة على الكود في GenerateRandomNumberInRange:
- استدعاء الدالة
BitSizeIمن المكتبةStd.Mathلحساب عدد وحدات البت اللازمة لتمثيل العدد الصحيح المخزن فيmax. - استخدم حلقة
forلإنشاء عدد من البتات العشوائية تساويnBits. استدعاء العملية الخاصة بكGenerateRandomBitلإنشاء البتات العشوائية. - داخل الحلقة
for، استخدم العبارةsetلتحديث المتغيرbitsمع كل بت عشوائي جديد. المتغيرbitsهو متغير قابل للتغيير ، مما يعني أن قيمة يمكنbitsأن تتغير أثناء الحساب. - قم باستدعاء الدالة
ResultArrayAsIntمن المكتبةStd.Convertلتحويل مصفوفة البتاتbitsإلى عدد صحيح موجب مخزن فيsample. - في البيان
return، تحقق مما إذا كانsampleأكبر منmax. إذاsampleكان أكبر منmax، فاتصلGenerateRandomNumberInRangeمرة أخرى وابدأ من جديد. وإلا، قم بإرجاع الرقم العشوائي المخزن فيsample.
إضافة نقطة إدخال
أخيرا ، أضف عملية نقطة إدخال إلى التعليمات البرمجية الخاصة بك حتى يتمكن المترجم من تشغيل برنامجك. بشكل افتراضي ، يبحث مترجم Q# عن Main عملية ويستخدم Main كنقطة إدخال ، بغض النظر عن مكان Main وجوده في ملفك. هنا، Main تقوم العملية بتعيين قيمة ل max وتستدعي GenerateRandomNumberInRange العملية لإنشاء رقم عشوائي بين 0 و max.
على سبيل المثال، لإنشاء رقم عشوائي بين 0 و100، انسخ التعليمات البرمجية التالية إلى ملفك Main.qs :
operation Main() : Int {
let max = 100;
Message($"Generating a random number between 0 and {max}: ");
// Generate random number in the 0..max range.
return GenerateRandomNumberInRange(max);
}
البرنامج النهائي
إليك كود Q # الكامل لبرنامجك في Main.qs:
import Std.Convert.*;
import Std.Math.*;
operation Main() : Int {
let max = 100;
Message($"Generating 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 {
set bits += [GenerateRandomBit()];
}
let sample = ResultArrayAsInt(bits);
// Return random number if it's within the requested range.
// Generate it again if it's 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 the Hadamard operation
H(q);
// 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.
Reset(q);
// Return the result of the measurement.
return result;
}
قم بتشغيل البرنامج.
جرب مولد الأرقام العشوائية الكمومية الجديد!
لتشغيل البرنامج الخاص بك ، اختر عدسة تشغيل التعليمات البرمجية من قائمة الأوامر أعلى العملية Main . أو اضغط على Ctrl + F5. يتم عرض الإخراج في وحدة تحكم تتبع الأخطاء. قم بتشغيل البرنامج عدة مرات ولاحظ كيف تتغير النتيجة.
تهانينا! لقد أنشأت مولد أرقام كمومية عشوائية حقا في Q #.
تمرين المكافأة
حاول تعديل البرنامج بحيث يتطلب أيضا أن يكون الرقم العشوائي الذي تم إنشاؤه أكبر من الحد الأدنى للأرقام الموجبة ، minبدلا من الصفر.