-
Notifications
You must be signed in to change notification settings - Fork 1
Using SolverWrapper Events
An arguably more powerful alternative to the callback function for monitoring optimization progress is through the use of SolverWrapper native events, albeit at the cost of a little more work. There are three native events: BeforeSolve which fires once before optimization begins, ShowTrial that fires on each trial solution, and AfterSolve which fires after optimization is completed. Below is an example of how to set up your own event class and connect that to SolverWrapper.
In order for SolverWrapper events to be triggered, the EnableEvents property of the SolvSolver class must be set to True, and a user-created event sink instantiated, as in the following example:
'enable SolverWrapper native events
oProblem.Solver.EnableEvents = True
If oProblem.Solver.EnableEvents Then
'connect-up user-created events processing class
Dim eventSink As SolverEventSink
Set eventSink = New SolverEventSink
Set eventSink.Problem = oProblem
End If
oProblem.SolveIt
In order then to process the SolverWrapper events, the user should create their own event sink class, such as the example below:
'Class Name: SolverEventSink (user preference)
'@ModuleDescription "This is an example of a user-written class to process events triggered by the SolvProblem class."
'@folder("SolverWrapper.Examples")
'The EnableEvents property of the SolvSolver class must be set to True to activate SolverWrapper events
Private WithEvents oProblem As SolvProblem
Private Sub oProblem_ShowTrial(ByVal reason As Long, ByVal trialNum As Long, stopSolver As Boolean)
'this event is triggered for any one of the reasons below
Dim i As Long
Debug.Print "Trial number: " & trialNum
Debug.Print "Objective: " & oProblem.Objective.CellRange.value
For i = 1 To oProblem.DecisionVars.Count
Debug.Print oProblem.DecisionVars.CellRange(i).Address, oProblem.DecisionVars.CellRange(i).value
Next i
Debug.Print "Constraints Satisfied? " & oProblem.Constraints.AreSatisfied
'decide whether to stop solver based on the reason for the event trigger
Select Case reason
Case SlvCallbackReason.slvShowIterations 'new iteration has completed or user hit esc key
stopSolver = False
Case SlvCallbackReason.slvMaxTimeLimit
stopSolver = True 'if set to True then solver is stopped!
Case SlvCallbackReason.slvMaxIterationsLimit
stopSolver = False
Case SlvCallbackReason.slvMaxSubproblemsLimit
stopSolver = False
Case SlvCallbackReason.slvMaxSolutionsLimit
stopSolver = False
End Select
End Sub
Private Sub oProblem_BeforeSolve(stopSolver As Boolean)
Debug.Print "Solver started on Worksheet: " & oProblem.SolverSheet.Name
End Sub
Private Sub oProblem_AfterSolve(ByVal returnMsgCode As Long, ByVal trialNum As Long)
Debug.Print "Solver completed with iterations= " & trialNum
Debug.Print "Solver return code= " & oProblem.Solver.MsgCodeToString(returnMsgCode)
End Sub
Public Property Set Problem(obj As SolvProblem)
Set oProblem = obj
End Property
Private Sub Class_Terminate()
Set oProblem = Nothing
Debug.Print "terminating SolvEventSink"
End Sub
Getting Started
How-to Topics
- Solver Primer
- A Walkthrough Example
- Using the Enhanced Callback
- Using SolverWrapper Events
- ActiveX DLL FAQ
- Using Without Registration
Object Model Overview