‫ درس 1 : حل یک مدل برنامه ریزی خطی عدد صحیح ( بخش اول ) | انجمن

مدیریت
مدیریت 30 شهریور 1396

در محیط ویژوال استدیو Visual studio for microsoft، زبان های برنامه نویسی مختلفی وجود دارد که بسته به توانایی و تسلط می تواند یکی از زبان های ویژوال بیسیک، ویژال سی، ویژال سی شارپ را انتخاب کنید. در سلسله درس های پیش رو، از زبان ویژوال بیسیک استفاده می شود که دلیل اصلی ان سادگی در برنامه نویسی است. البته اگر بنا به دلیلی می خواهید از زبان های دیگر در ویژال استدیو استفاده کند، می تواند کد ارایه شده را با استفاده از تبدیل کننده های زبان های برنامه نویسی به زبان دلخواه تبدیل کرد. از جمله وب سایت هایی که این کار را انجام می دهند می توان به سایت زیر اشاره کرد.

http://converter.telerik.com/

پس از آن که کتاب خانه cplex را به برنامه ویژال استدیو اضافه کردیم، با اضافه کردن دو خط زیر به ابتدای هر برنامه می توان از قابلیت های cplex در برنامه ویژال استدیو بهره برد.

Imports ILOG.Concert

Imports ILOG.CPLEX

در این تمرین یک فرم ایجاد می کنیم که مقدار پارامترهای مدل خطی را به ان می دهیم و با انتخاب متغیر از نوع پیوسته یا گسسته، جواب بهینه را محاسبه می شود.

1.برنامه ویژال استدیو را باز کرده و بر روی New project کلیک کنید تا صفحه زیر باز شود. در صورتیکه می خواهید با زبان ویژال بیسیک برنامه نویسی کنید، Visual Basic را انتخاب کنید. فرمت های مختلفی برای پروژه وجود دارد که در این تمرین Windows forms application انتخاب می شود.

2.در پروژه باز شده، فرمی به صورت زیر طراحی شود.

در فرم بالا اطلاعات مربوط به مدل برنامه ریزی خطی وارد می شود که شامل ضرایب تکنولوژیکی و ضرایب سمت راست است. مدل خطی برای دو حالت متغیر حل می شود: متغیر پیوسته و متغیر گسسته که این انتخاب با دو radiobutton انجام می شود. پس از کلیک بر روی دکمه solve، مقدار بهینه متغیرهای تصمیم گزارش می شود. برای جواب مدل سه حالت بهینه، امکان ناپذیر، و بیکران اتفاق می افتد که در قسمت پایین فرم آمده است.

3. برای این که برنامه نویسی به سادگی انجام شود توصیه می شود که نامگذاری کنترل های به صورت زیر انجام شود.

4. برای این که بتوان از قابلیت های cplex  استفاده کرد، باید از کلاس cplex ، شی نمونه سازی کرد تا بتوان از کلاس های وابسته در برنامه بهره برد.

  Dim cplex As New Cplex()

5.تعریف متغیر برای متغیرهای تصمیم گیری و تعریف محدودیت به صورت زیر انجام می شود. توصیه می شود که کلیه ها متغیر در یک آرایه ذخیره می شود که از نوع inumvar است که در هر یک از مولفه ها، ارایه مربوط به هر متغیر تصمیم ذخیره می شود. البته در این مثال چون تنها یک نوع متغیر داریم X، لزومی به ارایه var نمی باشد ولی اگر بیش از یک نام گذاری داشته باشیم،  مثلا X و Y، استفاده از ارایه Var توصیه می شود.

        Dim var(1)() As INumVar

        Dim rng(1)() As IRange

6.برای تعریف متغیر X که در ارایه var ذخیره شود از دستور زیر استفاده می شود. چون سه متغیر تصمیم داریم، x1 در x(0)، x2 در x(1) و x3 در x(2) ذخیره می شود.

        Dim x(2) As INumVar

7.در این برنامه به دنبال یافتن جواب بهینه برای متغیرهای پیوسته و عدد صحیح هستیم. اگر متغیر پیوسته باشد، در دستور تعریف متغیر از دستور cplex.NumVar(A,B,C) استفاده می شود که A حد پایین متغیر،B حد بالای متغیر، و C نوع متغیر است که اگر متغیر پیوسته باشد  ILOG.Concert.NumVarType.Float  و اگر متغیر گسسته باشد از ILOG.Concert.NumVarType.integer استفاده شود.

        If rbtncontin.Checked = True Then

            For i = 0 To UBound(x, 1)

                x(i) = cplex.NumVar(0, 33, ILOG.Concert.NumVarType.Float)

 

            Next

 

        End If

        If rbtninteger.Checked = True Then

            For i = 0 To UBound(x, 1)

                x(i) = cplex.NumVar(0, 33, ILOG.Concert.NumVarType.Int)

            Next

        End If

8. برای مرتبط کردن متغیرها به Var از دستور زیر استفاده می شود. اگر علاوه بر نوع X، متغیری از نوع Y وجود داشته باشد، در ارایه دوم Var متغیر از نوع Y در آن ذخیره می شود.

        var(0) = x

9. مقدار ضرایب متغیرها در تابع هدف در پارامتر objvalsذخیره می شود که مقدار ان از مقداری نوشته شده از textbox تعیین می شود.

        Dim objvals As Double() = {CInt(txtobjX1.Text), CInt(txtobjX2.Text), CInt(txtobjX3.Text)}

10. برای ساخت تابع هدف با فرمت بیشینه سازی، باید ضرایب objvals در متغیرها ضرب کرد. برای این کار ابتدا یک expression تعریف می شود و عبارت جبری تابع هدف در ان ذخیره می شود. سپس یک تابع هدف خالی (objfunction) با فرمت بیشینه سازی تعریف شده و expression ایجاد شده در ان ذخیره می شود.

        Dim experssion(2) As ILOG.Concert.IIntExpr

        experssion(1) = cplex.ScalProd(x, objvals)

        Dim objfunction As ILOG.Concert.IObjective = cplex.AddMaximize()

        cplex.AddToExpr(objfunction, experssion(1))

11. پس از تعریف تابع هدف، محدودیت ها به مدل باید اضافه شود. محدودیت های از کلاس  IRange نمونه سازی شود. محدودیت اول در rng(0)(0)  و محدودیت دوم در rng(0)(1)ذخیره می شود. برای جمع دو متغیر از تابع cplex.sum و برای ضرب مقداری در یک متغیر از cplex.prod استفاده شود.

        rng(0) = New IRange(1) {}

        rng(0)(0) = cplex.AddLe(cplex.Sum(cplex.Prod(CInt(txtCon1X1.Text), x(0)), cplex.Prod(CInt(txtCon1X2.Text), x(1)), cplex.Prod(CInt(txtCon1X3.Text), x(2))), CInt(txtCon1B.Text), "c1")

        rng(0)(1) = cplex.AddLe(cplex.Sum(cplex.Prod(CInt(txtCon2X1.Text), x(0)), cplex.Prod(CInt(txtCon2X2.Text), x(1)), cplex.Prod(CInt(txtCon2X3.Text), x(2))), CInt(txtCon2B.Text), "c2")

12. اکنون اطلاعات مورد نیاز برای مدل وارد شده است و نوبت حل مدل رسیده است. برای حل مدل کافی است که از تابع cplex.solve() استفاده شود. در صورتی که به جواب بهینه برسیم، خروجی این تابع true  است و داخل شرط if می شویم. برای گزارش مقدار بهینه متغیرها از تابع cplex.getvalues(Var(0)) استفاده می شود که آرگمان این تابع متغیر تصمیم است و خروجی این تابع مقدار بهینه متغیر تصمیم است که به صورت آرایه ذخیره می شود.

برای تعیین مقدار slack هر محدودیت از دستور cplex.slacks(rng(0)) ذخیره شود. در آرگمان این تابع، آرایه مربوط به محدویت آورده می شود. برای گزارش وضعیت جواب مدل که آیا به جواب بهینه رسیده یا خیر از دستور cplex.GetStatus(). استفاده می شود. مقدار بهینه تابع هدف از دستور  cplex.ObjValue.ToString بدست می اید.

        ' solve the model and display the solution if one was found

        If cplex.Solve() Then

            Dim xx As Double() = cplex.GetValues(var(0))

            Dim slack As Double() = cplex.GetSlacks(rng(0))

            cplex.Output().WriteLine(("Solution status = " + cplex.GetStatus().ToString))

            lblStatus.Text = cplex.GetStatus().ToString

            cplex.Output().WriteLine(("Solution value  = " + cplex.ObjValue.ToString))

13. مقدار بهینه متغیرهای تصمیم در label نشان داده می شود که در آرایه xx ذخیره می شود.

            lblX1.Text = xx(0)

            lblX2.Text = xx(1)

            lblX3.Text = xx(2)

        End If

        MessageBox.Show((“Solution value  = “ + cplex.ObjValue.ToString))

14. اگر جواب مدل بهینه باشد، ویژگی getstatus برابر optimal  می شود که در این صورت یک جعبه محاوره ای باز می شود که optimal نشان داد می شود.

        If cplex.GetStatus().ToString = "Optimal" Then

            MessageBox.Show("Optimal")

        End If

        cplex.End()

15.برای اجرای برنامه نوشته شده، بر روی Run کلیک کنید. پس از اجرای برنامه، صفحه زیر نمایش داده می شود.

که وضعیت جواب به صورت زیر نشان داده می شود.

16. اگر برای متغیرها فقط مقادیر گسسته در نظر گرفته شود، صفحه زیر نمایش داده می شود.

و وضعیت جواب و مقدار بهینه جواب در جعبه محاوره زیر نمایش داده می شود.

17. در صورتی که می خواهید تغییرات را ذخیره کنید بر روی save کلیک کنید.

ویرایش شده توسط مدیریت (30 شهریور 1396)