‫ درس 4 : حل یک مدل برنامه ریزی خطی عدد صحیح با تغییر روش شاخه کردن | انجمن

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

در این تمرین روش شاخه کردن گره با مقدار جواب غیرعدد صحیح را تغییر می دهیم. در روش جدید، بر روی متغیری با مقدار غیرعدد صحیح شاخه زده می شود که بیشتر امکان ناپذیری را داشته باشد و همچنین در تابع هدف بیشتر ضریب را داشته باشد.

1.در این تمرین از مدل های تعریف شده در تمارین سیپلکس CPLEX استفاده می شود. برای استفاده از ان ها کافی است که تنها مسیر مدل به فرمت زیر در برنامه اورده شود.

        Dim cplex As New Cplex()

        Dim filename As String = "C://ILOG/CPLEX101/examples/data/noswot.mps"

        cplex.ImportModel(filename)

 

2.برای تغییر در روش شاخه کردن در برنامه سیپلکس، باید ماتریس ضرایب در متغیر LP ذخیره شود.

        Dim matrixEnum As IEnumerator = cplex.GetLPMatrixEnumerator()

        matrixEnum.MoveNext()

        Dim lp As ILPMatrix = CType(matrixEnum.Current, ILPMatrix)

3.تغییر در روش شاخه زنی با به کارگیری کلاس MybranchGoal انجام می شود که ورودی این کلاس ماتریس ضرایب مدل است. بر خلاف callback، این کلاس خاص به عنوان ورودی در تابع cplex.solve وارد می شود.

        If cplex.Solve(New MyBranchGoal(lp.NumVars)) Then

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

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

        End If

 

        cplex.End()

        ' Catch e As ILOG.Concert.Exception

        System.Console.WriteLine(("Concert exception caught: " + e.ToString))

        'End Try

4. کلاس mybranckgoal به صورت زیر تعریف می شود. در کد زیر موارد زیر نیاز به توضیح دارد.

Dim x As Double() = GetValues(_vars): مقدار فعلی متغیرها در گره در متغیر x ذخیره شود.

Dim feas As Cplex.IntegerFeasibilityStatus() = GetFeasibilities(_vars): وضعیت امکان پذیری هر یک از متغیرها در fea ذخیره شود. برای مثال اگر یک متغیر عدد صحیح باشد و در گره فعلی مقدار صحیح نگرفته باشد به صورت infeasible ذخیره می شود.

Dim obj As Double() = GetObjCoefs(_vars): ضریب متغیرهای _vars در تابع هدف در متغیر Obj ذخیره می شود.

Dim cols As Integer = _vars.Length : تعداد متغیرها که همان ستون است در cols ذخیره شود.

cplex.And(cplex.Or(cplex.GeGoal(_vars(bestj), System.Math.Floor(x(bestj)) +1), cplex.LeGoal(_vars(bestj), System.Math.Floor(x(bestj)))),Me): این کد گره فعلی را از درخت شاخه و کرانه حذف کرده و دو گره که یک محدودیت به هر گره اضافه شده جایگزین می کند.

Friend Class MyBranchGoal

        Inherits Cplex.Goal

        Friend _vars() As INumVar

        Friend Sub New(ByVal vars() As INumVar)

            _vars = vars

        End Sub 'New

        Public Overrides Function Execute(ByVal cplex As Cplex) As Cplex.Goal

            Dim x As Double() = GetValues(_vars)

            Dim obj As Double() = GetObjCoefs(_vars)

            Dim feas As Cplex.IntegerFeasibilityStatus() = GetFeasibilities(_vars)

            Dim maxinf As Double = 0.0

            Dim maxobj As Double = 0.0

            Dim bestj As Integer = -1

            Dim cols As Integer = _vars.Length

            Dim j As Integer

            For j = 0 To cols - 1

                If feas(j).Equals(cplex.IntegerFeasibilityStatus.Infeasible) Then

                    Dim xj_inf As Double = x(j) - System.Math.Floor(x(j))

                    If xj_inf > 0.5 Then

                        xj_inf = 1.0 - xj_inf

                    End If

                    If xj_inf >= maxinf AndAlso (xj_inf > maxinf OrElse System.Math.Abs(obj(j)) >= maxobj) Then

                        bestj = j

                        maxinf = xj_inf

                        maxobj = System.Math.Abs(obj(j))

                    End If

                End If

            Next j

            If bestj >= 0 Then

                Return cplex.And(cplex.Or(cplex.GeGoal(_vars(bestj), System.Math.Floor(x(bestj)) + 1), cplex.LeGoal(_vars(bestj), System.Math.Floor(x(bestj)))),Me)

            Else

                Return Nothing

            End If

        End Function 'Execute

    End Class 'MyBranchGoal

5. اکنون برنامه آماده اجرا است. در صورتی که می خواهید تغییرات را ذخیره کنید بر روی save کلیک کنید.