-
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