بخشی از مقاله

الگوريتم ژنتيك در زبان برنامه نويسي c++
چكيده
علم ژنتيك، علمي است كه به تازگي وارد علوم كامپيوتر شده و با استفاده از اجزا مورد نياز ژنتيك و شبيه سازي آن در كامپيوتر، انسان را قادر مي سازد تا بعضي از مسائل مختلف و پيچيده اي كه در اوايل حل نشدني بودند، را حل كند.
اين مستند، يك كتابخانه از اشيا الگوريتم ژنتيك به زبان c++ مي باشد. اين كتابخانه شامل ابزاريست كه براي بهبود هر برنامه اي به زبان c++ و هر خروجي و هر عملگر ژنتيكي، استفاده مي شوند. در اينجا، با پياده سازي الگوريتم ژنتيك، رابط برنامه نويسي آن و اشكالي براي راهنمايي، آشنا خواهيد شد.

مقدمه
اين مستند محتويات كتابخانه الگوريتم ژنتيك را رمز بندي مي كند و بعضي از فلسفه هاي طراحي را كه در پشت پياده سازي هستند، نمايش مي دهد. بعضي از مثال هاي كد منبع در آخر صفحه مشخص شده تا ساختار اصلي برنامه، توانايي هاي عملگرها، تطابق عملگرها با نياز كاربر و مشتقاتي از كلاس هاي جديد مجموعه ژن را نمايش بدهند. وقتي كه شما از يك كتابخانه استفاده مي كنيد به صورت ابتدايي با دو نوع كلاس كار مي كنيد الگوريتم مجموعه ژن و الگوريتم ژنتيك. هر نمونه اي از مجموعه ژن يك راه حل براي مسئله شما نشان مي دهد. شي الگوريتم ژنتيك توضيح مي دهد كه چگونه سير تكامل بايد طي شود. الگوريتم ژنتيك از يك تابع عضو شي اي كه توسط شما تعريف شده است استفاده مي كند تا معين كند چگونه هر مجموعه ژن براي زنده ماندن مناسب است؟
الگوريتم ژنتيك از عملگر هاي مجموعه ژن ( كه در داخل مجموعه هستند) و استراتژي هاي انتخاب/ جايگزيني ( كه در داخل الگوريتم ساخته مي شود ) براي توليد يك مجموعه ژن جديد مجزا ، استفاده مي كند.


سه چيز براي حل مسئله با استفاده از الگوريتم ژنتيك وجود دارد :
1. تعريف خروجي هاي كه نشان داده ميشوند
2. تعريف عملگر هاي ژنتيكي
3. تعريف تابع عضو شي را

GALIB (كتابخانه الگوريتمهاي ژنتيك ) به شما در دومورد اول به وسيله مهيا كردن مثال هاي زياد وتكه برنامه هايي كه شما مي توانيد ، خروجي ها و عملگر هاي خود را بسازيد كمك مي كند . در خيلي از موارد شما مي توانيد از ساختار خروجي ها و عملگر ها با كمي يا هيچ اصلاحي استفاده كنيد . تابع عضو شي كاملا به شما مربوط مي شود .


در صورتي كه شما خروجي ها ، عملگرها و موارد شي را داشته باشيد ، مي توانيد هر كدام از الگوريتم هاي ژنتيك را براي پيدا كردن راه حل بهتر و مناسبتر براي مسئله تان به كار بگيريد. موقعي كه شما از الگوريتم ژنتيك براي حل يك مشكل بهينه استفاده مي كنيد، بايد قادر باشيد كه يك راه حل براي مسئله در يك ساختمان داده ارائه بدهيد . الگوريتم ژنتيك يك جمعيت از راه حل هايي كه بر طبق نمونة ساختمان دادهايي كه به وجود آورده ايد، ايجاد مي كند . بعد الگوريتم ژنتيك بر روي اين جمعيت عمل

مي كند تا بهترين راه حل را ازآن استخراج كند.در GALIB كتابخانه الگوريتم ژنتيك به نمونة ساختمان داده GAGENOME گفته مي شود (بعضي ها به آن كروموزوم نيز مي گويند ). اين كتابخانه شامل چهار نوع از اين مجموعه هاست GALISTGENOME ( ليست پيوندي مجموعه ژن)GATREEGAGENOME (درخت مجموعه ژن) GAARRYGENOME( آرايه مجموعه ژن) GABINARYSTRINGGENOME(رشته دودويي مجموعه ژن). اين كلاس ها از كروموزوم يا كلاس GAGENOME اصلي و يك كلاس ساختمان داده اي كه بوسيله نامشان مشخص شده اند، مشتق شده اند.


براي مثال ليست پيوندي مجموعه ژن از كلاس GALIST و همچنين كلاس مجموعه ژن GAGENOME مشتق شده است. از ساختمان داد ه اي كه با تعريفات مسئله شما همخواني دارد، استفاده كنيد. براي مثال ، اگر شما سعي مي كنيد كه يك تابعي را بهينه سازي كنيد كه به پنج عدد حقيقي وابسته است ، پس به عنوان مجموعه ژن خود از يك آرايه يك بعدي با پنج عنصر اعشاري استفاده كنيد.


الگوريتم هاي ژنتيك مختلف زيادي وجود دارند. GALIB (كتابخانه الگوريتم ژنتيك) شامل سه نوع اصلي مي باشد:
1. حالت ساده
2. حالت ساكن يا ثابت يا يكنواخت
3. حالت افزايش


اين الگوريتم ها در طريق هاي كه مجموعه هاي جديد مجاز را ايجاد مي كند ومجموعه هاي قديمي را درزمان سيرتكامل جايگزين مي كنند ، با يكديگر تفاوت دارند.
GALIB دو مكانيسم اوليه براي گسترش قابليت هاي ساخت شي را مهيا مي كند اول از همه (و مهمتر از همه از نظر برنامه نويسي C++ ) شما مي توانيد كلاس هاي خودتان را درست كنيد و تابع هاي عضو جديدي را تعريف كنيد . اگر شما احتياج داريد كه فقط تنظيمات كمي را بر روي رفتار كلاس GALIB اعمال كنيد ، در بيشتر موارد مي توانيد يك تابع تعريف كنيد و به كلاس GALIB بگوييد كه از آن به عنوان پيش فرض استفاده كند .


الگوريتم هاي ژنتيك اگر به درستي پياده سازي شوند، قابليت هر دو مورد پويش( پيدا كردن وسيع)و كاوش (پيداكردن محلي )در فضاي SEARCH را، دارند. نوع رفتار يا عملكردي را كه شما مي بينيد، بستگي به اين دارد كه چگونه عملگرها كار مي كنند و همچنين بستگي به شكل يا فرم فضاي SEARCH شما دارد.

الگوريتم ژنتيك
شي الگوريتم ژنتيك معين مي كند كه كدام سلول مجرد بايد زنده بماند، كدام يك بايد دوباره توليد شود و كدام يك بايد بميرد. شيء‌الگوريتم ژنتيك مي‌تواند آمارها را ضبط كرده و تصميم بگيرد كه چه مدت تكامل ادامه پيدا كند. معمولا يك الگوريتم ژنتيك هيچ نقطه پايان دقيقي ندارد وشما بايد الگوريتم فرمان بدهيد كه چه موقع تمام شود. از تعداد نسل‌ها براي پايان الگوريتم استفاده مي‌شود. ولي شما مي‌توانيد از خوبي بهترين راه حل يا جمعيت‌ها يا هر استاندارد مخصوصي براي مشكل خودكه مايل هستيد، براي پايان الگوريتم استفاده كنيد.


اين كتابخانه شامل چهار نوع از الگوريتم ژنتيك مي‌باشد. اولين آنها استاندارد الگوريتم ژنتيك ساده است كه توسط Goldberg در كتابش توضيح داده شده است. اين الگوريتم از جمعيت‌هاي بدون اشتراك و بهترين‌هاي قابل انتخاب، استفاده مي‌كند. هر نسلي كه الگوريتم ژنتيك ايجاد مي كند يك مجموعه اجزاء جديد جمعيت، بوجود مي‌آيد. دومين نوع الگوريتم ژنتيك،‌ الگوريتم حالت ساكن يا يكنواخت مي‌باشد كه از جمعيت اشتراكي استفاده مي‌كند. دراين گونه شما مي توانيد مشخص كنيد كه چه مقدار از جمعيت بايد در هر نسلي جايگزين شوند. سومين نوع، الگوريتم ژنتيك افزايش است كه درآن هر نسلي شامل يك يا دو فرزند مي‌باشد. الگوريتم به متدهاي جايگزيني دلخواه اجازه مي‌دهد چگونگي يكپارچگي جمعيت از يك نسل جديد دخيل تعريف كنند. به عنوان مثال يك فرزند جديد توليد شده مي‌‌تواند جاي والدين خود را بگيرد يا به جاي افراد مختلف در جمعيت جايگزين شود و يا جايگزين فردي كه بيشترين شباهت را به او دارد شود. نوع چهارم، الگوريتم ژنتيك مرتبط مي باشد اين نوع الگوريتم چندين جمعيت را به صورت موازي با استفاده از الگوريتم حالت يكنواخت نمو مي‌دهد. هر نسل الگوريتم بعضي از افراد را از يك جمعيت به جمعيت ديگري انتقال مي‌دهد.


به علاوه اين نوع هاي اصلي ، Galib يك تركيب از كلاسهاي الگوريتم ژنتيكي كه شما نياز داريد تا كلاس‌هاي دلخواه خودتان را داشته باشيد، تعريف مي‌كند. مثال‌ها شامل بعضي از مشتقات داراي (1) يك الگوريتم ژنتيك كه از چندين جمعيت وانتقال بين جمعيت بر روي cpu هاي مختلف استفاده كند. (2) يك الگوريتم ژنتيك كه انبوه سازي وابسته به ورودي را انجام مي‌دهد، تا گونه‌هاي مختلف افراد را در حين سير تكامل حفظ كند.
كلاس پايه‌اي الگوريتم ژنتيك شامل عملگرها و داده‌هاي معمول براي بيشترين نوع الگوريتم ژنتيك است. وقتي شما الگوريتم ژنتيك دلخواه خود را مي‌خواهيد درست كنيد مي‌توانيد از اين اعضا داده و تابع‌ها براي داشتن آمارها و نظارت بر اجرا، استفاده كنيد.


الگوريتم ژنتيك شامل آمارها، استراتژي جايگزيني و پارامترها، براي راه اندازي و اجرا الگوريتم مي‌باشد. شي جمعيت ظرفي براي مجموعه ژن، همچنين بعضي از آمارها و عملگرهاي انتخاب و اندازه‌گيري را نيز داراست. يك الگوريتم ژنتيك معمولي براي هميشه اجرا مي شود. كتابخانه تابعي را براي مشخص كردن اين كه در چه زماني الگوريتم بايد پايان يابد، ايجاد كرده است كه شامل پايان بر روي نسل، كه در آن شما يك شماره از نسل ها را تعيين مي كنيدكه الگوريتم بايد تا آنجا اجرا شود و پايان برروي همگرايي، كه در آن ارزشي را مشخص مي‌كنيد كه بهترين امتياز از نسل‌ها بايد همگرا شوند. شما مي‌توانيد توابع پاياني را به طور دلخواه تنظيم كنيد و از ملاك خود براي پايان استفاده كنيد.


تعداد ارزشيابي توابع، راه خوبي براي مقايسه الگوريتم‌هاي ژنتيك با متدهاي مختلف جستجوي ديگر مي‌باشد. الگوريتم‌هاي ژنتيك Galib هر دو سنجش‌هاي جمعيت و تعداد مجموعه ژنها را مي‌تواند داشته باشد.

تعريف خروجي ( نمايش)
از ساختمان داده مناسبي براي مسئله‌تان استفاده كنيد. اگر شما يك تابع از اعداد حقيقي را بهبود مي‌بخشيد، از اعداد حقيقي در مجموعه ژنها استفاده كنيد. اگر راه حل مشكلتان مي‌تواند بوسيله اعداد تصويري يا ارزش صحيح ديگر، نمايش داده‌ شود، از آنها براي تعريف مجموعه ژنها استفاده كنيد.


تعريف يك خروجي مناسب ا زهنرهاي استفاده از الگوريتم است. (و هنوز يك هنر است نه يك علم) از حداقل خروجي استفاده كنيد كه كاملا تشريح كننده مي‌باشد. خروجي شما بايد بتواند تمامي راه حل‌ها براي مسئله‌تان را نمايش دهد. ولي اگر شما بايد آن را طراحي كنيد تا نتواند راه حل غير علمي را براي مسئله نمايش دهد،‌بخاطر داشته باشيد كه اگر مجموعه ژنها بتواند راه‌حل‌هاي غير علمي را نمايش دهد در اينصورت تابع بايد طوري طراحي شود كه به راه‌حل‌هاي غير علمي يك ارزش ناتمامي بدهد.


خروجي نبايد شامل اطلاعاتي بيشتر از اطلاعات مورد نياز براي نمايش باشد. اگر چه مزيتي است استفاده از خروجي كه شامل موادهاي اضافي ژنتيكي‌ مي‌باشد ولي آنها بايد بدرستي پياده سازي شده باشند. در مجموعه تابع هاي شي و توجه كامل به نوع و خصوصيات فضاي SEARCH اين تمايل به افزايش در اندازه فضاي SEARCH مي باشد و بدين گونه از عملكرد خوب الگوريتم ژنتيك جلوگيري مي شود. تعداد نمايش خروجي بي نهايت مي باشد. شايد شما كاملا يك خروجي عددي مانند آرايه اي اعداد حقيقي را انتخاب كنيد، اين اعداد مي توانند به عنوان اعداد حقيقي پياده سازي شوند يا در نوع Goldberg رشته اي از بيت ها كه اعداد حقيقي را طراحي كنند. مواظب باشيد كه استفاده مستقيم از اعداد حقيقي مي تواند خروجي هاي دودويي را به دهدهي براي بيشتر مسئله ها تبديل كند خصوصا موقعي كه از عملگر هاي منطقي متقاطع استفاده مي كنيد.


مسئله شما ممكن است به توالي و سلسله مراتب موارد بستگي داشته باشد.كه در اين مورد يك ترتيب پايه اي براي خروجي يا ليست پيوندي و يا آرايه بيشتر صحيح مي باشد، در خيلي از اين موارد شما بايد عملگر هاي را انتخاب كنيد كه يكپارچگي سلسله مراتب را نگه مي دارد عملگر متقا طع بايد ليست ثبت شده را بدون تكثير كردن عناصر ليست توليد كند بقيه مسائل به ساختمان درختي مرتبط هستند.


در اينجا شايد شما بخواهيد كه صريحا راه حل را به صورت درختها نمايش دهيد و عمليات ژنتيكي را مستقيما بر روي آنها انجام دهيد. معمولا بيشتر افراد درخت ها را در يك آرايه يا رشتة معيني برنامه نويسي مي كنند، بعد روي رشته مورد نظر عمليات را انجام مي دهند. بعضي از اشكالات شامل مخلوطي از عناصر پيوسته و ناپيوسته مي باشند، كه در اين مورد شما احتياج به يك ساختار جديد داريد تا اطلاعات مختلط را در خود نگاه دارد. همچنين شما بايد عملگرهاي ژنتيكي را تعريف كنيد كه به ساختار راه حل، احترام بگذارد. براي مثال، يك راه حل با هر دو قسمت صحيح و اعشاري ممكن است از crossover استفاده كند كه قسمت هاي صحيح را با قسمت هاي اعشاري طي كند، و هيچ وقع قسمت اعشاري را با قسمت صحيح مخلوط نمي كند.


هر كدام از اين خروجي هايي را كه انتخاب مي كنيد، اين اطمينان را داشته باشيد كه عملگرهاي درستي را براي نمايشتان انتخاب كرده ايد.

عملگرهاي مجموعه ژن
هر مجموعه ژن سه عملگر اوليه دارد:عمگر اوليه،عملگر جهشي و عملگر متقاطع. با اين عملگرها شما مي توانيد يك جمعيت اوليه را بوجود آوريد، يك جهش يا يك crossover خاصي را براي خروجي مسئله تان تعريف كنيد يا زماني كه جمعيت شما رشد مي كند قسمت هايي از الگوريتم ژنتيك را نمو دهيد. GALIB با اين عملگرهاي از قبل تعريف شده براي هر مجموعه ي سلول همراه است ولي شما مي توانيد اين عملگرها را بر طبق سليقه تان تنظيم كنيد.


عمگر اوليه معين مي كند كه چگونه مجموعه ي سلول ها مقدار دهي اوليه مي شوند. اين عملگر زماني صدا زده مي شود كه شما يك جمعيت يا الگوريتم ژنتيك را مقدار دهي اوليه مي كنيد. اين عملگر در اصل يك مجموعه ي جديد را ايجاد نمي كند، بلكه مجموعه ي سلول ها را مقدار دهي اوليه مي كند با استفاده از مواد اصلي ژنتيك كه از آنها تمام راه حلها رشد مي كنند. شي جمعيت داراي عملگر اوليه ي خود مي باشد. به طور پيش فرض اين عمل، عملگرهاي اوليه ي مجموعه ژن در جمعيت را صدا ميزند ولي شما مي توانيد آن را به دلخواه تنظيم كنيد.


عملگر جهشي يك زير برنامه براي جهش هر مجموعه ي ژن تعريف مي كند. جهش يعني چيزهاي مختلف براي نوع داده هاي مختلف . براي مثال ، يك جهشگر معمولي براي يك مجموعه ژنهاي دودويي رشته اي مي تواند بيت ها را بوسيلة امكانات داده شده ، در خود جاي دهد. يك جهشگر معمولي براي درخت مي تواند زير درخت ها را با امكان داده شده جابجا كند. بصورت عام شما بايد عملگرجهشي را طوري تعريف كنيد كه بتواند هر دو عمل كاوش و استخراج را انجام دهد، عملگر جهشي بايد قادر به معرفي كردن مواد ژنتيكي جديد و همچنين ، تغيير مواد موجود باشد. ممكن است شما بخواهيد چندين نوع عملگر جهشي را براي يك مسئله تعريف كنيد.
عملگر متقاطع يك زير برنامه براي توليد فرزند از دو والدين ( مجموعه ژن ) تعريف مي كند. همانند عملگر جهشي و عملگر متقاطع، مخصوص نوع داده مي باشد و بر خلاف عملگرهاي ديگر عملگر متقاطع شامل چندين مجموعه ي ژن مي شود.


در GALIB هر مجموعه ژن شامل بهترين متد براي جفتگيري است(متد پيش فرض متقاطع )ولي قادر به انجام عمل crossover به خودي خود نمي باشد. هر كدام از الگوريتم هاي ژنتيك مي دانند كه چگونه متد پيش فرض متقاطع را از مجموعه ژن بگيرند و بعد از آن متد براي جفتگيري استفاده كنند. با استفاده از اين مدل، اين امكان وجود دارد كه كلاس هاي الگوريتم ژنتيك جديد مشتق شده اي را داشته باشيم كه از متدهاي جفتگيري ،بيشتر از مجموعه ژن هاي پيش فرض تعريف شده، استفاده مي كنند.


هر كدام از اين متدها مي توانند بطور دلخواه تنظيم شوند تا نه فقط مخصوص به نوع داده باشند بلكه به نوع مسئله هم مرتبط باشد. اين راهي است كه شما مي توانيد بعضي از مسائل مخصوص به هوش را در الگوريتم ژنتيك جاي دهيد( در اين مورد كه آيا اين راه خوبي است يا نه در اينجا بحث نخواهيم كرد).


به علاوه عملگرهاي اوليه ، هر مجموعه ژن بايد شامل يك تابع شيء باشد و ممكن است يك مقايسه كننده نيز داشته باشد. تابع شيء براي ارزيابي مجموعه ژن استفاده مي شود. مقايسه كننده (كه معمولا به تابع هاي دور از محيط معروف هستند ) براي اين است كه تعيين كند چگونه يك مجموعه ژن از ديگري متفاوت است. هر الگوريتم ژنتيك نياز به يك تابع شيء دارد ، در اين صورت است كه الگوريتم ژنتيك تعيين مي كند كدام يك از اجزاء برتر از ديگري است. بعضي از الگوريتم هاي ژنتيك نياز به مقايسه كننده نيز دارند . اين كتابخانه بعضي از انواع دادههاي دست نخورده را دارد ، ولي اگر شما بعنوان مثال يك آرايه يا ليستي از اشياء را داريد ، مي توانيد سريعا بوسيله ي چندين خصوصيت وراثتي شيءتان و شيءمجموعه ژن، يك مجموعه ژن بسازيد. بعد از اين عمليات مي توانيد مستقيماْ اين شئ جديد را در كتابخانه اشياٌ GALIB استفاده كنيد .


به صورت عام ، الگوريتم ژنتيك نيازي به دانستن اينكه بر روي چه ساختمان داده اي عمليات انجام مي دهد ، ندارد . كتابخانه اين عمل را به طور خودكار انعكاس مي دهد. شما مي توانيد نوع هاي مجموعه ژن را با الگوريتم ژنتيك مخلوط و هماهنگ كنيد. الگوريتم ژنتيك مي داند كه چگونه مجموعه ژن را با هم در آميزد تا يك جمعيت جديد ايجاد كند ، مجموعه ژن را مقدار دهي اوليه كند تا اجرا شروع شود ، مجموعه ژن ها را طي كند تا فرزندان توليد شوند ، و درآخر، در مجموعه ژن جهش ايجاد كند. تمام اين عمليات بوسيله ي توابع عضو مجموعه سلول ، انجام مي شود.

شئ جمعيت
شي جمعيت ظرفي براي مجموعه ژن مي باشد. هر شي جمعيت عملوندهاي اوليه ( به طور پيش فرض ، عملوند اوليه را براي هر اجزا در جمعيت صدا مي زند ) و عملوند ارزياب ( كه بطور پيش فرض عملوند ارزياب را براي هر اجزا در جمعيت صدا مي زند )مرتبط با خودشان را دارند. همچنين اين شي بهترين ميانگين و قوانين و غيره براي جمعيت را نگه داري مي كند. ابعاد مختلف را نيز مي توان ثبت كرد ، ولي به اين خاطر كه ابعاد محاسباتي بيشتر اوقات نياز به محاسبات عددي بسيار بزرگي را دارند ، پيش فرض شي ثبت ابعاد نمي باشد . متد انتخاب نيز در شي جمعيت تعريف شده است. اين متد بوسيله ي الگوريتم ژنتيك براي انتخاب اينكه كداميك از اجزا مجموعه بايد در هم بياميزند ، استفاده مي شود.


هر شي جمعيت يك شي ارزياب برنامه، مرتبط با خودش دارد. شي ارزيابي برنامه امتياز شي گرايي هر مجموعه را به بهترين امتياز شي گرايي آن مجموعه ژن تبديل مي كند تا الگوريتم ژنتيك از آن براي انتخاب استفاده كند. همچنين اين شي اطلاعات با اندازه ي معين را براي استفاده بعدي كه به وسيله ي برنامه هاي انتخاب انجام مي شود ، نگهداري مي كند .

توابع شي و مقياس گداري مناسب
معمولا الگوريتم ژنتيك بيشتر از متدهاي جستجوي GARDIENT كه جالب تر هستند استفاده مي كند، زيرا آنها نيازي به معادله هاي مختلف پيچيده يا فضاي SEARCH صاف ، ندارند.
الگوريتم ژنتيك فقط يك مقدار از اينكه چگونه سلولي با سلول هاي ديگر مقايسه مي شوند ، را نياز دارد . تابع شي با استفاده از يك راه حل، اين مقدار را مهيا مي كند .
مهم است كه تفاوت بين امتيازات مناسب و شي را بفهميم. امتياز شي مقدار برگشتي از تابع شي تان مي باشد و اين يك عمليات ارزيابي خام براي مجموعه ژن است.

امتياز مناسب ، سرعت امكان انتقال است كه به وسيله ي الگوريتم ژنتيك استفاده مي شود تا مناسب بودن اجزا براي جفتگيري را تعيين كند . معمولا امتياز مناسب بوسيله ي يك امتيازدهنده ي خطي شي گرايي خام بدست مي آيد(ولي شما مي توانيد هر نقشه اي را كه مي خواهيد طراحي كنيد و يا هيچ انتقالي نداشته با شيد). براي مثال، اگر شما از امتياز دهنده ي خطي استفاده مي كنيد و بعد از آن امتياز مناسب از امتيازات شي گرايي با استفاده از تكنيك امتيازدهنده ي دلخواه مناسب تعريف شده در كتاب GOLDBERG بدست مي آيد. الگوريتم ژنتيك ، از امتياز مناسب براي عمل انتخاب استفاده مي كند و نه از امتياز شي گرايي.


شما مي توانيد اجزا را در جمعيت با استفاده از تابع ارزياب ( كه شما خود آن را تعريف كرده ايد ) ارزيابي كنيد يا با استفاده از يك ارزياب بر پايه جمعيت نيز(كه خود تعريف كرده ايد) مي توانيد اين سنجش را انجام دهيد. اگر شما از يك شي گرايي بر پايه اجزا استفاده كنيد ، تابع به همه ي مجموعه ژن ها، مرتبط مي شود. تابع شي گرايي بر پايه جمعيت مي تواند از توابع شي گرايي اجزا استفاده كند ، يا مي تواند امتياز آنها را خودش تعيين كند.

حالا ببينيم الگوريتم ژنتيك چگونه درc++ نمايش داده مي شود ؟
يك نوع برنامه بهينه سازي شده به شكل زير مي باشد. اين مثال يك مجموعه ژن رشته اي باينري يك بعدي با عملگرهاي پيش فرض ايجاد و بعد از يك الگوريتم ژنتيك ساده براي تكامل استفاده مي كند.
float Objective(GAGenome&);
main(){
GA1DBinaryStringGenome genome(length, Objective); // create a genome
GASimpleGA ga(genome); // create the genetic algorithm
ga.evolve(); // do the evolution
cout << ga.statistics() << endl; // print out the results
}
float Objective(GAGenome&) {
// your objective function goes here
}
شما به آساني مي توانيد رفتار الگوريتم ژنتيك را بوسيله ي معرفي پارامتر هاي مختلف تغيير دهيد.بيشتر آنها بصورت زير هستند:
ga.populationSize(popsize);
ga.nGenerations(ngen);
ga.pMutation(pmut);
ga.pCrossover(pcross);
GASigmaTruncationScaling sigmaTruncation;
ga.scaling(sigmaTruncation);

به صورت متوالي شما مي توانيد الگوريتم ژنتيك GALIB را از فايل يا خط فرمان بخوانيد . قطعه برنامه زير يك الگوريتم ژنتيك را ايجاد مي كند، پارامتر ها را از فايل مي خواند، پارامتر ها را از خط فرمان مي خواند، تغييرات را اعمال مي كند و بعد مشخصات را بعد از اجرا چاپ مي كند.
GASteadyStateGA ga(genome);
ga.parameters("settings.txt");
ga.parameters(argc, argv);
ga.evolve();
cout << ga.statistics() << endl;

يك نوع تابع شي گرايي به اين شكل مي باشد( اين تابع امتياز بالاتري را به مجموعه ژن دودويي رشته اي كه همه ي آنها شامل 1 مي باشد، اختصاص مي دهد).
float
Objective(GAGenome & g) {
GA1DBinaryStringGenome & genome = (GA1DBinaryStringGenome &)g;
float score=0.0;
for(int i=0; i<genome.length(); i++)
score += genome.gene(i);
return score;
}

شما مي توانيد يك تابع شي گرايي به عنوان يك عضو ثابتي از كلاس مشتق شده ، تعريف كنيد ويا يك تابع تعريف كنيد و از آن براي كلاس هاي مجموعه ژن در GALib موجود ، استفاده كنيد.
وقتي كه شما يك تابع شي گرايي را مي نويسيد، شما اول بايد مجموعه ژن كلي را در نوع مجموعه ژني كه تابع شئ گرايي شما نياز دارد، اضافه كنيد. از آن به بعد مي توانيد با يك مجموعه ژن خاص كار كنيد. هر تابع شئ گرايي يك مقدار را برمي گرداند كه اين مقدار امتياز شئ گرايي آن مجموعه ژني كه به تابع شئ گرايي فرستاده شده بود، را نمايش مي دهد.

عملگرها، چه كارهايي مي توانند انجام دهند؟
در اينجا، بعضي مثال هايي كه از نوع جهش و متقاطع مي باشند كه مي توان با استفاده از GALib انجام داد، مشاهده مي كنيد. متقاطع هاي سنتي دو فرزند از دو والدين توليد مي كنند و جهش معمولا به يك فرد اختصاص داده مي شود. به هر حال، خيلي ديگر از نوع جهش ها و متقاطع ها، امكان وجود دارد، مانند متقاطع با استفاده از سه والدين يا بيشتر، متقاطع جنسي يا جهش بر پايه جمعيت. مثال هاي زير بعضي از متدهاي استاندارد، متقاطع جنسي و جهش فردي در GALib ،را نشان مي دهد.

چگونه عملگرهاي خودتان را تعريف كنيد؟
تعريف عملگرها به مشكلي طراحي الگوريتمي است كه مي خواهيد پياده سازي كنيد. همانطور كه پياده سازي انجام مي شود، در مورد تعريف عملگر چيز زيادي نمي توان گفت. براي اختصاص دادن يك عملگر به مجموعه ژن ، فقط از تابع عضو صحيحي استفاده كنيد. براي مثال، كدهاي زير’MyInitializer’ را به تابع اوليه ساز و ‘MyCrossover’ را بعنوان تابع متقاطع را به مجموعه ژن رشته اي دودوئي،تخصيص مي دهد.
GA1DBinaryStringGenome genome(20);
genome.initializer(MyInitializer);
genome.crossover(MyCrossover);


اگر شما اين عمل را با اولين مجموعه ژن انجام دهيد، (آن ژني كه براي مجموعه ژن استفاده مي كنيد) در نتيجه تمام ژنهايي كه GA كپي مي كند، تمام عملگرها برايشان تعريف شده خواهند بود.
وقتي كه شما مجموعه ژن خودتان را مشتق مي كنيد، معمولا يك كپي سخت از عملگرها را در مجموعه ژن به صورت زير انجام خواهيد داد:
class MyGenome : public GAGenome {


public:
static void RandomInitializer(GAGenome&);
static int JuggleCrossover(const GAGenome&, const GAGenome&, GAGenome*, GAGenome*);
static int KillerMutate(GAGenome&, float);
static float ElementComparator(const GAGenome&, const GAGenome&);
static float ThresholdObjective(GAGenome&);
public:


MyGenome() {
initializer(RandomInitializer);
crossover(JuggleCrossover);
mutator(KillerMutate);
comparator(ElementComparator);
evaluator(ThresholdObjective);
}
// remainder of class definition here
};

در نظر داشته باشيد كه چه آسان تغيير عملگرها صورت مي گيرد. شما مي توانيد تعدادي از عملگرها را براي يك نمايش ساده و تجربه با آنها تعريف كنيد تا ببينيد كدام عملگر بهتر عمل مي كند.

در متن اصلی مقاله به هم ریختگی وجود ندارد. برای مطالعه بیشتر مقاله آن را خریداری کنید