در این تمرین روش شاخه کردن گره با مقدار جواب غیرعدد صحیح را تغییر می دهیم. در روش جدید، بر روی متغیری با مقدار غیرعدد صحیح شاخه زده می شود که بیشتر امکان ناپذیری را داشته باشد و همچنین در تابع هدف بیشتر ضریب را داشته باشد.
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 کلیک کنید.