-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path4_Voting_ZermeloTree.ps1
More file actions
93 lines (82 loc) · 2.26 KB
/
4_Voting_ZermeloTree.ps1
File metadata and controls
93 lines (82 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#region +INPUT
$p1 = @('A','B','C','D')
$p2 = @('D','B','C','A')
$p3 = @('A','C','B','D')
$players = @($p1,$p2,$p3)
#endregion _INPUT
$initPool = New-Object Collections.Generic.List[string]
$p1 | % { $initPool.Add($_) }
$root = @{
Pool = $initPool
Removed = $null
Prev = $null
Next = New-Object Collections.Generic.List[Object]
}
function CreateDecisionTree
{
Param(
[object] $node
)
$pool = $node.Pool
foreach($i in $pool) {
$newPool = New-Object Collections.Generic.List[string]
$pool | ? { $_ –ne $i } | % { $newPool.Add($_) }
$cnode = @{
Pool = $newPool
Removed = $i
Prev = $node
Next = New-Object Collections.Generic.List[Object]
}
$node.Next.Add($cNode)
if ($newPool.Count -gt 1) {
CreateDecisionTree $cnode
}
}
}
function TraverseDecisionTree
{
Param(
[object] $node,
[string] $path = '()'
)
if ($node.Removed) {
$path += (" -> {0}" -f $node.Removed)
}
if ($node.Next.Count) {
foreach ($n in $node.Next) {
TraverseDecisionTree $n $path
}
}
else {
$path += (" -> {0}" -f $node.Pool[0])
$path
}
}
function ZermeloCutDecisionTree
{
Param(
[object] $node,
[int] $level = 0
)
if ($node.Next.Count) {
if ( ($players.Count-1) -lt $level) {
throw ("Mismatch between Current Level ({0}) and Players Array max index ({1})" -f $level, $players.Count-1)
}
$playerPreferences = $players[$level]
$bestItemIndex = [int]::MaxValue
foreach ($n in $node.Next) {
ZermeloCutDecisionTree $n ($level+1)
$lastItemInPool = $n.Pool[0]
$lastItemInPoolIndex = $playerPreferences.indexOf($lastItemInPool)
if ($lastItemInPoolIndex -lt $bestItemIndex) {
$bestItemIndex = $lastItemInPoolIndex
}
}
$bestItem = $playerPreferences[$bestItemIndex]
$node.Next.RemoveAll({ param($n) ($n.Pool[0] -ne $bestItem) }) | Out-Null
$node.Pool.RemoveAll({ param($n) ($n -ne $bestItem) }) | Out-Null
}
}
CreateDecisionTree $root
ZermeloCutDecisionTree $root
TraverseDecisionTree $root