برنامه نویسی توارثی در ++ C
برنامه نویسی توارثی در ++ C – ایران ترجمه – Irantarjomeh
مقالات ترجمه شده آماده گروه کامپیوتر
مقالات ترجمه شده آماده کل گروه های دانشگاهی
مقالات
قیمت
قیمت این مقاله: 48000 تومان (ایران ترجمه - Irantarjomeh)
توضیح
بخش زیادی از این مقاله بصورت رایگان ذیلا قابل مطالعه می باشد.
شماره | ۱ |
کد مقاله | COM01 |
مترجم | گروه مترجمین ایران ترجمه – irantarjomeh |
نام فارسی | برنامه نویسی توارثی در ++ C : موارد اجرایی |
نام انگلیسی | Genetic Programming in C ++ : Implementation Issues |
تعداد صفحه به فارسی | ۴۴ |
تعداد صفحه به انگلیسی | ۲۹ |
کلمات کلیدی به فارسی | برنامه نویسی توارثی، ++ C |
کلمات کلیدی به انگلیسی | |
کشور |
برنامه نویسی توارثی در C++ موارد اجرایی
هدف از تحقیق جاری بررسی طرح و اجرای پلتفرم برنامهنویسی توارثی در C++، به همراه تمرکز اولیه بر کارایی و انعطاف پذیری مربوطه میباشد. در این فصل ما ویژگیهای اجرایی سطح پایین چنین پلتفرمی، علیالخصوص مفسر توارثی، را بررسی مینمائیم. این حقیقت که برنامه نویسی توارثی ار نظر محاسباتی عملی پرهزینه و گران محسوب میگردد، بدان معناست که کارایی کلی پلتفرم در زمان و حافظه حیاتی و مهم میباشد. بویژه، نماد گرهای یکی از قسمتهای اصلی اجرایی بوده که در آن اورهد (مقدار پردازش مورد نیاز برای اتمام پروسه) مورد توجه قرار خواهد گرفت. ما در ابتدا چندین روش ذخیره توپولوژی یا جانمایی درختی را مورد مقایسه قرار میدهیم. موثرترین نماد همهجانبه در این زمینه روشی میباشد که در آن درختچه برنامه دارای آرایه خطی از گرهها با نظم پیشوندی، در مقابل ساختار درختی بر مبنای اشارهگر، میباشد. ما این امر را با دیگر معرفها یا نمادهای خطی، اکثرا بصورت پسوندی و قراردهی دلخواه توابع و آرگومانهای آن، مورد توجه قرار میدهیم. پس از آن توجه ما بر چگونگی معرفی آنکه کدام تابع یا ترمینال معرف هر گره میباشد معطوف شده و همچنین روش بسیار موثر ارائه یک بایت به دو بایت را نشان میدهیم. در نهایت ما این دیدگاهها را با هم ترکیب نموده و یک دیدگاه جدول پیشوند / پرش یا جست (PJT)، که موجب اورهد بسیار کوچکی در گره هم در زمان و هم در فضا در مقایسه با موارد دیگری که مطالعه نمودهایم میشود، را پیشنهاد مینمائیم. علاوه بر کارایی داشتن، مفسر ما بسیار انعطاف پذیر میباشد. نهایتا، ما روشها و دیدگاههایی را به منظور اداره نمودن جریان کنترل یک برنامه، کپسوله سازی، بازگشت و برنامه نویسی موازی شبیه سازی شده ارائه مینمائیم.
برنامه نویسی توارثی در ++ C
مقدمه
در این فصل ما موارد اجرایی سطح پایین که آن را بنام مفسر توارثی میخوانیم را مورد بررسی قرار میدهیم. برای این منظور از کدهای نمونه پنج برنامه تست جهت ارزیابی عملکرد استفاده نمودیم. بخش ۸/۱۳ نتایج بدست آمده از این تست را خلاصه نموده و موارد جایگزین شامل شده را در هر عملیات اجرایی مورد بحث قرار میدهد.
برای مباحث آتی، چیزی که ما آن را بعنوان مفسر میخوانیم مشخص کننده ویژگیهای سطح پایین طرح بشرح ذیل میباشد:
نماد گره خام
چگونگی معرفی گرههای درختی
روش ارزیابی گره منفرد
روش ارزیابی درخت بصورت کلی
روشهایی برای (کمک به) اپراتورهای توارثی که متکی به نماد گرهای یا درختچهای میباشند.
نکته کلیدی آن است که مفسر اجرای گرهی را مشخص مینماید که بعنوان بخش خاص کدینگ ـ پلتفرمی باشد که در آن اورهد مورد بزرگنمایی قرار گرفته است. بنابر این، مفسر یکی از مهمترین و اساسی ترین ترکیبات یا اجزای طراحی همهجانبه، با توجه به کارایی فضا / زمان بشمار میآید.
به منظور نشان دادن شدت بزرگ نمایی گره، به یک برنامه کاربردی توجه نمائید که اندازه جمعیتی M ۲۰۰۰ برنامه را بکار برده است و در آن اندازه میانگین سطح هر یک از درختچههای برنامه منفرد مشتمل بر ۲۰۰ گره میگردد. همچنین به یک سناریوی معمولی توجه کنید که در آن، به منظور برقرار نمودن تناسب هر برنامه، میبایست بیش از ۲۰ مورد تست به اجرا گذاشته شود (در این خصوص اجازه دهید تا C تعداد تستهای مورد نیاز باشد). بنابر این، برای هر نسل، مجموع کل گرههایی که میبایست Np را پردازش نموده و Ns را ذخیره نمایند عبارتند از:
Np = M Pave C = 8,000,000 (Equation 13.1)
Nf = M Pave = 400,000
برای برنامههای سختتر، فاکتور بزرگنمایی حداقل به میزان فاکتور درجه دوم افزایش مییابد، چرا که هم اندازه برنامه و هم اندازه جمعیتی میبایست افزایش یابد.
برنامه نویسی توارثی در ++ C
کاربردهایی بر مبنای اشارهگر
کوزا (۱۹۹۲) و تکت (۱۹۹۳) کاربردهایی بر مبنای اشارهگر برای استفاده در برنامه نویسی کلی، که در آن هر برنامه یک درخت تجزیه بوده و هر گره دارای یک اشارهگر به هر چایلد (یک رکورد داده که تنها با توجه به محتوای رکورد دیگر میتواند ایجاد شود) یا هر ورودی میباشد، را پیشنهاد نمودند. این دیدگاه سنتی برای معرفی ساختار درختی، معمولا بصورت زیر در C کد میشود:
…
دیدگاه پسوندی، بر اساس پشته
ما هم اکنون دیدگاهی را بر اساس پشته معرفی مینمائیم که در آن هر تابع و ترمینال مسئول بدست آوردن آرگومانهای خود (در صورت وجود) بوسیله برداشتن آنها از پشته و نشاندن خروجی واحد آن در پشته میباشد. این روتین، مشابه زبان برنامهنویسی فورت (FORTH) است. به ۷ گره برنامه زیر توجه کنید :
Postfix: a b + c d – + Infix: (a+b) + (c-d)
قرارداد پشتهای که هماکنون تشریح گردید مهیا کننده ارتباط ضمنی بین گرهها میباشد. بطور مثال، گره ترمینال a مقدار خود را در پشته خالی مینشاند، پس از آن b نیز همین کار را انجام میدهد. در این مرحله، پشته شامل دو ارزش میباشد و b در راس قرار خواهد داشت. گره + نیز پس از آن دو مقدار دیگر را مینشاند (در این مثال a و b)، و سپس آنها را اضافه نموده و نتایج را به پشته برمیگرداند. این ارتباط ضمنی به ما اجازه میدهد تا آنکه بتوانیم اشارهگرهای Arg را که در کاربردهای بر مبنای اشارهگر بدانها نیاز بود را حذف نموده و کل برنامه را بعنوان آرایهای از گرهها مثل زیر ذخیره نمائیم:
…
برنامه نویسی توارثی در ++ C
کارایی حافظه
استفاده از آرایههای اندازه ثابت جهت نگهداری ژنومهای با اندازه- متغیر میتواند بطور آشکاری باعث بوجود آمدن میزان مشخصی از فضای بدون استفاده شود. بنابر این، با وجود آنکه هر گره در طرح ارتباط – ضمنی تنها میتواند ۲ بایت را نگهداری نماید، اندازه گره موثر (Se) بزرگتر از اندازه واقعی گره (Sa) در مقایسه با میانگین فضای آرایه استفاده نشده (Uave) و میانگین اندازه ژنوم (Gave) میباشد:
…
کار با برنامههای پسوندی
جهت انجام درست اپراتورهای GP سنتی، ما باید اطمینان داشته باشیم که پس از راهاندازی، تمرکز نخستین بر روی کار و اعمال تغییرات، دارای نماد معتبری از درخت هستیم. اساس الگوریتمهای زیر، استفاده از کل مجموع اقلام موجود در هر گره میباشد، تا اجازه دهیم که دستور دارای چسبندگی و تناسب لازم باشد.در این نقطه میبایست ذکر نمود که از آنجایی که هیچ یک از این عملیات به هنگام محاسبه تناسب لازم به اجرا در نمیآیند، کارایی آنها بطور کل جزء موارد اصلی مد نظر ما بشمار نمیرود.
آغاز یا راهاندازی پسوند
ما میتوانیم یک آرایه خط گرهها را بعنوان درخت ضمنی، در حالت بازگشتی مشابه با آغاز درختهای بر مبنای اشارهگر، راهاندازی و آغاز نمائیم. یکی از فرقها در این خصوص آن است که علاوه بر محدودیت MaxDepth، به محدودیت اندازه درخت ضمنی و عدم بزرگتر بودن آن از اندازه آرایه ژنوم نیاز میباشد. این مورد را میتوان با داشتن یک پارامتر، که شمارش تعداد براکتهای باز را بعهده دارد، انجام داد و آن را بصورت زیر مورد استفاده قرار داد :
…
تمرکز پسوندی
قاعده طلایی ما، که موجب جمع StackCount به ۱ بر هر عبارت پسوند مجاز میگردد، را میتوان به زیردرخت نیز تعمیم داد. این بدان معنا میباشد که چنانچه یک مورد در هر نقطه X بر روی عبارت پسوندی شروع گردد و جمع آن بسمت چپ تا نقطه Y، جائیکه StackCount در ابتدا ۱ شده بود، ادامه یابد، پس نقاط X و Y زیردرختی را که گره ریشه آن X باشد را پوشش میدهد. توجه داشته باشید که ترمینالها زیردرختی به اندازه یک را بوجود آورده و بصورت میانگین اغلب بیشترین زیردرختان تبادلی را تشکیل میدهند.
…
جهش پسوندی
جهش را میتوان بعنوان بخشی از روشهای راهاندازی و کراساور بکار برد. ما یک زیردرخت را جهت جایگزینی انتخاب میکنیم، همانگونه که در مورد کراساور انجام میدهیم و سپس یک زیردرخت را درست مانند آنچه در راهاندازی انجام میدهیم تولید مینمائیم. در نهایت، ممکن است نیاز پیدا کنیم تا قسمتی از بخش غیر جهشی را شیفت داده تا آنکه برای موارد جهشی جا باز نمائیم.
مشکل کنترل جریان با پسوند
مشکل اصلی با طرح مرتبه پسوندی عدم توانایی آن جهت اداره جریان کنترل میباشد. مشکل غامض آشکار در خصوص پسوند، آرگومانهای یک تابع میباشند که معمولا قبل از خود تابع اجرا میشوند. این مسئله عدم اجرای زیرعبارات شرطی که میخواهیم آن را نادیده انگاشته یا اسکیپ کنیم را غیر ممکن میسازد.
ترکیب وند
راهی وجود دارد که از طریق آن میتوان از اجرای بخشهای درخت ممانعت نمود. برای این امر میبایست نیازهای مقادیر توابع دریافت برگشت به پشته را مرتفع نمود. ما بسادگی اجازه میدهیم تا برخی از توابع مشخص محاسبات دلخواه را بین آرگومانهای ارزیابی اجرا نموده، و از نتایج این محاسبات جهت تصمیم گیری از آنکه آیا زیردرخت بعدی را ارزیابی و یا رد کنیم استفاده مینمائیم. مرتبه هیبرید را در نظر بگیرید که آن را ترکیب وند خوانده و در آن آرگومانهای ساختارهای کنترل جریان با کدی که برای فانکشن حقیقی در نظر گرفته شده گسترده گردیدهاند. بطور مثال کدینگ زیر :
…
برنامه نویسی توارثی در ++ C
مرتب سازی پیشوندی
ما دریافتیم که بهترین روش جهت حل مشکل کنترل جریان بصورت طبیعی در حالی که از مزیت کارایی حافظه برای کاربردهای خطی سود میبریم، استفاده از مرتب سازی پیشوندی در یک آرایه ژنوتایپ (با مشخصات برابر توارثی) میباشد. طرح مرتب سازی پیشوندی دارای ۳ مزیت بر نوع پسوندی آن میباشد:
آرگومانها میبایست بصورت صریح بوسیله والدین خود، که اجازه کنترل ساختارها را برای اجرا در یک حالت طبیعی میدهند، مورد ارزیابی قرار گیرند.
کدینگی که نیاز به جست از یک زیردرخت دارد کاملا ساده بوده و نیازی به مکانیزمهای خاص که قبلا در بخش ترکیب وند تشریح گردید ندارند.
نیازی به مکانیزم صریح پشته نمیباشد، که خود باعث کاهش پیچیدگی و کاهش اورهد عملکرد میشود.
ما اجرا را از طریق آرایه کرموزوم بازگشتی مانند زیر خواهیم داشت :
…
راه اندازی، تقاطع و جهش با پیشوند
طرح ترتیب پیشوند اجازه میدهد تا دستور در یک روش اساسی مشترک مانند دوز پسوند نگهداری گردد. این بدان معناست، که با مجموع هر گره منهای یک، و جمع نمودن از چپ به راست، جمع کل میبایست مساوی منهای یک باشد تا عبارت پیشوند معتبر شود.
اداره نمودن جریان برنامه با پیشوند
در این بخش ما راههای گوناگون برای اداره نمودن جریان برنامه در طرح پیشوندی را مورد برسی قرار میدهیم. ایده اساسی کاربرد روتین EvalNextArg() جهت ارزیابی آرگومانها و SkipNextArg() جهت جهش در یک آرگومان بدون ارزیابی آن میباشد. این روتین در زیر نشان داده شده است :
…
ارائه گره
تا بحال، ما تنها چگونگی ارائه توپولوژی درخت را نشان داده ایم و کمتر به مسئله کاربرد تابع اشارهگر جهت ارائه اطلاعات مورد نیاز جهت ارزیابی گره پرداختهایم. در این بخش، ما دیدگاه خود را در خصوص ارائه یک گره بیان میداریم.
پشتیبانی داده عمومی
این ایده را میتوان از دنبال کردن مشاهدات ساده دریافت. چنانچه ۲۵۶ نوع از انواع مختلف گره وجود داشته باشد (توابع و ترکیبهای ترمینالها، هر ثابت بعنوان انواع مختلف گره در نظر گرفته شود)، بنابر این ما تنها از یک بایت برای معرفی گره استفاده کردهایم. این بایت را میتوان بعنوان ایندکس به آرایه اطلاعات شامل نوع اشارهگر تابع، مجموع آن، نام و غیره بکار برد. تابع اشاره شده به آن را بنام هندلر و آرایه آن را جدول جست و کل ورودی برای یک نوع از گره را نشانه میخوانیم، که بوسیله کلاس نشانه مشخص میگردد:
…
فرمت آپکد (رمزالعمل)
برای یک کاربرد با دو متغیر ممیز اعشار و ثابتهای از قبل تعریف شده بسیار، جائیکه یک بایت نیز ممکن است عملی گردد، میتوان جدول ـ جست را بشکل ذیل تعریف نمود:
توابع (۱۵-۰)، متغیرهای (۱۷-۱۶)، ثابتهای (۲۵۵-۱۸)
توجه داشته باشید که در این طرح، اشارهگر هندلر ثابت در محدوده آن تکرار شده و مقدار گره را جهت تعیین آنکه کدام ثابت مورد نیاز است بررسی مینماید. برای جزئیات بیشتر، مورد زیر را ببینید :
…
برنامه نویسی توارثی در ++ C
مکانیزم جدول جهش
مکانیزم جدول جهش ما بسادگی آرایهای از آبجکتهای نشانه میباشد. مزیت اصلی چنین جدول جهشی آن است که هم اکنون میتوانیم انتخاب کنیم که کدام تابع را با حذف ارجاع آرایه، در مقابل جمله case، اجرا کنیم. با وجود آنکه کامپایلرها معمولا یک عبارت case را در چنین جدول جهشی کمپایل مینمایند، عمل کنترل محدودیت در ایندکس انجام شده و همچنین سرعت آن در مقایسه با جدول جهشی کد دستی کمتر خواهد بود. چنانچه current-node به یک آبجکت node اشاره کند و token ها به آرایه آبجکتهای token اشاره کنند، پس EvalNextArg() را میتوان با عبارت زیر اجرا نمود:
…
دیدگاه پیشوند، جدول- جهشی (PJT)
ما تصور میکنیم که بهترین حالت اجرای همه جانبه مفسرهای ژنوم استفاده از این ۴ مفهوم کلیدی باشد: طرح مرتبسازی پیشوندی، پشتیبانی داده عمومی، ارائه گره ۲ بایتی و مکانیزم جدول – جهش. این یک دیدگاه بهترین و عالیترین دیدگاه مادولهای میباشد، چرا که بینیاز از کاربرد عبارت case جهت تعیین نوع گره است. این مورد دارای بیشترین میزان انعطاف پذیری بوده، چرا که بطور طبیعی کلیه ساختارهای کنترل جریان را اداره مینماید. در نهایت، علاوه بر صفات قبلی، این موثرترین دیدگاه در خصوص اورهد گره، فضا / زمان میباشد. بر این اساس، یک طراح مربوطه میتواند گواهی دهد که ما کاملا خوششانس میباشیم که چنین برگ برنده آشکاری را در اختیار داریم.
…
برنامه نویسی توارثی در ++ C