خوارزميات التصحيح على الرسوم البيانية - الآن مع الصور

تخيل موقفًا نموذجيًا في السنة الأولى: قرأت عن خوارزمية Dinits ، وقمت بتنفيذها ، لكنها لم تنجح ، ولا تعرف السبب. يتمثل الحل القياسي في بدء تصحيح الأخطاء بخطوات ، في كل مرة يتم فيها رسم الحالة الحالية للرسم البياني على قطعة من الورق ، ولكن هذا غير مريح بشكل كبير. حاولت تصحيح الموقف كجزء من مشروع فصل دراسي في هندسة البرمجيات ، وفي منشور ، سوف أخبرك كيف انتهى بي الأمر باستخدام مكون إضافي لبرنامج Visual Studio. يمكنك تنزيله من هنا ، ويمكن الاطلاع على الكود المصدري والوثائق هنا . فيما يلي لقطة شاشة للرسم البياني الذي تم الحصول عليه لخوارزمية Dinits.



عن نفسي


اسمي أولغا ، تخرجت من السنة الثالثة في اتجاه "الرياضيات التطبيقية وعلوم الكمبيوتر" في سان بطرسبرج HSE مع شهادة في هندسة البرمجيات. قبل دخول الجامعة ، لم أشارك في البرمجة.

البحث: المتطلبات


في أعمالنا البحثية ممارسة الفصل الدراسي. يحدث هذا عادةً مثل هذا: في بداية الفصل الدراسي ، يتم تقديم عرض للأعمال البحثية - يقدم ممثلو الشركات المختلفة جميع أنواع المشاريع. ثم يختار الطلاب مشاريعهم المفضلة ، والمشرفون يختارون طلابهم المفضلين ، وما إلى ذلك. في النهاية ، يجد كل طالب مشروعًا لنفسه.

ولكن هناك طريقة أخرى: يمكنك أن تجد بشكل مستقل مشرفًا ومشروعًا ، ثم تقنع المنسق بأن هذا المشروع يمكن أن يكون حقًا بحثًا وتطويرًا كاملاً. للقيام بذلك ، إثبات أن:

  1. أنت ستفعل شيئًا جديدًا. بالطبع ، قد يحتوي المشروع على نظائرها ، ولكن يجب أن يكون لديك بعض المزايا عليها.
  2. يجب أن تكون المهمة معقدة للغاية ، أي أن العمل يجب أن يكون لفصل دراسي ، وليس ليوم واحد. في الوقت نفسه ، من الضروري أن يتم المشروع بالفعل في فصل دراسي.
  3. يجب أن يكون مشروعك مفيدًا للعالم. هذا هو ، عندما سئل لماذا هذا ضروري ، يجب أن لا تجيب: "حسنا ، أنا بحاجة إلى القيام ببعض البحوث."

اخترت الطريقة الثانية. أول شيء فعله بعد أن اتفقت مع المشرف هو العثور على موضوع المشروع. تتضمن قائمة الأفكار: مدقق نمط الكود الخاص بـ Lua ، مصحح الأخطاء الذي يسمح لك بحساب التعبيرات في أجزاء ، وأداة لتدريب أولمبياد / البرمجة ، والتي تسمح لك بتصور ما يحدث في الكود. وهذا هو ، متخيل لهياكل البيانات التعسفية جنبا إلى جنب مع المصحح. على سبيل المثال ، يكتب الشخص شجرة الديكارتية ، وفي رؤوس العملية ، يتم رسم الحواف ، والرأس الحالي وما إلى ذلك. في النهاية ، قررت أن أتناول هذا الخيار.

خطة عمل المشروع


يتكون عملي في المشروع من المراحل التالية:

  1. كانت دراسة موضوع الموضوع مطلوبة لفهم ما إذا كانت هذه المشكلة قد تم حلها بالفعل (عندئذٍ يجب تغيير موضوع المشروع) ، وما هي نظائرها ، وما هي مزاياها وعيوبها ، والتي يمكنني أخذها في الاعتبار في عملي.
  2. تحديد الوظيفة المحددة التي ستتمتع بها الأداة التي تم إنشاؤها. تم الإعلان عن موضوع المشروع بشكل تجريدي تمامًا ، وكان هذا ضروريًا للتأكد من أن المهمة معقدة للغاية ، ولكن في الوقت نفسه ، من الواقعي إكمالها في فصل دراسي.
  3. مطلوب إنشاء واجهة مستخدم نموذج أولي لشرح كيفية استخدام الأداة التي تم إنشاؤها. وأضاف أكثر خصوصية من مجموعة من الميزات التي وصفتها الكلمات.
  4. اختيار التبعيات - تحتاج إلى فهم كيفية ترتيب كل شيء من وجهة نظر المطور وتحديد الأدوات التي سيتم استخدامها في عملية كتابة التعليمات البرمجية.
  5. إنشاء نموذج أولي (إثبات للمفهوم) ، وهذا هو ، مثالا بسيطًا يكون فيه معظمها مشفرًا. من خلال هذا المثال ، كان علي التعامل مع جميع الأدوات التي كنت سأستخدمها ، وتعلم أيضًا كيفية حل جميع الصعوبات التي نشأت على طول الطريق ، حتى تكون النسخة النهائية مكتوبة بالفعل "نظيفة".
  6. العمل على جزء المحتوى ، أي تطوير وتنفيذ منطق الأداة.
  7. مطلوب حماية المشروع من أجل التحدث بسرعة عن العمل المنجز وإعطاء فرصة لتقييمه للجميع ، حتى الأشخاص الذين لا يبحثون في الموضوع. إنه تدريب قبل التخرج. في الوقت نفسه ، لا يضمن مشروع جيد الإعداد أن يكون التقرير جيدًا ، لأنه يتطلب مهارات أخرى ، على سبيل المثال ، القدرة على التحدث إلى الجمهور.

لقد قمت دائمًا بالتخطيط مع المشرف. لقد توصلنا دائمًا إلى جميع الأفكار التي نشأت على طول الطريق وناقشناها. بالإضافة إلى ذلك ، قدم لي المشرف النصيحة بشأن الكود وساعد في إدارة الوقت. حول جميع المشكلات الفنية (الأخطاء غير المفهومة ، وما إلى ذلك) التي أبلغت عنها دائمًا ، لكن في أغلب الأحيان تمكنت من حلها بنفسي.

بحث الموضوع


بالنسبة للمبتدئين ، ينبغي أن تكون قيادتنا مقتنعة بأن هذا الموضوع يستحق أن يكون عملي البحثي. وللبداية من النقطة الأولى: البحث عن نظائرها.

كما اتضح ، هناك العديد من نظائرها. ولكن تم تصميم معظمها لتصور الذاكرة. وهذا يعني أنهم كانوا يقومون بعمل رائع من خلال التصور الخاص بالشجرة الديكارتية ، لكنهم لا يستطيعون أن يفهموا أن الكومة الموجودة على المصفوفة يجب ألا تُرسم كصفيف ، ولكن كشجرة. وشملت هذه gdbgui ، مصحح عرض البيانات ، ومكون إضافي لبرنامج Eclipse jGRASP ، ومكوّن إضافي لبرنامج Visual Studio Data Structures Visualizer . تم إنشاء الأخير أيضًا لمشاكل برمجة olympiad ، ولكنه كان قادرًا على تصور هياكل البيانات فقط على المؤشرات.

كان هناك عدد قليل من الأدوات الأخرى: Algojammer for python (وقد أردنا إيجابيات ، باعتبارها اللغة الأكثر شعبية بين أولمبياد) وأداة Lens المطورة في عام 1994. هذا الأخير ، بناءً على الوصف ، فعل ما يحتاجه تقريبًا ، ولكن لسوء الحظ ، تم إنشاؤه تحت Sun OS 4.1.3 (نظام تشغيل من 1992). لذلك ، على الرغم من توافر أكواد المصدر ، فقد تقرر عدم إضاعة الوقت في هذه الآثار المريبة.

لذلك ، بعد إجراء بعض الأبحاث ، تبين أن تولا ، التي من شأنها أن تفعل بالضبط ما أردنا ، وفي نفس الوقت تعمل على الآلات الحديثة ، ليست في طبيعتها بعد.

تعريف الوظيفة


كانت الخطوة الثانية لإثبات أن هذه المهمة معقدة للغاية ، ولكنها قابلة للتنفيذ. للقيام بذلك ، كان من الضروري اقتراح شيء أكثر تحديداً من "أريد صورة جميلة ، وأن كل شيء يصبح واضحًا على الفور".

في هذا المشروع ، قررنا التركيز على تصور الرسوم البيانية فقط: هناك العديد من الخوارزميات على الرسوم البيانية التي يمكن تنفيذها بطرق مختلفة ، وحتى لو ضاقت ، فإن المهمة لا تزال غير تافهة.

من الواضح أيضًا أن الأداة يجب أن تتكامل بطريقة أو بأخرى مع مصحح الأخطاء. يجب أن نكون قادرين على عرض قيم المتغيرات والتعبيرات ورسم صورة نهائية من هذه القيم.

بعد ذلك ، كان من الضروري التوصل إلى لغة معينة تسمح لنا ببناء رسم بياني وفقًا للحالة الحالية للبرنامج بالطريقة التي نريدها. بالإضافة إلى الرسم البياني نفسه ، كان من الضروري توفير القدرة على تغيير لون الرؤوس والحواف ، وإضافة ملصقات عشوائية إليهم وتغيير الخصائص الأخرى. تبعا لذلك ، كانت الفكرة الأولى:

  1. تحديد ما لدينا رؤوس ، على سبيل المثال ، الأرقام من 0 إلى ن.
  2. تحديد وجود حافة بين القمم باستخدام الشرط المنطقي. في هذه الحالة ، تكون الحواف من أنواع مختلفة ، ولكل نوع مجموعة الخصائص الخاصة به.
  3. علاوة على ذلك ، يمكننا تحديد خصائص قمة الرأس مثل اللون ، وأيضا باستخدام الشرط المنطقي.
  4. تجول في الخطوات مع مصحح الأخطاء: يتم حساب جميع التعبيرات ، ويتم فحص جميع الشروط ، وبناءً على ذلك ، يتم رسم رسم بياني.

نماذج واجهة المستخدم


وجهت النموذج الأولي لواجهة المستخدم في NinjaMock . كان هذا مطلوبًا لفهم كيفية ظهور الواجهة من وجهة نظر المستخدم بشكل أفضل ، والإجراءات التي سيحتاج إلى تنفيذها. إذا كانت هناك مشاكل في النموذج الأولي ، فسنفهم أن هناك بعض التناقضات المنطقية ، ويجب التخلص من هذه الفكرة. للإخلاص ، أخذت بعض الخوارزميات. تُظهر الصورة أدناه أمثلة عن كيف تخيلت إعدادات تصور DFS وخوارزمية Floyd .



كما تخيلت إعدادات DFS. يتم تخزين الرسم البياني كقائمة مجاورة ، لذلك يتم تحديد الحافة بين القمم i و j بالشرط g[i].find() != g[i].end() (في الواقع ، حتى لا g[i].find() != g[i].end() الحواف ، نحتاج إلى التحقق من i <= j ). يظهر مسار DFS بشكل منفصل: p[j] == i . سيتم توجيه هذه الحواف.



افترضت أنه بالنسبة لخوارزمية فلويد ، سيكون من الضروري رسم الحواف الحقيقية المخزنة في الصفيف c والرمادي - أقصر الطرق الموجودة في هذه المرحلة ، المخزنة في الصفيف d . لكل حافة وأقصر مسار ، يتم كتابة وزنه.

اختيار التبعية


للخطوة التالية ، كان من الضروري فهم كيفية القيام بكل هذا. بادئ ذي بدء ، كان التكامل مع مصحح الأخطاء مطلوبًا. أول ما يتبادر إلى الذهن عندما تكون كلمة "مصحح الأخطاء" هي gdb ، ولكن بعد ذلك سيتعين عليك إنشاء الواجهة الرسومية بالكامل من الصفر ، وهو أمر صعب حقًا على الطالب القيام به في الفصل الدراسي. الفكرة الثانية الواضحة هي جعل مكون إضافي لبعض بيئة التطوير الحالية. كخيارات اعتبرتها QTCreator و CLion و Visual Studio.

تم تجاهل خيار CLion على الفور تقريبًا ، لأنه يحتوي أولاً على شفرة مصدر مغلقة ، وثانيًا ، كل شيء سيء للغاية مع الوثائق (ولا يحتاج أي شخص إلى صعوبات إضافية). QTCreator ، على عكس Visual Studio ، هو نظام أساسي مفتوح المصدر ، وبالتالي ، في البداية ، قررنا أن نتناوله.

ومع ذلك ، اتضح أن QTCreator تم تكييفه بشكل سيء للتمديد باستخدام المكونات الإضافية. تتمثل الخطوة الأولى في إنشاء مكون إضافي لـ QTCreator في الإنشاء من المصدر. استغرق الأمر مني أسبوعًا ونصف. في النهاية ، أرسلت تقريرين عن الأخطاء ( هنا وهناك ) بخصوص عملية التجميع. نعم ، هذا هو مقدار الجهد المبذول في بناء QTCreator فقط لاكتشاف أن مصحح الأخطاء في QTCreator لا يحتوي على واجهة برمجة تطبيقات عامة. عدت إلى خيار آخر ، وهو Visual Studio.

واتضح أن هذا هو القرار الصحيح: ليس لدى Visual Studio واجهة برمجة تطبيقات رائعة فحسب ، بل وثائق ممتازة له أيضًا. _debugger.GetExpression(...).Value تبسيط _debugger.GetExpression(...).Value التعبير _debugger.GetExpression(...).Value طريق استدعاء _debugger.GetExpression(...).Value . يوفر Visual Studio أيضًا القدرة على التكرار عبر الإطارات ، وتقييم التعبير في سياق أي منها. للقيام بذلك ، قم بتغيير الخاصية CurrentStackFrame إلى المطلوبة. يمكنك أيضًا تتبع تحديثات مسابقة مصحح الأخطاء لإعادة رسم الصورة عند التغيير.

بالطبع ، لم يكن من المفترض أن أشارك في تصور الرسوم البيانية من البداية - هناك الكثير من المكتبات الخاصة لهذا الغرض. أشهرها هو Graphviz ، وخططنا لاستخدامه في البداية. ولكن للحصول على مكون إضافي لبرنامج Visual Studio ، سيكون من المنطقي أكثر استخدام المكتبة لـ C # ، لأنني كنت سأكتب عليها. لقد غوغل قليلاً ووجدت مكتبة MSAGL : كان لديه كل الوظائف المطلوبة وله واجهة بسيطة وبديهية.

إثبات صحة مفهوم


الآن ، مع وجود آلية لحساب التعبيرات التعسفية من ناحية ومكتبة لتصور الرسوم البيانية من ناحية أخرى ، كان من الضروري إنشاء نموذج أولي. تم إنشاء النموذج الأولي الأول لـ DFS ، ثم خوارزمية Dinits ، وخوارزمية Kuhn ، والبحث عن المكونات ذات الارتباط المزدوج ، والشجرة الديكارتية ، و SNM تم أخذها كأمثلة. أخذت تطبيقاتي القديمة لهذه الخوارزميات من السنة الأولى إلى الثانية ، وقمت بإنشاء مكون إضافي جديد ، ورسمت رسم بياني يتوافق مع هذه المهمة (تم تغيير جميع أسماء المتغيرات). فيما يلي مثال على رسم بياني حصلت عليه لخوارزمية Kuhn:


على هذا الرسم البياني ، تظهر حواف المطابقة الحالية باللون الأرجواني ، ويظهر رأس dfs الحالي باللون الأحمر ، والرؤوس التي تمت زيارتها هي باللون الرمادي ، وحواف سلسلة بالتناوب ليست من المطابقة تظهر باللون الأحمر.

لقد اعتبرت أنه يجوز تعديل رمز الخوارزمية قليلاً لجعله أسهل في التصور. على سبيل المثال ، في حالة الشجرة الديكارتية ، اتضح أنه من الأسهل إضافة جميع العقد التي تم إنشاؤها إلى متجه بدلاً من تجاوز الشجرة داخل البرنامج المساعد.

تم اكتشاف غير سارة أن المصحح في Visual Studio لا يدعم أساليب الاتصال ووظائف من STL. هذا يعني أنه لم يكن من الممكن التحقق من وجود عنصر في الحاوية باستخدام std::find ، كما هو مفترض أصلاً. يمكن حل هذه المشكلة إما عن طريق إنشاء دالة معرفة من قبل المستخدم أو عن طريق تكرار الخاصية "العنصر موجود في الحاوية" في صفيف Boolean.

في الإضافات التجريبية ، حدث شيء مثل التالي (إذا تم تخزين الرسم البياني كقائمة مجاورة):

  1. أولاً تأتي حلقة for من 0 إلى _debugger.GetExpression("n").Value ، التي أضافت كل الرؤوس إلى الرسم البياني ، ولكل منها رقمه الخاص.
  2. ثم هناك نوعان متداخلان _debugger.GetExpression($"g[{i}].size()").Value ، الأول على i - من 0 إلى n ، والثاني على j - من 0 إلى _debugger.GetExpression($"g[{i}].size()").Value والحافة {i, _debugger.GetExpression($"g[{i}][{j}]").Value} .
  3. إذا لزم الأمر ، تمت إضافة بعض المعلومات الإضافية إلى ملصقات الرؤوس والحواف. على سبيل المثال ، قيمة المصفوفة d ، المسؤولة عن المسافة إلى القمة المحددة.
  4. إذا كانت الخوارزمية تستند إلى dfs ، فسوف يتم تمييز حلقة عبر كل الإطارات ، وسيتم stackFrame.FunctionName.Equals("dfs") && stackFrame.Arguments.Item(1) == v كل الرؤوس في الحزمة ( stackFrame.FunctionName.Equals("dfs") && stackFrame.Arguments.Item(1) == v ) باللون الرمادي.
  5. ثم ، بالنسبة لكل i من 0 إلى n ، تشير إلى أرقام الرؤوس ، تم التحقق من بعض الشروط ، وإذا كانت راضية ، فإن بعض الخصائص تتغير في الرأس ، وغالبًا ما يكون اللون.

في ذلك الوقت ، كتبت الرمز "حسب الضرورة" ، دون محاولة وضع مخطط عام لجميع الخوارزميات ، أو كتابة الرمز بطريقة جميلة على الأقل بطريقة ما. بدأ إنشاء كل مكون إضافي جديد بنسخ اللصق الخاص بالمادة السابقة.

التكوين الرسم البياني


بعد البحث ، كان من الضروري وضع مخطط عام يمكن تطبيقه على جميع الخوارزميات. أول ما تم تقديمه هو فهارس الرؤوس والحواف. كل فهرس له اسم فريد ونهايات النطاق ، محسوبة باستخدام _debugger.GetExpression . للوصول إلى قيمة الفهرس ، استخدم اسمه محاطًا بـ __ (أي __x__). تسمى التعبيرات التي تحتوي على أماكن لاستبدال قيم الفهرس ، وكذلك اسم الوظيفة الحالية (__CURRENT_FUNCTION__) وقيم الوسائط الخاصة بها (__ARG1__ ، __ARG2__ ، ...) ، القوالب.

يتم استبدال الفهارس لكل قمة أو حافة ، وبعد ذلك يتم حسابها في المصحح. تم استخدام القوالب لتصفية بعض قيم الفهرس (إذا تم تخزين الرسم البياني كمصفوفة قريبة c ، فستكون الفهارس a و b من 0 إلى n ، ويكون القالب الخاص بالتحقق هو c[__a__][__b__] ). حدود نطاق الفهرس هي أيضًا قوالب ، لأنها قد تحتوي على فهارس سابقة.

يمكن أن يحتوي الرسم البياني على أنواع مختلفة من الرؤوس والحواف. على سبيل المثال ، في حالة البحث عن الحد الأقصى للمطابقة في الرسم البياني ثنائي الأطراف ، يمكن فهرسة كل جزء على حدة. لذلك ، تم تقديم مفهوم الأسرة للرؤوس والحواف. لكل عائلة ، يتم تحديد الفهرسة وجميع الخصائص بشكل مستقل. في هذه الحالة ، يمكن للحواف توصيل الرؤوس من عائلات مختلفة.

يمكنك تعيين خصائص محددة لعائلة قمة أو حافة سيتم تطبيقها انتقائيًا على عناصر في العائلة. يتم تطبيق الخاصية إذا تم استيفاء الشرط. يتكون الشرط من قالب يتم تقييمه إلى true أو false ، وتعبير منتظم لاسم الوظيفة. يتم التحقق من الحالة إما فقط للإطار الزجاجي الحالي ، أو لجميع الإطارات الزجاجية (وبعد ذلك يتم الوفاء بها إذا كانت راضية عن إطار واحد على الأقل).

خصائص متنوعة جدا. للرؤوس: التسمية ، لون التعبئة ، لون الحدود ، عرض الحدود ، الشكل ، نمط الحدود (على سبيل المثال ، الخط المنقط). للحواف: التصنيف ، اللون ، العرض ، النمط ، الاتجاه (يمكنك تحديد سهمين - من البداية إلى النهاية أو العكس ؛ في هذه الحالة ، يمكن أن يكون هناك سهمان في نفس الوقت).

من المهم في كل مرة يتم فيها رسم الرسم البياني من نقطة الصفر ، ولا تؤخذ الحالة السابقة في الاعتبار بأي شكل من الأشكال. قد تكون هذه مشكلة إذا تغير الرسم البياني ديناميكيًا أثناء الخوارزمية - يمكن أن تتغير الرؤوس والحواف موضعها بشكل كبير ، ومن ثم يصعب فهم ما يحدث.

يمكن العثور على وصف تفصيلي لتكوين الرسم البياني هنا .

واجهة المستخدم


مع الواجهة ، قررت عدم عناء الكثير. تحتوي النافذة الرئيسية التي تحتوي على الإعدادات ( ToolWindow ) على textarea للتكوين المتسلسل في JSON وقائمة من العائلات العلوية والحافة. كل عائلة لديها نافذة خاصة بها مع الإعدادات ، ولكل خاصية في الأسرة نافذة واحدة أخرى (يتم الحصول على ثلاثة مستويات من التعشيش). يتم رسم الرسم البياني نفسه في نافذة منفصلة. لم ينجح الأمر في وضعه في ToolWindow ، لذا قمت بإرسال تقرير بالأخطاء إلى مطوري MSAGL ، لكنهم أجابوا أن هذه ليست حالة الاستخدام الهدف. تم إرسال تقرير خطأ آخر إلى Visual Studio ، حيث يتم تعليق TextBoxes أحيانًا في إطارات الإعدادات الإضافية.



المساعد


من أجل تكوين الرسم البياني ، يحتوي المكون الإضافي على واجهة مستخدم والقدرة على (إلغاء) إجراء تسلسل للتهيئة في JSON. المخطط العام للتفاعل بين جميع المكونات هو كما يلي:



يعرض اللون الأزرق المكونات التي كانت موجودة أصلاً ، باللون الرمادي - والتي قمت بإنشائها. عند بدء تشغيل Visual Studio ، تتم تهيئة الملحق (هنا يتم تعيين المكون الرئيسي كـ الرئيسي). يحصل المستخدم على الفرصة لتحديد التكوين من خلال الواجهة. في كل مرة يتم تغيير سياق المصحح ، يتم إعلام المكون الرئيسي. إذا تم تعريف التكوين وتم تنفيذ البرنامج الجاري تصحيحه ، يتم تشغيل GraphRenderer. يتلقى إدخال التكوين وبمساعدة مصحح أخطاء يقوم بإنشاء رسم بياني عليه ، ثم يتم عرضه في نافذة خاصة.

أمثلة


نتيجة لذلك ، قمتُ بإنشاء أداة تسمح لك بتصور خوارزميات الرسم البياني وتتطلب تغييرات صغيرة في الكود. تم اختباره على ثماني مهام مختلفة. فيما يلي بعض الصور الناتجة:


خوارزمية Ford-Bellman : يشار إلى قمة الرأس التي نحسب عليها أقصر الطرق من قبل المنزل ، أقصر مسافة حالية للقمم هي d ، والأحمر يشير إلى الحافة التي يمر بها الاسترخاء.


الرسوم المتحركة باستخدام DFS - تظهر قمة الرأس الحالية باللون الأحمر ، وتكون الرؤوس في المجموعة رمادية اللون ، والرؤوس التي تمت زيارتها الأخرى باللون الأخضر. ضلوع التوت تشير إلى اتجاه الالتفافية.

المزيد من خوارزميات العينة متاحة هنا.

حماية NIR


لحماية العمل البحثي ، يجب على الطلاب في سبع دقائق أن يخبروا عن عملهم لفصل دراسي. في الوقت نفسه ، بغض النظر عما إذا كان الموضوع قد تم اقتراحه كجزء من عرض العمل البحثي أو وجده الطالب بمفرده ، فأنت بحاجة إلى أن تكون قادرًا على الإجابة لتبرير لماذا يندرج موضوع المشروع تحت المتطلبات الموضحة في البداية. عادةً ما يتم تنظيم التقرير على النحو التالي: أولاً ، هناك الدافع ، ثم مراجعة النظائر ، ويقال عن سبب عدم تناسبنا ، ثم صياغة الأهداف والغايات ، ثم يتم وصف كل مهمة من المهام بالطريقة التي تم بها حلها. في النهاية هناك شريحة مع النتائج ، والتي تقول مرة أخرى أن الهدف قد تم تحقيقه ويتم حل جميع المهام.

نظرًا لأنني قررت بالفعل دوافع النظائر ومراجعتها في المرحلة الأولية ، فقد كنت بحاجة فقط لجمع كل المعلومات معًا وضغطها لمدة سبع دقائق. في النهاية ، نجحت ، وسار الدفاع بسلاسة ، وحصلت على أعلى درجة للبحث.

مراجع


Source: https://habr.com/ru/post/ar461473/


All Articles