VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END Attribute VB_Name = "PowerEstimator" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = False Attribute VB_Exposed = False ' ====== Estimate power level according to graph synthesis ==== Option Explicit Private graph_ As CDS_Graph Private powerLevels_ As Scripting.Dictionary Private visiting_ As Scripting.Dictionary Private reps_ As Scripting.Dictionary Public Function Estimate(iGraph As CDS_Graph, iOrder As Collection, iReps As Scripting.Dictionary) As Scripting.Dictionary Set graph_ = iGraph Set reps_ = iReps Call Reset Dim vNode As Variant For Each vNode In iOrder Call GetPowerRecursive(vNode) Next vNode Set Estimate = powerLevels_ End Function ' =========== Private Function Reset() Set powerLevels_ = New Scripting.Dictionary Set visiting_ = New Scripting.Dictionary Set reps_ = New Scripting.Dictionary End Function Private Function GetPowerRecursive(vNode As Variant) As Long If reps_.Exists(vNode) Then _ vNode = reps_(vNode) If visiting_.Exists(vNode) Then Call MsgBox("Внимание! Граф синтеза содержит цикл!", vbExclamation) ' TODO: extract message and raise error instead GetPowerRecursive = 0 Exit Function End If If powerLevels_.Exists(vNode) Then GetPowerRecursive = powerLevels_(vNode) Exit Function End If Call visiting_.Add(vNode, 0) Dim parentCount&: parentCount = graph_.nodes_(vNode).inputs_.Count Dim nLevel& If parentCount = 0 Then nLevel = 1 Else nLevel = 0 Dim vChild As Variant For Each vChild In graph_.nodes_(vNode).inputs_ nLevel = nLevel + GetPowerRecursive(vChild) Next vChild End If Call visiting_.Remove(vNode) Call powerLevels_.Add(vNode, nLevel) GetPowerRecursive = nLevel End Function