, , . :
(!)
, , :
$Script:NodeTracker = @{}
class TaskNode {
[System.Collections.ArrayList]$then = @()
[String] $Val
[Bool]$Visited = $false
[Collections.ArrayList]$Parent = @()
TaskNode([String]$Val) {$this.constructor($Val, $null)}
TaskNode([String]$Val, [TaskNode]$Parent) {$this.constructor($Val, $Parent)}
hidden constructor([String]$Val, [TaskNode]$Parent) {
$This.Val = $Val
if ($Parent) {$This.Parents.Add($Parent)}
$Script:NodeTracker.$Val = $This
}
[TaskNode] To([String]$Val) {
$Node = $Script:NodeTracker.$Val
if (!$Node) {$Node = New-Object TaskNode $Val}
$This.then.Add($Node)
$Node.Parent.Add($This)
return $Node
}
[String] ToString() {return "$($this.val)-$(if($this.Visited){'β'}else{'β'})"}
static [String] ReverseModdedBFS([Collections.Queue]$Queue) {
$Output = ""
[Collections.Queue]$NextQueue = @()
do {
while ($Queue.Count) {
$Root = $Queue.Dequeue()
if ($Root.Visited) {continue}
if ($Root.Then.Count -gt 1 -and ($Root.then | {!$_.Visited})) {$NextQueue.Enqueue($Root);continue}
$Root.Visited = $true
$Output += ','+$Root.Val
$Root.Parent | % {
$Queue.Enqueue($_)
}
}
If ($Queue.Count -eq 1 -and !$Queue.Peek().Parent.count) {break}
$Queue = $NextQueue
$NextQueue = @()
} while($Queue.Count)
$Out = $Output.Substring(1).split(',')
[Array]::Reverse($Out)
return $Out -join ','
}
static [TaskNode] Fetch([String]$Val) {
$Node = $Script:NodeTracker.$Val
if (!$Node) {return (New-Object TaskNode $Val)}
return $Node
}
static [TaskNode[]] GetAll() {
return @($Script:NodeTracker.Values)
}
static [TaskNode] GetStart() {
$Nodes = [TaskNode]::GetAll() | {$_.Parent.count -eq 0}
if ($Nodes.Count -gt 1) {throw 'There is more than one starting node!'}
if (!$Nodes.Count) {throw 'There is no starting node!'}
return @($Nodes)[0]
}
static [TaskNode[]] GetEnds() {
$Nodes = [TaskNode]::GetAll() | {$_.Then.count -eq 0}
if (!$Nodes.Count) {throw 'There is no ending node!'}
return @($Nodes)
}
}
function Parse-Edge($From, $To) {
[TaskNode]::Fetch($From).To($To)
}
function XML-Main([xml]$XML) {
@($XML.Flow.Task) | % {Parse-Edge $_.From $_.To}
[TaskNode]::ReverseModdedBFS([TaskNode]::GetEnds())
}
!
:
$Root = [TaskNode]::Fetch('O')
$root.To('A').To('B').To('C').To('H').To('Z').To('M')
$Root.To('D').To('E').To('C').To('H').To('I').To('M')
$Root.To('F').To('G').To('C').To('H').To('J').To('M')
[TaskNode]::Fetch('C').To('K').To('L').To('M')
[TaskNode]::ReverseModdedBFS([TaskNode]::GetEnds())
Root: M-β | Queue: [] | Next-Queue [] | Non-Visited []
Enqueuing Z-β
Enqueuing I-β
Enqueuing J-β
Enqueuing L-β
Root: Z-β | Queue: [I-β J-β L-β] | Next-Queue [] | Non-Visited []
Enqueuing H-β
Root: I-β | Queue: [J-β L-β H-β] | Next-Queue [] | Non-Visited []
Enqueuing H-β
Root: J-β | Queue: [L-β H-β H-β] | Next-Queue [] | Non-Visited []
Enqueuing H-β
Root: L-β | Queue: [H-β H-β H-β] | Next-Queue [] | Non-Visited []
Enqueuing K-β
Root: H-β | Queue: [H-β H-β K-β] | Next-Queue [] | Non-Visited []
Enqueuing C-β
Enqueuing C-β
Enqueuing C-β
Root: H-β | Queue: [H-β K-β C-β C-β C-β] | Next-Queue [] | Non-Visited []
Root: H-β | Queue: [K-β C-β C-β C-β] | Next-Queue [] | Non-Visited []
Root: K-β | Queue: [C-β C-β C-β] | Next-Queue [] | Non-Visited []
Enqueuing C-β
Root: C-β | Queue: [C-β C-β C-β] | Next-Queue [] | Non-Visited []
Enqueuing B-β
Enqueuing E-β
Enqueuing G-β
Root: C-β | Queue: [C-β C-β B-β E-β G-β] | Next-Queue [] | Non-Visited []
Root: C-β | Queue: [C-β B-β E-β G-β] | Next-Queue [] | Non-Visited []
Root: C-β | Queue: [B-β E-β G-β] | Next-Queue [] | Non-Visited []
Root: B-β | Queue: [E-β G-β] | Next-Queue [] | Non-Visited []
Enqueuing A-β
Root: E-β | Queue: [G-β A-β] | Next-Queue [] | Non-Visited []
Enqueuing D-β
Root: G-β | Queue: [A-β D-β] | Next-Queue [] | Non-Visited []
Enqueuing F-β
Root: A-β | Queue: [D-β F-β] | Next-Queue [] | Non-Visited []
Enqueuing O-β
Root: D-β | Queue: [F-β O-β] | Next-Queue [] | Non-Visited []
Enqueuing O-β
Root: F-β | Queue: [O-β O-β] | Next-Queue [] | Non-Visited []
Enqueuing O-β
Root: O-β | Queue: [O-β O-β] | Next-Queue [] | Non-Visited []
Root: O-β | Queue: [O-β] | Next-Queue [] | Non-Visited []
Root: O-β | Queue: [] | Next-Queue [] | Non-Visited []
O,F,D,A,G,E,B,C,K,H,L,J,I,Z,M
graph OOP. - (.. , ). BFS, node, :
, , . :