로 수행됩니다
# Idea from http://stackoverflow.com/questions/7468707/deep-copy-a-dictionary-hashtable-in-powershell
function Get-ClonedObject {
param($DeepCopyObject)
$memStream = new-object IO.MemoryStream
$formatter = new-object Runtime.Serialization.Formatters.Binary.BinaryFormatter
$formatter.Serialize($memStream,$DeepCopyObject)
$memStream.Position=0
$formatter.Deserialize($memStream)
}
에
function Get-TopologicalSort {
param(
[Parameter(Mandatory = $true, Position = 0)]
[hashtable] $edgeList
)
# Make sure we can use HashSet
Add-Type -AssemblyName System.Core
# Clone it so as to not alter original
$currentEdgeList = [hashtable] (Get-ClonedObject $edgeList)
# algorithm from http://en.wikipedia.org/wiki/Topological_sorting#Algorithms
$topologicallySortedElements = New-Object System.Collections.ArrayList
$setOfAllNodesWithNoIncomingEdges = New-Object System.Collections.Queue
$fasterEdgeList = @{}
# Keep track of all nodes in case they put it in as an edge destination but not source
$allNodes = New-Object -TypeName System.Collections.Generic.HashSet[object] -ArgumentList (,[object[]] $currentEdgeList.Keys)
foreach($currentNode in $currentEdgeList.Keys) {
$currentDestinationNodes = [array] $currentEdgeList[$currentNode]
if($currentDestinationNodes.Length -eq 0) {
$setOfAllNodesWithNoIncomingEdges.Enqueue($currentNode)
}
foreach($currentDestinationNode in $currentDestinationNodes) {
if(!$allNodes.Contains($currentDestinationNode)) {
[void] $allNodes.Add($currentDestinationNode)
}
}
# Take this time to convert them to a HashSet for faster operation
$currentDestinationNodes = New-Object -TypeName System.Collections.Generic.HashSet[object] -ArgumentList (,[object[]] $currentDestinationNodes)
[void] $fasterEdgeList.Add($currentNode, $currentDestinationNodes)
}
# Now let's reconcile by adding empty dependencies for source nodes they didn't tell us about
foreach($currentNode in $allNodes) {
if(!$currentEdgeList.ContainsKey($currentNode)) {
[void] $currentEdgeList.Add($currentNode, (New-Object -TypeName System.Collections.Generic.HashSet[object]))
$setOfAllNodesWithNoIncomingEdges.Enqueue($currentNode)
}
}
$currentEdgeList = $fasterEdgeList
while($setOfAllNodesWithNoIncomingEdges.Count -gt 0) {
$currentNode = $setOfAllNodesWithNoIncomingEdges.Dequeue()
[void] $currentEdgeList.Remove($currentNode)
[void] $topologicallySortedElements.Add($currentNode)
foreach($currentEdgeSourceNode in $currentEdgeList.Keys) {
$currentNodeDestinations = $currentEdgeList[$currentEdgeSourceNode]
if($currentNodeDestinations.Contains($currentNode)) {
[void] $currentNodeDestinations.Remove($currentNode)
if($currentNodeDestinations.Count -eq 0) {
[void] $setOfAllNodesWithNoIncomingEdges.Enqueue($currentEdgeSourceNode)
}
}
}
}
if($currentEdgeList.Count -gt 0) {
throw "Graph has at least one cycle!"
}
return $topologicallySortedElements
}
이 의존을 그리고 당신이 그것을 사용 like
# Sort the Wikipedia example:
Get-TopologicalSort @{[email protected](7,5);[email protected](7,3);[email protected](11);[email protected](11,8);[email protected](11,3)}
산출
:
7
5
3
11
8
10
2
9
당신은 단순히 C#으로 그것을 구현할 수는 DLL을로드하고 PowerShell을에서 그것을 사용할 수 있습니다. 'Add-Type'으로 인라인 할 수도 있습니다. – Joey
시각화를 위해 yEd를 사용하고 형식을 위해 GraphML을 사용하여 앤트에 대해이 작업을 수행했습니다. 블로그에 대해 블로그를 게시하고 여기에 다시 게시해야합니다. :) – JasonMArcher
@JasonMArcher : 친구 게시물을 작성 했습니까? – Samselvaprabu