GoGPT Best VPN GoSearch

OnWorks فافيكون

PDL::Threadingp - عبر الإنترنت في السحابة

قم بتشغيل PDL::Threadingp في موفر الاستضافة المجاني OnWorks عبر Ubuntu Online أو Fedora Online أو محاكي Windows عبر الإنترنت أو محاكي MAC OS عبر الإنترنت

هذا هو الأمر PDL::Threadingp الذي يمكن تشغيله في موفر الاستضافة المجاني OnWorks باستخدام إحدى محطات العمل المجانية المتعددة عبر الإنترنت مثل Ubuntu Online أو Fedora Online أو محاكي Windows عبر الإنترنت أو محاكي MAC OS عبر الإنترنت

برنامج:

اسم


PDL::Threading - برنامج تعليمي لميزة الترابط في PDL

مقدمة


واحدة من أقوى ميزات PDL هي خيوط، والتي يمكن أن تنتج مضغوطة جدًا و
رمز PDL سريع جدًا عن طريق تجنب حلقات for المتداخلة المتعددة التي قد يكون مستخدمو C وBASIC
مألوف. المشكلة هي أن الأمر قد يستغرق بعض الوقت للتعود عليه، وقد لا يحتاج المستخدمون الجدد إلى ذلك
نقدر فوائد الخيوط.

تستخدم اللغات الأخرى المعتمدة على المتجهات، مثل MATLAB، مجموعة فرعية من تقنيات الترابط، ولكن
يتألق PDL من خلال تعميمه بالكامل على جميع أنواع التطبيقات المعتمدة على المتجهات.

المصطلح: عبث


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

A عبث يتكون من سلسلة من الأرقام منظمة كمجموعة بيانات ذات أبعاد N. العبث
توفير تخزين فعال وحساب سريع للمصفوفات الكبيرة ذات الأبعاد N. هم
الأمثل للغاية للعمل العددي.

التفكير IN شروط OF خيط


إذا كنت قد استخدمت PDL لفترة قصيرة بالفعل، فربما كنت تستخدم الترابط بدونه
تحقيق ذلك. ابدأ تشغيل غلاف PDL (اكتب "perldl" أو "pdl2" على الجهاز الطرفي). معظم الأمثلة
في هذا البرنامج التعليمي، استخدم قذيفة PDL. تأكد من وجود PDL::NiceSlice وPDL::AutoLoader
ممكّن. على سبيل المثال:

%pdl2
بيرلدل شل v1.352

تم تمكين ReadLines وNiceSlice وMultiLines

ملاحظة: أداة التحميل التلقائي غير ممكّنة (يوصى بـ "استخدام PDL::AutoLoader")

pdl>

في هذا المثال، تم تمكين NiceSlice تلقائيًا، ولكن لم يتم تمكين AutoLoader. لتمكين
اكتب "استخدم PDL::AutoLoader".

لنبدأ مع ثنائي الأبعاد عبث:

pdl> $a = التسلسل(11,9)
pdl> p $ a
[
[ 0 1 2 3 4 5 6 7 8 9 10]
[11 12 13 14 15 16 17 18 19 20 21]
[22 23 24 25 26 27 28 29 30 31 32]
[33 34 35 36 37 38 39 40 41 42 43]
[44 45 46 47 48 49 50 51 52 53 54]
[55 56 57 58 59 60 61 62 63 64 65]
[66 67 68 69 70 71 72 73 74 75 76]
[77 78 79 80 81 82 83 84 85 86 87]
[88 89 90 91 92 93 94 95 96 97 98]
]

تمنحك طريقة "المعلومات" معلومات أساسية حول ملف عبث:

pdl> p $a->info
PDL: مزدوج D [11,9]

هذا يخبرنا أن $a هو 11 × 9 عبث تتألف من أرقام الدقة المزدوجة. اذا نحن
أراد إضافة 3 إلى كافة العناصر في "nxm"، فإن اللغة التقليدية ستستخدم اثنين
حلقات متداخلة:

# كود مزيف. الطريقة التقليدية لإضافة 3 إلى مجموعة.
لـ (x=0; x < n; x++) {
لـ (y=0; y < m; y++) {
أ(س،ص) = أ(س،ص) + 3
}
}

ملاحظات: لاحظ أن المؤشرات تبدأ من 0، كما هو الحال في Perl وC وJava (وعلى عكس MATLAB وIDL).

ولكن مع PDL، يمكننا فقط أن نكتب:

pdl> $b = $a + 3
pdf> ص $ب
[
[ 3 4 5 6 7 8 9 10 11 12 13]
[ 14 15 16 17 18 19 20 21 22 23 24]
[ 25 26 27 28 29 30 31 32 33 34 35]
[ 36 37 38 39 40 41 42 43 44 45 46]
[ 47 48 49 50 51 52 53 54 55 56 57]
[ 58 59 60 61 62 63 64 65 66 67 68]
[ 69 70 71 72 73 74 75 76 77 78 79]
[ 80 81 82 83 84 85 86 87 88 89 90]
[ 91 92 93 94 95 96 97 98 99 100 101]
]

هذا هو أبسط مثال على الترابط، وهو شيء تستخدمه جميع البرامج الرقمية
الأدوات تفعل. تم تطبيق العملية "+3" تلقائيًا على بعدين. لنفترض الآن
تريد طرح سطر من كل صف في $a:

pdf> خط $ = تسلسل(11)
pdl> ع $line
[0 1 2 3 4 5 6 7 8 9 10]
pdl> $c = $a - $line
pdf> ص $c
[
[ 0 0 0 0 0 0 0 0 0 0 0]
[11 11 11 11 11 11 11 11 11 11 11]
[22 22 22 22 22 22 22 22 22 22 22]
[33 33 33 33 33 33 33 33 33 33 33]
[44 44 44 44 44 44 44 44 44 44 44]
[55 55 55 55 55 55 55 55 55 55 55]
[66 66 66 66 66 66 66 66 66 66 66]
[77 77 77 77 77 77 77 77 77 77 77]
[88 88 88 88 88 88 88 88 88 88 88]
]

هناك شيئان يجب ملاحظتهما هنا: أولاً، قيمة $a لا تزال كما هي. حاول "p $a" للتحقق.
ثانيًا، قام PDL تلقائيًا بطرح سطر $ من كل صف في $a. لماذا فعلت ذلك؟ دعونا
انظر إلى أبعاد $a و$line و$c:

pdl> p $line->info => PDL: Double D [11]
pdl> p $a->info => PDL: Double D [11,9]
pdl> p $c->info => PDL: Double D [11,9]

لذا، فإن كلا من $a و $line لهما نفس عدد العناصر في البعد 0! ما PDL بعد ذلك
تم إجراء خيط فوق الأبعاد الأعلى في $a وكرر نفس العملية 9 مرات
جميع الصفوف في $a. هذا هو ترابط PDL قيد التنفيذ.

ماذا لو كنت تريد طرح $line من السطر الأول في $a فقط؟ يمكنك القيام بذلك عن طريق
تحديد السطر صراحة:

pdl> $a(:,0) -= $line
pdl> p $ a
[
[ 0 0 0 0 0 0 0 0 0 0 0]
[11 12 13 14 15 16 17 18 19 20 21]
[22 23 24 25 26 27 28 29 30 31 32]
[33 34 35 36 37 38 39 40 41 42 43]
[44 45 46 47 48 49 50 51 52 53 54]
[55 56 57 58 59 60 61 62 63 64 65]
[66 67 68 69 70 71 72 73 74 75 76]
[77 78 79 80 81 82 83 84 85 86 87]
[88 89 90 91 92 93 94 95 96 97 98]
]

راجع PDL::Indexing وPDL::NiceSlice لمعرفة المزيد حول تحديد مجموعات فرعية من التلاعبات.

تأتي القوة الحقيقية للخيوط عندما تدرك أن اللغز يمكن أن يحتوي على أي عدد من الخيوط
أبعاد! لنقم بعمل مجسم رباعي الأبعاد:

pdl> $piddle_4D = التسلسل (11,3,7,2)
pdl> $c = $piddle_4D - $line

الآن $c هو عبارة عن piddle بنفس البعد مثل $piddle_4D.

pdl> p $piddle_4D->info => PDL: Double D [11,3,7,2]
pdl> p $c->info => PDL: Double D [11,3,7,2]

هذه المرة، قام PDL بربط ثلاثة أبعاد أعلى تلقائيًا، مع طرح $line
طوال الطريق.

ولكن، ربما لا تريد الطرح من الصفوف (البعد 0)، ولكن من الأعمدة
(البعد 1). كيف يمكنني طرح عمود من الأرقام من كل عمود في $a؟

pdf> $cols = تسلسل(9)
pdl> p $a->info => PDL: Double D [11,9]
pdl> p $cols->info => PDL: Double D [9]

بطبيعة الحال، لا يمكننا كتابة "$a - $cols" فقط. الأبعاد غير متطابقة:

pdl> ف $a - $cols
PDL: PDL::Ops::minus(a,b,c): المعلمة 'b'
PDL: بُعد الخيط الضمني غير المتطابق 0: يجب أن يكون 11، وهو 9

كيف نخبر PDL أننا نريد الطرح من البعد 1 بدلاً من ذلك؟

المناورة الأبعاد


هناك العديد من وظائف PDL التي تتيح لك إعادة ترتيب أبعاد صفائف PDL. هم
مغطاة في الغالب بـ PDL::Slices. الثلاثة الأكثر شيوعًا هي:

xchg
mv
إعادة ترتيب

الطريقة: "xchg"
طريقة "xchg"التبادلات"بعدان في لغز:

pdl> $a = التسلسل(6,7,8,9)
pdl> $a_xchg = $a->xchg(0,3)

pdl> p $a->info => PDL: Double D [6,7,8,9]
pdl> p $a_xchg->info => PDL: Double D [9,7,8,6]
| |
VV
(خافت 0) (خافت 3)

لاحظ أنه تم تبادل الأبعاد 0 و3 دون التأثير على الأبعاد الأخرى.
لاحظ أيضًا أن "xchg" لا يغير $a. المتغير الأصلي $a يبقى دون تغيير.

الطريقة: "بالفيديو"
طريقة "mv" "التحركات"بعد واحد، في لغز، يتحول إلى أبعاد أخرى كما
ضروري.

pdl> $a = التسلسل (6,7,8,9) (خافت 0)
pdl> $a_mv = $a->mv(0,3) |
بدل> الخامس _____
pdl> p $a->info => PDL: Double D [6,7,8,9]
pdl> p $a_mv->info => PDL: Double D [7,8,9,6]
----- |
V
(خافت 3)

لاحظ أنه عند نقل البعد 0 إلى الموضع 3، يجب نقل جميع الأبعاد الأخرى
تحولت كذلك. لاحظ أيضًا أن "mv" لا يغير $a. يبقى المتغير الأصلي $a
لم يمسها.

الطريقة: "إعادة الترتيب"
طريقة "إعادة الترتيب" هي تعميم لطريقتي "xchg" و"mv". هو - هي "يعيد الطلب"
الأبعاد بأي طريقة تحددها:

pdl> $a = التسلسل(6,7,8,9)
pdl> $a_reorder = $a->reorder(3,0,2,1)
pdl>
pdl> p $a->info => PDL: Double D [6,7,8,9]
pdl> p $a_reorder->info => PDL: Double D [9,6,8,7]
| | | |
ف.ف.ف.ف
الأبعاد: 0 1 2 3

لاحظ ما حدث. عندما كتبنا "reorder(3,0,2,1)" طلبنا من PDL القيام بما يلي:

* ضع البعد 3 أولاً.
* ضع البعد 0 بعد ذلك.
* ضع البعد 2 بعد ذلك.
* ضع البعد 1 بعد ذلك.

عند استخدام طريقة "إعادة الترتيب"، يتم خلط كافة الأبعاد. لاحظ أن "إعادة الترتيب"
لا يغير $a. المتغير الأصلي $a يبقى دون تغيير.

مسكتك: الربط VS مهمة


ربط
بشكل افتراضي، pddles هي مرتبط سويا بحيث تعود التغييرات التي تطرأ على أحدهما وتؤثر على
أصلي as حسنا.

pdl> $a = التسلسل(4,5)
pdl> $a_xchg = $a->xchg(1,0)

هنا $a_xchg is ليست a مستقل موضوع. إنها مجرد طريقة مختلفة للنظر إلى $a. أي
سيظهر التغيير في $a_xchg في $a أيضًا.

pdl> p $ a
[
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
[12 13 14]
[16 17 18]
]
pdl> $a_xchg += 3
pdl> p $ a
[
[3 4 5 6]
[7 8 9 10]
[11 12 13]
[15 16 17]
[19 20 21]
]

مهمة
في بعض الأحيان، لا يكون الارتباط هو السلوك الذي تريده. إذا كنت تريد أن تجعل piddles
مستقل، استخدم طريقة "النسخ":

pdl> $a = التسلسل(4,5)
pdl> $a_xchg = $a->نسخ->xchg(1,0)

الآن أصبح $a و$a_xchg كائنين منفصلين تمامًا:

pdl> p $ a
[
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
[12 13 14]
[16 17 18]
]
pdl> $a_xchg += 3
pdl> p $ a
[
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
[12 13 14]
[16 17 18]
]
pdf> $a_xchg
[
[3 7 11 15 19]
[4 8 12 16 20]
[5 9 13 17 21]
[6 10 14 18 22]
]

وضع IT الجميع سويا


نحن الآن على استعداد لحل المشكلة التي حفزت هذه المناقشة بأكملها:

pdl> $a = التسلسل(11,9)
pdf> $cols = تسلسل(9)
pdl>
pdl> p $a->info => PDL: Double D [11,9]
pdl> p $cols->info => PDL: Double D [9]

كيف نطلب من PDL أن يطرح $cols على طول البعد 1 بدلاً من البعد 0؟ ال
أبسط طريقة هي استخدام طريقة "xchg" والاعتماد على ربط PDL:

pdl> p $ a
[
[ 0 1 2 3 4 5 6 7 8 9 10]
[11 12 13 14 15 16 17 18 19 20 21]
[22 23 24 25 26 27 28 29 30 31 32]
[33 34 35 36 37 38 39 40 41 42 43]
[44 45 46 47 48 49 50 51 52 53 54]
[55 56 57 58 59 60 61 62 63 64 65]
[66 67 68 69 70 71 72 73 74 75 76]
[77 78 79 80 81 82 83 84 85 86 87]
[88 89 90 91 92 93 94 95 96 97 98]
]
pdl> $a->xchg(1,0) -= $cols
pdl> p $ a
[
[ 0 1 2 3 4 5 6 7 8 9 10]
[10 11 12 13 14 15 16 17 18 19 20]
[20 21 22 23 24 25 26 27 28 29 30]
[30 31 32 33 34 35 36 37 38 39 40]
[40 41 42 43 44 45 46 47 48 49 50]
[50 51 52 53 54 55 56 57 58 59 60]
[60 61 62 63 64 65 66 67 68 69 70]
[70 71 72 73 74 75 76 77 78 79 80]
[80 81 82 83 84 85 86 87 88 89 90]
]

الإستراتيجية العامة:
انقل الأبعاد التي تريد العمل عليها إلى بداية بُعد الكملة الخاص بك
قائمة. ثم دع PDL يخيط على الأبعاد الأعلى.

EXAMPLE: كونواي لعبة OF حياة


حسنا، نظرية كافية. دعونا نفعل شيئًا أكثر إثارة للاهتمام: سنكتب كونواي لعبة Rocket League – CD Playstation
of الحياة في PDL وشاهد مدى قوة PDL!

ال لعبة Rocket League – CD Playstation of الحياة عبارة عن محاكاة يتم تشغيلها على شبكة كبيرة ثنائية الأبعاد. كل خلية في الشبكة
يمكن أن يكون حيًا أو ميتًا (ممثلًا بالرقم 1 أو 0). الجيل القادم من الخلايا في
يتم حساب الشبكة بقواعد بسيطة حسب عدد الخلايا الحية الموجودة فيها
الجوار المباشر:

1) إذا كانت الخلية الفارغة تحتوي على ثلاثة جيران بالضبط، يتم إنشاء خلية حية.

2) إذا كان للخلية الحية أقل من جارين فإنها تموت بسبب الإفراط في التغذية.

3) إذا كان للخلية الحية 4 جيران أو أكثر فإنها تموت جوعا.

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

كلاسيكي التنفيذ
وإليك طريقة كلاسيكية لكتابة هذا البرنامج في بيرل. نحن نستخدم PDL فقط للعنونة
الخلايا الفردية.

#!/ البيرة / بن / بيرل -w
استخدام PDL ؛
استخدم PDL::NiceSlice;

# اصنع لوحة للعبة الحياة.
بلدي $nx = 20؛
$ny = 20؛

# الجيل الحالي.
بلدي $a = أصفار($nx, $ny);

# الجيل القادم.
بلدي $n = أصفار($nx, $ny);

# ضع طائرة شراعية بسيطة.
$a(1:3,1:3) .= pdl ( [1,1,1],
[0,0,1]،
[0,1,0] );

لـ ($i = 0; $i < 100; $i++) {
$n = أصفار($nx, $ny);
$new_a = $a->نسخ;
لـ ($x = 0; $x < $nx; $x++) {
لـ ($y = 0; $y < $ny; $y++) {

# لكل خلية، انظر إلى الجيران المحيطين بها.
لـ ($dx = -1؛ $dx <= 1؛ $dx++) {
لـ ($dy = -1؛ $dy <= 1؛ $dy++) {
$px = $x + $dx;
$py = $y + $dy;

#التفاف حول الحواف.
إذا ($px < 0) {$px = $nx-1};
إذا ($py < 0) {$py = $ny-1};
إذا ($px >= $nx) {$px = 0};
إذا ($py >= $ny) {$py = 0};

$n($x,$y) .= $n($x,$y) + $a($px,$py);
}
}
# لا تحسب الخلية المركزية نفسها.
$n($x,$y) -= $a($x,$y);

# معرفة ما إذا كانت الخلية تعيش أو تموت:
# تعيش الخلية الميتة إذا كان n = 3
# تموت الخلية الحية إذا لم تكن n 2 أو 3
إذا ($أ($x,$y) == 1) {
إذا ($n($x,$y) < 2) {$new_a($x,$y) .= 0};
إذا ($n($x,$y) > 3) {$new_a($x,$y) .= 0};
{} آخر
إذا ($n($x,$y) == 3) {$new_a($x,$y) .= 1}
}
}
}

طباعة $أ؛

$a = $new_a;
}

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

الخيوط PDL التنفيذ
وهنا النسخة المترابطة في PDL. أربعة أسطر فقط من كود PDL، وواحد منها هو
طباعة أحدث جيل!

#!/ البيرة / بن / بيرل -w
استخدام PDL ؛
استخدم PDL::NiceSlice;

بلدي $a = أصفار (20,20،XNUMX)؛

# ضع طائرة شراعية بسيطة.
$a(1:3,1:3) .= pdl ( [1,1,1],
[0,0,1]،
[0,1,0] );

بلدي $ن؛
لـ ($i = 0; $i < 100; $i++) {
# حساب عدد الجيران لكل خلية.
$n = $a->range(ndcoords($a)-1,3,"دوري")->reorder(2,3,0,1);
$n = $n->sumover->sumover - $a;

# حساب الجيل القادم.
$a = ((($n == 2) + ($n == 3))* $a) + (($n==3) * !$a);

طباعة $أ؛
}

إصدار PDL المترابط أسرع بكثير:

الكلاسيكية => 32.79 ثانية.
مترابطة => 0.41 ثانية.

تفسير
كيف تعمل النسخة المترابطة؟

هناك العديد من وظائف PDL المصممة لمساعدتك في تنفيذ عملية ربط PDL. في هذا
على سبيل المثال، الوظائف الرئيسية هي:

الطريقة: "يتراوح"

على المستوى الأبسط، تعد طريقة "النطاق" طريقة مختلفة لتحديد جزء من ملف
عبث. بدلاً من استخدام الترميز "$a(2,3)"، نستخدم رمزًا آخر.

pdl> $a = التسلسل(6,7)
pdl> p $ a
[
[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16]
[18 19 20 21 22]
[24 25 26 27 28]
[30 31 32 33 34]
[36 37 38 39 40]
]
pdl> p $a->range( pdl [1,2] )
13
pdf> ص $a(1,2)
[
[13]
]

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

pdl> $index = pdl [ [[1,2],[2,3],[3,4],[4,5] ]
pdl> p $a->النطاق( $index )
[13 20 27]

بالإضافة إلى ذلك، يأخذ "النطاق" معلمة ثانية تحدد حجم القطعة
إرجاع:

دل> حجم $ = 3
pdl> p $a->range( pdl([1,2]) , $size )
[
[13]
[19]
[25]
]

يمكننا استخدام هذا لتحديد واحد أو أكثر من الصناديق 3x3.

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

pdl> p $ a
[
[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16]
[18 19 20 21 22]
[24 25 26 27 28]
[30 31 32 33 34]
[36 37 38 39 40]
]
دل> حجم $ = 3
pdl> p $a->range( pdl([4,2]) , $size , "دوري")
[
[16]
[22]
[28]
]
pdl> p $a->range( pdl([5,2]) , $size , "دوري")
[
[17]
[23]
[29]
]

لاحظ كيف يلتف الصندوق حول حدود اللغز.

الطريقة: "ندوكوردز"

الأسلوب "ndcoords" هو أسلوب ملائم يقوم بإرجاع قائمة تعدادية من
إحداثيات مناسبة للاستخدام مع طريقة "المدى".

pdl> p $piddle = التسلسل (3,3)
[
[0]
[3]
[6]
]
pdl> p ndcoords($piddle)
[
[
[0 0]
[1 0]
[2 0]
]
[
[0 1]
[1 1]
[2 1]
]
[
[0 2]
[1 2]
[2 2]
]
]

قد يكون هذا صعبًا بعض الشيء في القراءة. في الأساس تقول أن الإحداثيات لكل
يتم إعطاء العنصر في $piddle بواسطة:

(0,0) (1,0) (2,0)
(1,0) (1,1) (2,1)
(2,0) (2,1) (2,2)

الجمع بين "يتراوح" و "ندوكوردز"

ما يهم حقًا هو أن "ndcoords" مُصمم للعمل مع "range"، بدون أي شيء
$size المعلمة، يمكنك الحصول على نفس اللغز مرة أخرى.

pdl> p $piddle
[
[0]
[3]
[6]
]
pdl> p $piddle->range( ndcoords($piddle))
[
[0]
[3]
[6]
]

لماذا قد يكون هذا مفيدا؟ لأنه يمكننا الآن أن نطلب سلسلة من "الصناديق" للكل
عبث. على سبيل المثال، صناديق 2x2:

pdl> p $piddle->range( ndcoords($piddle) , 2 , "دوري")

من الصعب قراءة مخرجات هذه الوظيفة لأن "المربعات" موجودة على طول الأخيرين
البعد. يمكننا أن نجعل النتيجة أكثر قابلية للقراءة من خلال إعادة ترتيب الأبعاد:

pdl> p $piddle->range( ndcoords($piddle) , 2 , "دوري" )->reorder(2,3,0,1)
[
[
[
[0 1]
[3 4]
]
[
[1 2]
[4 5]
]

]

هنا يمكنك أن ترى ذلك بشكل أكثر وضوحا

[0 1]
[3 4]

هل المربع 2x2 يبدأ بالعنصر (0,0) الخاص بـ $piddle.

نحن لم ننتهي بعد. بالنسبة للعبة الحياة، نريد صناديق 3x3 من $a:

pdl> p $ a
[
[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16]
[18 19 20 21 22]
[24 25 26 27 28]
[30 31 32 33 34]
[36 37 38 39 40]
]
pdl> p $a->range( ndcoords($a) , 3 , "دوري" )->reorder(2,3,0,1)
[
[
[
[0 1 2]
[6 7 8]
[12]
]

]

يمكننا أن نؤكد أن هذا هو المربع 3x3 الذي يبدأ بالعنصر (0,0) الخاص بـ $a. لكن هناك
هي مشكلة واحدة. نريد في الواقع أن يكون الصندوق 3x3 مركز على (0,0،XNUMX). هذا ليس أ
مشكلة. ما عليك سوى طرح 1 من جميع الإحداثيات في "ndcoords($a)". تذكر أن
يعتني الخيار "الدوري" بجعل كل شيء يلتف حوله.

pdl> p $a->range( ndcoords($a) - 1 , 3 , "دوري" )->reorder(2,3,0,1)
[
[
[
[41]
[5 0 1]
[11]
]
[
[36]
[0 1 2]
[6 7 8]
]


نرى الآن مربعًا مقاس 3x3 به العنصر (0,0) في وسط المربع.

الطريقة: "سموفر"

تضيف طريقة "sumover" البعد الأول فقط. إذا طبقناها مرتين سنكون كذلك
إضافة جميع عناصر كل مربع 3x3.

pdl> $n = $a->range(ndcoords($a)-1,3,"دوري")->reorder(2,3,0,1)
pdf> ع $ن
[
[
[
[41]
[5 0 1]
[11]
]
[
[36]
[0 1 2]
[6 7 8]
]

pdl> p $n->sumover->sumover
[
[144 135 144 153 162]
[ 72 63 72 81 90 81]
[126 117 126 135 144]
[180 171 180 189 198]
[234 225 234 243 252]
[288 279 288 297 306]
[216 207 216 225 234]
]

استخدم الآلة الحاسبة للتأكد من أن 144 هو مجموع كل العناصر الموجودة في المربع 3×3 الأول
و135 هو مجموع كل العناصر الموجودة في المربع الثاني 3×3.

عد الجيران

نحن على وشك الانتهاء!

إن إضافة كافة العناصر في مربع 3x3 ليس كذلك تماما ماذا نريد. لا نريد العد
مربع المركز. لحسن الحظ، هذا حل سهل:

pdl> p $n->sumover->sumover - $a
[
[144 134 142 150 158]
[ 66 56 64 72 80 70]
[114 104 112 120 128]
[162 152 160 168 176]
[210 200 208 216 224]
[258 248 256 264 272]
[180 170 178 186 194]
]

عند تطبيقه على لعبة الحياة لكونواي، سيخبرنا هذا بعدد الجيران الأحياء لكل منهم
تحتوي الخلية على:

pdl> $a = أصفار (10,10)
pdl> $a(1:3,1:3) .= pdl ( [1,1,1],
..( > [0,0,1],
..( > [0,1,0] )
pdl> p $ a
[
[0 0 0 0 0 0 0 0 0]
[0 1 1 1 0 0 0 0 0]
[0 0 0 1 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
]
pdl> $n = $a->range(ndcoords($a)-1,3,"دوري")->reorder(2,3,0,1)
pdl> $n = $n->sumover->sumover - $a
pdf> ع $ن
[
[1 2 3 2 1 0 0 0 0]
[1 1 3 2 2 0 0 0 0]
[1 3 5 3 2 0 0 0 0]
[0 1 1 2 1 0 0 0 0]
[0 1 1 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
]

على سبيل المثال، يخبرنا هذا أن الخلية (0,0) بها جار حي واحد، بينما الخلية (1) بها 2,2 جيران حي
الجيران الأحياء.

حساب القادم التالي جيل

عند هذه النقطة، يحتوي المتغير $n على عدد الجيران الأحياء لكل خلية. الآن نحن
تطبيق قواعد لعبة الحياة لحساب الجيل القادم.

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

pdl> p ($n == 3)
[
[0 0 1 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0]
[0 1 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
]

احصل على قائمة بـ فارغ الخلايا التي لها ثلاثة جيران بالضبط:

pdl> p ($n == 3) * !$a

إذا كان للخلية الحية أقل من 2 أو أكثر من 3 جيران، فإنها تموت.
احصل على قائمة بالخلايا التي تحتوي على 2 أو 3 جيران بالضبط:

pdl> ص (($n == 2) + ($n == 3))
[
[0 1 1 1 0 0 0 0 0]
[0 0 1 1 1 0 0 0 0]
[0 1 0 1 1 0 0 0 0]
[0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
]

احصل على قائمة بـ الذين يعيشون الخلايا التي لها بالضبط 2 أو 3 جيران:

pdl> p (($n == 2) + ($n == 3)) * $a

وبجمع كل ذلك معًا، فإن الجيل القادم هو:

pdl> $a = ((($n == 2) + ($n == 3)) * $a) + (($n == 3) * !$a)
pdl> p $ a
[
[0 0 1 0 0 0 0 0 0]
[0 0 1 1 0 0 0 0 0]
[0 1 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0]
]

علاوة الميزة: الرسومات!
إذا كان لديك PDL::Graphics::TriD مثبتًا، فيمكنك إنشاء نسخة رسومية من البرنامج
بمجرد تغيير ثلاثة أسطر:

#!/ البيرة / بن / بيرل
استخدام PDL ؛
استخدم PDL::NiceSlice;
استخدم PDL::Graphics::TriD;

بلدي $a = أصفار (20,20،XNUMX)؛

# ضع طائرة شراعية بسيطة.
$a(1:3,1:3) .= pdl ( [1,1,1],
[0,0,1]،
[0,1,0] );

بلدي $ن؛
لـ ($i = 0; $i < 100; $i++) {
# حساب عدد الجيران لكل خلية.
$n = $a->range(ndcoords($a)-1,3,"دوري")->reorder(2,3,0,1);
$n = $n->sumover->sumover - $a;

# حساب الجيل القادم.
$a = ((($n == 2) + ($n == 3))* $a) + (($n==3) * !$a);

# عرض.
nokeeptwiddling3d();
إيماجرغب [$a];
}

ولكن إذا أردنا حقًا رؤية شيء مثير للاهتمام، فيجب علينا إجراء بعض التغييرات الإضافية:

1) ابدأ بمجموعة عشوائية من 1 و0.

2) جعل الشبكة أكبر.

3) أضف مهلة صغيرة حتى نتمكن من رؤية اللعبة تتطور بشكل أفضل.

4) استخدم حلقة while حتى يتمكن البرنامج من العمل طالما يحتاج إلى ذلك.

#!/ البيرة / بن / بيرل
استخدام PDL ؛
استخدم PDL::NiceSlice;
استخدم PDL::Graphics::TriD;
استخدام الوقت::HiRes qw(usleep);

$a = عشوائي(100,100);
$أ = ($أ < 0.5)؛

بلدي $ن؛
بينما (1) {
# حساب عدد الجيران لكل خلية.
$n = $a->range(ndcoords($a)-1,3,"دوري")->reorder(2,3,0,1);
$n = $n->sumover->sumover - $a;

# حساب الجيل القادم.
$a = ((($n == 2) + ($n == 3))* $a) + (($n==3) * !$a);

# عرض.
nokeeptwiddling3d();
إيماجرغب [$a];

# النوم لمدة 0.1 ثانية.
انت نائم(100000)
}

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


الاستراتيجية العامة هي: تحرك القادم الأبعاد لصحتك! تريد إلى طريقة التوسع on إلى القادم بداية of لك
بيدل بعد قائمة. ثم اسمحوا PDL خيط على مدى القادم أعلى الأبعاد.

يعد Threading أداة قوية تساعد في التخلص من حلقات for ويمكن أن تجعل التعليمات البرمجية الخاصة بك أكثر
مختصرا. نأمل أن يوضح هذا البرنامج التعليمي سبب أهمية التعامل مع الخيوط
في بدل.

حقوق الطبع والنشر


حقوق الطبع والنشر 2010 ماثيو كينورثي ([البريد الإلكتروني محمي]) ودانييل كاريرا
([البريد الإلكتروني محمي]). يمكنك توزيع و/أو تعديل هذا المستند بموجب نفس الشروط
مثل ترخيص بيرل الحالي.

انظر: http://dev.perl.org/licenses/

استخدم PDL::Threadingp عبر الإنترنت باستخدام خدمات onworks.net


خوادم ومحطات عمل مجانية

قم بتنزيل تطبيقات Windows و Linux

أوامر لينكس

Ad




×
الإعلانات
❤️تسوق أو احجز أو اشترِ هنا - بدون تكلفة، مما يساعد على إبقاء الخدمات مجانية.