آموزش رایگان نرم افزار گمز
در این پست، آموزش رایگان نرم افزار گمز را برای شما در قالب متن و ویدیو (اگه حوصله خوندن متن ندارید میتونید فقط از ویدیوهای این پست استفاده کنید، نگران نباشید چون چیزی را از دست نمیدید) آوردهام. امیدوارم در روند بهینه سازی مسائل شما و یادگیری این نرمافزار، نقشی خوبی داشته باشم. اگه با خواندن این مطلب سوالی برای شما پیش اومد، خوشحال میشم که اون را از طریق راههای ارتباطی که در همین وبسایت موجوده، باهام مطرح کنید.
گمز چیه؟
گمز (Gams-General Algebraic Modeling System) یک نرمافزار حل مدل ریاضی هست، به این صورت که ما مدل ریاضی را بهش میدیم و شروع به پیدا کردن بهینهترین جواب در مدل میکنه. انواع مدلها را هم حل میکنه، مدل ریاضی خطی باشه یا غیر خطی، یک جواب بهینه داشته باشه یا چندتا یا اصلا جواب بهینه نداشته باشه، در هر صورت حلش میکنه و بعد از اینکه مدل را حل کرد، گزارش کاملی از حل اون مدل بهمون میده (بضی مواقع ممکنه مدل ما اصلا جواب نداشته باشه یا نشدنی باشه، در این صورت نرمافزار بعد از بررسی مدل این موضوع را به ما میگه، در غیر اینصورت جوابها را به ما میده). البته حرف من را اشتباه برداشت نکنید، برای اینکه گمز کمکتون کنه، باید یک مدل ریاضی درست حسابی داشته باشید و قرار نیست این نرم افزار نقصهای مدل شما را برطرف کنه. پس اگه با مدل سازی ریاضی آشنایی ندارید حتما اول اون را یاد بگیرید (به طور مثال میتونید با جستجو در مورد تحقیق عملیات در گوگل شروع کنید).
گمز به درد چه کسانی میخوره؟
بنظرم هر کسی که به نحوی با بهینه سازی سرکار داره، نرمافزار گمز بهترین نرمافزاری هست که میتونه یاد بگیره، بخصوص دانشجوها و مهندسهای صنایع که اصلا کارشون همینه!
نصب نرمافزار گمز
گمز نرمافزار گرونی هست، هم برای نصب خود نرمافزار باید هزینه کنید و هم هر سالور (Solver) اون را جداگونه باید بخرید (خود نرمافزار یادمه حدود 1000 دلار بود و هر سالور هم بسته به توانایی حلش، قیمت مخصوص به خودش و جدا از نرمافزار را داره). برای همین، طبق معمول لازمه به سراغ یکی از وبسایتهای ایرانی بریم و نسخه کرک شده گمز را دانلود و نصب کنیم (من خودم از اینجا دانلود و نصب کردم). نصب نرمافزار که خیلی آسونه و چارتا Next میزنید ولی برای کرک کردنش حتما از دستور العمل همون وبسایتی که گمز را ازش دانلود کردید استفاده کنید.
سالور گمز چیه؟
گمز یک نرمافزار یکپارچه هست که داخلش چند تا سالور وجود داره، سالور الگوریتم یا ابزاری هست که مساله شما را حل میکنه، در حقیقت کار گمز اینه که مدل را شسته رفته تحویل سالور بده و بعد از حل، اطلاعات مورد نیاز را از سالور بگیره و شسته رفته تحویل ما بده (برای اطلاعات بیشتر از این لینک استفاده کنید). مثلا یک سالور فقط مسائل خطی را حل میکنه، یکی هم غیر خطیها را، پس با توجه به نوع مدل تصمیم میگیریم که از چه سالوری استفاده کنیم. وقتی گمز را نصب میکنید تعدادی سالور داخلش هست (پس لازم نیست سالور را جداگونه نصب کنید)، بعضی از اونها رایگان هستند و برای استفاده از بعضیهاشون هم باید هزینه کنید و لایسنس اونها را بخرید (که البته برای ما که از گمز کرک شده استفاده میکنیم، معمولا همه سالورها کامل باز هستند).
شروع کار با گمز: حدل یک مدل ساده
برای شروع کار یک مدل ساده آوردم (مثال از کتاب راهنمای کاربران گمز نوشته دکتر مهدی طلوع و سمانه جوشقانی هست)، مساله اینجوریه که دو تا کارخانه داریم و سه تا بازار، قراره از این کارخانهها برای این بازارها محصول بفرستیم. هر بازار هم تقاضای مخصوص به خودش را داره و هر کارخانه هم عرضه خودش را داره. جدول پایین فاصله کارخانهها و بازارها (به کیلومتر)، عرضه هر کارخانه، تقاضای هر بازار و هزینه حمل و نقل هر واحد کالا به ازای هر یک کیلومتر برای کارخانه را نشون میده.
پس مدل ریاضی این مساله اینجوری میشه:
خب، حالا وقت کدنویسی با گمزه، برای همین گمز را باز میکنیم، اولش یک صفحه سفید برای ما میاره که همونجا میتونید کدنویسی کنید. فقط یادتون نره که فایل را Save یا Save as کنید.
تعریف مجموعه در گمز
اولین چیزی که باید برای گمز مشخص کنید، اندیسهای مدل هست، الان ما در این مدل دو تا اندیس داریم، اندیس i که به کارخانههامون اشاره داره و مقادیر زنجان و تهران را میتونه داشته باشه، و اندیس j برای بازارها با مقادیر قزوین، همدان و اراک. اندیسها در گمز در قالب مجموعهها تعریف میشوند، به عبارت دیگه اندیس در گمز با نام مجموعه شناخته میشه. با کد پایین اندیسهامون را به همراه مقادیرشون را میتونیم وارد گمز کنیم (اگه این قسمت آموزش یا هر قسمت دیگهای براتون ابهامی داشت، میتونید ویدیو آموزشی که در ادامه براتون قرار دادم را ببینید):
sets
i factories /zanjan , tehran/
j markets /qazvin , hamedan , arak/;
همونطور که از کد مشخصه، مجموعهها لازمه با عنوان sets تعریف بشن. عبارت factories یا عبارت markets که بعد از نام اندیس اومده، توضیح اختیاری هستند و فقط برای این مینویسیم که اگه خودمون (یا کس دیگهای) بعد از چند ماه کدمون را خوندیم، بفهمیم چی به چیه! مقادیر مجموعه یا اندیس هم باید بین دو تا علامت / تعریف شوند. حواستون باشه بعد از تعریف مجموعهها از ; استفاده کنید. در ضمن من در پست مجموعهها در گمز، مجموعهها را با جزییات بیشتری آموزش دادم.
وارد کردن دادهها و معلومات مدل در گمز
دومین مرحله اینه که باید دادهها و معلومات مدل را به گمز بدیم. یعنی فاصله کارخانهها تا بازار، عرضهها، تقاضاها و هزینه حمل و نقل. دادهها را در گمز میتوان به سه حالت تعریف کرد:
پارامترها: تقریبا هر نوع دادهای با هر بعدی را میتونیم به صورت پارامتر تعریف کنیم. برای مثال من عرضه هر کارخانه و تقاضای هر بازار را به صورت زیر در گمز تعریف کردم. کافیه کدهای زیر را پایین کدهای مربوط به اندیسها بنویسیم:
parameters
a(i) capocity of factory /zanjan 400
tehran 600/
b(j) demand of market /qazvin 375
hamedan 300
arak 325/;
تعریف پارامترها با نوشتن عبارت parameters شروع میشه، بعد از نوشتن این عبارت، لازمه نام پارامتر، یک توضیح (اختیاری) و مقادیر (داخل // ) طبق مثال بالا نوشته شود. به طور مثال طبق تعریف بالا، پارامتر a شامل مقادیر مربوط به عرضه (ظرفیت) هر کارخانه هست که مقدار مربوط به زنجان برابر 400 هست.
جدولها: جدول یکی دیگر از انواع تعریف داده هست که معمولا برای دادههای دو بعدی بکار میره ولی برای هر تعداد بعدی قابل کاربرد هست. من تصمیم گرفتم فاصله کارخانهها را تا بازارها را به صورت جدول به شکل زیر در گمز تعریف کنم:
table d(i , j) distance
qazvin hamedan arak
zanjan 329 160 505
tehran 337 160 239
;
جدول با عبارت table تعریف میشود، جلوی این عبارت نام جدول با اندیسها را مینویسیم (اسم table را چون به فاصله اشاره داره، d گذاشتم)، بعدش هم یک توضیح اختیاری. خط بعدی هم خود جدول را مطابق شکل مینویسیم (خوبی گمز همینه، کدنویسی داخلش خیلی راحته، دقیقا همینوطوری که جدول را روی کاغذ مینویسیم، اینجا هم مینویسیم).
اسکالر (Scalar): اسکالرها برای تعریف یک عدد ثابت بکار میروند:
scalars
f The cost of transporting a product per kilometer /25/;
همونطور که مشخصه، من هزینه ثابت حمل و نقل هر واحد کالا در هر کیلومتر را در قالب یک اسکالر به نام f تعریف کردم.
پارمترهای محاسباتی: این نوع دادهها از انجام عملیات ریاضی روی یک یا چند داده دیگر بدست میآیند. مثلا در همین مثال پارامتر c از حاصل ضرب پارامتر f در d بدست میآید، بنابراین کد اون را اینطوری مینویسیم:
parameter c(i , j) transport cost;
c(i , j) = f * d(i , j);
اجازه بدید این قطعه از کد را توضیح بدم، خط اول، پارامتر c را با اندیسهای خودش با استفاده از عبارت parameter تعریف کردم (اگه تعجب کردید که چرا اینجا به جای عبارت parameters از عبارت parameter استفاده کردم، باید بگم که این دو تا هیچ فرقی با هم ندارند و هر دو را میتوان برای تعریف پارامتر استفاده کرد، معمولا اگه دارید چندتا پارامتر را پست سر هم تعریف میکنید، از parameters استفاده کنید قشنگتره. همین موضوع برای set هم صدق میکنه) و یکمی توضیح براش نوشتم که اگه بعد از یک مدت به کد خودم نگاه کردم، بدونم که این پارامتر به هزینه حمل و نقل اشاره داره. چون پارامتر محاسباتی هست، همینجا ; میگذارم و میرم خط بعدی.
خط دوم به نظر خیلی راحته و نیاز به توضیح خاصی نداره، صرفا پارامتر d را در اسکالر f ضرب کردم و حاصل را در پارامتر c قرار دادم.
تعریف متغیرها در گمز
بعد از تعریف اندیسها و دادههای مدل، نوبت به این میرسه که متغیرها را تعریف کنیم. برای تعریف متغیرهای این مدل از دو خط کد زیر استفاده میکنیم:
positive variable x(i , j);
free variable z;
هنگام تعریف یک متغیر، اول نوع آن را باید مشخص کنیم، در اینجا متغیر x، طبق مدل فقط مقادیر مثبت را میتونه بگیره، برای همین اول عبارت positive را نوشتم، بعد از اون هم عبارت variable را لازمه بنویسیم، سپس نام متغیر با اندیسهای اون را مینویسیم و در پایان هم اگر صلاح دونستید میتونید یک توضیح در رابطه با این متغیر بنویسید. برای متغیرهای منفی میتوانیم از کلید واژه negative استفاده کنیم.
در خط دوم متغیری از نوع free (این نوع متغیر هم اعداد مثبت و هم اعداد منفی را میتونه شامل بشه) به نام z تعریف کردم. این متغیر مستقیما در مدل نبود ولی برای حل مدل لازمه که تعریف بشه. z متغیر حاوی مقدار تابع هدف است و یادتون باشه که متغیر تابع هدف حتما باید از نوع free باشد.
تعریف تابع هدف و محدودیتها در گمز
برای تعریف تابع هدف و محدودیتها در گمز از کلید واژه equations استفاده میکنیم و بعد از اون برای تمامی معادلات مدل (چه تابع هدف و چه محدودیت) اسم انتخاب میکنیم. مثلا من اسم تابع هدف را obj گذاشتم و اسم محدودیت اول را c1 و… .
حالا لازمه که معادلات را بنویسیم، طبق کد پایین، اول باید اسم معادله را بنویسید، بعدش .. (دو تا نقطه) و بعدش خود معادله را مینویسید. دقت کنید که در نوشتن معادلات در گمز، مساوی به صورت =e= ، بزرگتر به صورت =g= و کوچکتر به صورت =l= نوشته میشه.
تابع sum یک تابع از پیش نوشته شده در گمز هست که کار جمع را برای ما انجام میده. این تابع به عنوان پارامتر اول اندیسی (یا اندیسهایی) را میگیره که باید روی اون اندیس عملیات جمع انجام بشه و به عنوان پارامتر دوم، عبارتی که مقادیرش را باید جمع کنه را از ما میگیره.
به عنوان نکته آخر از این بخش باید بگم که اگه توجه کرده باشید، جلوی نام دو محدودیت ما پرانتز باز شده و نام یک اندیس داخلش نوشته شده. لطفا برگردید بالا و مدل ریاضی را دوباره نگاه کنید، روبروی محدودیت اول یک سور عمومی (∀) روی هر i وجود دارد، این مورد را دقیقا با باز کردن پرانتز و قرار دادن اندیس i داخل پرانتزِ جلوی نام محدودیت اول، به گمز حالی کردیم (برای محدودیت دوم هم همینطور). اگه در رابطه با این بخش یا بخشهای قبلی آموزش ایهامی برای شما وجود دارد، حتما توصیه میکنم از ویدیو آموزشی که در ادامه این پست هست، استفاده کنید.
equations
obj,c1,c2;
obj.. z =e= sum((i , j) , x(i , j) * c(i , j));
c1(i).. sum(j , x(i , j)) =l= a(i);
c2(j).. sum(i , x(i , j)) =g= b(j);
نامگذاری برای مدل در گمز
تقریبا همه کدهای لازم را نوشتیم، الان لازمه که برای مدل خودمون با استفاده از کد زیر اسم بگذاریم (اسم مدل transport گذاشته شده)، و داخل // هم به گمز بگیم که کدام معادلات را در حل مدل دخیل کنه:
model transport /all/;
عبارت model برای تعریف یک مدل در گمز بکار میره، هر چیزی که روبروی این عبارت نوشته بشه بیانگر نام مدل هست، یعنی گمز از این به بعد مدل من را با نام transport میشناسه. داخل // از کلید واژه all استفاده کردم، یعنی تمامی معادلات موجود را در حل مدل استفاده کن. مثلا اگه شما نمیخواستید که محدودیت دوم در حل مدل اعمال بشه، به جای all از عبارت obj,c1 باید استفاده میکردید تا گمز فقط تابع هدف و محدودیت اول را در حل مدل در نظر بگیره.
دستور حل در گمز
برای دستور حل از عبارت solve استفاده میکنیم (گمز بعد از دیدن عبارت solve، شروع به حل مدل میکند و تا پایان حل مدل، به سراغ خطوط بعدی کد نمیره)، بعد از solve، نام مدل را مینویسیم، بعدش کلید واژه using، سپس نوع مدل (مدل مورد بررسی من، چون خطی هست، نوع مدل را برابر LP قرار دادم)، بعد از نوع مدل، مشخص میکنیم که مساله از نوع ماکزیمم سازی هست یا مینیمم سازی (برای ماکزیمم سازی از عبارت Maximizing و برای مینیمم سازی از کلید واژه Minimizing استفاده میکنیم) و در پایان نام متغیر تابع هدف را مینویسیم. برای این مدل دستور solve به شکل زیر باید نوشته شود:
solve transport using LP Minimizing z;
نمایش متغیرها
بعد از حل مدل، گمز گزارش مفصلی در رابطه با حل مدل، متغیرها و مقدار آنها و… به ما میده ولی در صورتی که تمایل داشتید، متغیر یا پارامتر خاصی را جداگانه بررسی کنید یا مقدارش را بعد از حل مدل به صورت مجزا ببنید، میتونید از دستور display استفاده کنید:
display z.l , x.l;
منظور از عبارت l. که بعد از نام متغیر آوردم، level متغیر یا مقدار فعلی متغیر هست.
حل مدل در گمز
کل کد گمز ما تا اینجا، اینطوری شد:
sets
i factories /zanjan , tehran/
j markets /qazvin , hamedan , arak/;
parameter
a(i) capocity of factory /zanjan 400
tehran 600/
b(j) demand of market /qazvin 375
hamedan 300
arak 325/;
table d(i , j) distance
qazvin hamedan arak
zanjan 329 160 505
tehran 337 160 239
;
scalars
f The cost of transporting a product per kilometer /25/;
parameter c(i , j) transport cost;
c(i , j) = f * d(i , j);
positive variable x(i , j);
free variable z;
equations
obj,c1,c2;
obj.. z =e= sum((i , j) , x(i , j) * c(i , j));
c1(i).. sum(j , x(i , j)) =l= a(i);
c2(j).. sum(i , x(i , j)) =g= b(j);
model transport /all/;
solve transport using LP Minimizing z;
display z.l , x.l;
برای حل مدل از دکمه RUN GAMS (مطابق تصویر) یا کلید f9 استفاده میکنیم:
گزارش گمز در رابطه با مدل حل شده
وقتی گمز مدل را حل کرد، گزارش کاملی در رابطه با حل مدل به ما ارائه میده، این گزارش بخشهای زیادی داره (در تصویر پایین این بخشها را هایلایت کردم):
گزارش حلی که گمز به ما میده، اطلاعات خیلی مفیدی داخلش داره و من قطعا در ادامه این آموزش که به صورت هفتگی بروز میشود، به سراغ تمامی این بخشها، خواهم رفت. ولی در حال حاضر بخش Solution Report و Display را بررسی میکنم. اول به سراغ Solution Report میرم و روی اون دو تا کلیک میکنم و این بخش گزارش برای من باز بشه:
در قسمت SOLVER STATUS خیلی خوبه که ما عبارت Normal Completion را ببینیم، چون این یعنی که سالور تونسته مساله را بدون هیچ مشکلی حل کنه. قسمت MODEL STATUS مقدار Optimal را به ما نشون میده، یعنی اینکه مساله دارای جواب بهینه هست. و مهمترین قسمت، یعنی OBJECTIVE VALUE هست که مقدار تابع هدف را به ما نشون میده.
در قسمت Display هم میتونید، متغیرهایی که مشخص کردید را ببنید، من روی یک زیر مجموعه از این قسمت، مثل z دابل کلیک میکنم و همانطور که از تصویر پایین مشخصه، مقدار z و x را میتونم ببینم. یعنی الان میدونم که به چه بازاری باید چقدر محصول ارسال کنم (مثلا ارسال محصول از کارخانه زنجان به اراک بصرفه نیست و چیزی نباید ارسال شود ولی از زنجان به قزوین 375 تا محصول باید ارسال شود، همچنین حداقل هزینه ارسال هم برابر 6،226،250 تومان میباشد) :
ویدیو آموزش تا به اینجا
هر چیزی که تا حالا نوشتم را داخل این ویدیو هم توضیح دادم، میتونید به جای خوندن متن از این ویدیو استفاده کنید. در ضمن این ویدیوها را در داخل چنل یوتوب خودم هم قرار میدم، خوشحال میشم که چنل من را دنبال کنید.
نقشه راه یادگیری گمز
چون این پست خیلی طولانی شد، تصمیم گرفتم که ادامه آموزش را در پستهای دیگه منتشر کنم و اینجا بهشون لینک بدم. بنابراین این پست بجز آموزش، یک نقشه راه یادگیری گمز هم محسوب میشه. لطفا آموزش را طبق ترتیب پستهایی که در پایین قرار دادهام، ادامه دهید: