Apply a binary fixing heuristic to an unpresolved MIP problem
|
|
Type: | Production planning |
Rating: | 3 (intermediate) |
Description: | We take a production plan model and solve its LP relaxation. This heuristic will speed up solution - though may fail to optimse the problem. The results are displayed on screen and the problem statistics stored in a log file. |
File(s): | FixBV.vb |
Data file(s): | coco.mat |
|
FixBV.vb |
Imports System Imports Microsoft.VisualBasic Imports Optimizer Imports System.IO Module FixBV Private Const TOL As Double = 0.0005 ' Tolerance on binary variables Public Sub RunFixBV(ByRef Log As TextWriter) Try Const sProblem As String = "..\Data\coco" ' Problem name Const sLogFile As String = "fixbv.log" ' Log file name Dim nCol As Integer ' Number of columns ' Global problem information Dim nGlEnt As Integer ' Number of global entities: binary, integer, ' semi-continuous and partial integer variables Dim nSet As Integer ' Number of S1 and S2 sets Dim pGlInd() As Integer ' Column indices of the global entities Dim pGlType() As Char ' Global entity types ' Bound changes Dim pBndInd() As Integer ' Column indices of the bounds to be changed Dim pBndType() As Char ' New bound type Dim pBndVal() As Double ' New bound values Dim nBnd As Integer ' Bound counter Dim i As Integer ' Loop counter Dim j As Integer ' Holder for the bound indices ' Solution information Dim x() As Double ' LP solution values Dim nGlStatus As Integer ' Global status Dim nNodes As Integer ' Number of nodes solves so far in global search Dim dObjVal As Double ' Objective value of the best integer solution ' Initialise Optimizer XPRS.Init("") Log.WriteLine(XPRS.GetBanner()) Dim prob As XPRSprob prob = New XPRSprob ' Delete and define log file If (File.Exists(sLogFile)) Then File.Delete(sLogFile) End If prob.SetLogFile(sLogFile) ' Tell Optimizer to call HandleOptimizerMessage whenever a message is output prob.AddMessageCallback(New Optimizer.MessageCallback(AddressOf HandleOptimizerMessage), Log) ' Get and display the Optimizer version number Log.WriteLine( _ vbCrLf & "Xpress Optimizer Subroutine Library Release {0}" & vbCrLf & vbCrLf, _ prob.Version / 100 _ ) ' Turn off presolve and permit no cuts - to slow down solution and allow ' the effect of the heuristic to be seen prob.Presolve = 0 prob.CutStrategy = 0 ' Read the problem file prob.ReadProb(sProblem, "") ' Solve the LP relaxation ' Get the number of columns nCol = prob.Cols ' Allocate memory for solution array and check for memory shortage ReDim x(nCol - 1) ' Solve the LP prob.Maxim("") ' Get the LP solution values prob.GetSol(x, Nothing, Nothing, Nothing) ' Fix the binary variables that are at their bounds ' Allocate memory for gloval entity arrays ReDim pGlInd(nCol - 1) ReDim pGlType(nCol - 1) ' Get global entity information prob.GetGlobal(nGlEnt, nSet, pGlType, pGlInd, Nothing, Nothing, DirectCast(Nothing, Long()), Nothing, Nothing) ' Allocate memory for bound arrays ReDim pBndInd(nGlEnt - 1) ReDim pBndVal(nGlEnt - 1) ReDim pBndType(nGlEnt - 1) ' Initialise the bound counter nBnd = 0 ' Go through the gloval entities For i = 0 To nGlEnt - 1 ' Test whether each is a binary variable If (pGlType(i) = "B") Then ' Hold the index of the BV j = pGlInd(i) ' If the value of the BV is within TOL of zero, store its index, ' set its upper bound to 0, and increment the bound counter If (x(j) <= TOL) Then pBndInd(nBnd) = j pBndType(nBnd) = "U" pBndVal(nBnd) = 0.0 nBnd = nBnd + 1 ' If the value of the BV is within TOL of one, store its index, ' set its lower bound to 1, and increment the bound counter ElseIf ((1 - x(j)) <= TOL) Then pBndInd(nBnd) = j pBndType(nBnd) = "L" pBndVal(nBnd) = 1.0 nBnd = nBnd + 1 End If End If Next ' Instruct the Optimizer to change the bounds of the appropriate BVs, ' and tell the user how many have been fixed prob.ChgBounds(nBnd, pBndInd, pBndType, pBndVal) Log.WriteLine("Solving problem {0} with a binary fixing heuristic" & _ vbCrLf & vbCrLf, sProblem) Log.WriteLine(" After the LP optiziation {0} binary variables were fixed" & _ vbCrLf & vbCrLf, nBnd) ' Solve the modified problem as a MIP ' Search for an integer solution prob.[Global]() ' Get th enumber of nodes solved in the global search nNodes = prob.Nodes ' Get the objective value of the best integer solution dObjVal = prob.MIPObjVal ' Check the global status and display the results of the global search nGlStatus = prob.MIPStatus Select Case nGlStatus Case 0 Log.WriteLine(" Problem has not been loaded") Case 1 Log.WriteLine(" Search has not begun - LP has not been optimised") Case 2 Log.WriteLine(" Search has not begun - LP has been optimised") Case 3 Log.WriteLine(" Search interrupted - No integer solution was found") Case 4 Log.WriteLine(" Search interrupted - Integer solution found: %g", dObjVal) Case 5 Log.WriteLine(" No integer solution was found") Case 6 Log.WriteLine(" Integer solution found: {0}", dObjVal) End Select Log.WriteLine(vbCrLf & vbCrLf & "The MIP optimisation took {0} nodes" & vbCrLf & vbCrLf, nNodes) ' Destroy the problem and free the optimizer prob.Destroy() XPRS.Free() Catch ex As Exception Log.WriteLine(ex.ToString) End Try End Sub Private Sub HandleOptimizerMessage(ByVal prob As Optimizer.XPRSprob, ByVal data As Object, _ ByVal message As String, ByVal len As Integer, _ ByVal msglvl As Integer) Dim log As TextWriter log = data If (msglvl = 3 Or msglvl = 4) Then log.WriteLine(message) End If End Sub End Module |
© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.