我已阅读Smith Set,Schwartz Set,Kosaraju's Algorithm,Tarjan's Algorithm和path-based strongly component algorithms上的Wikipedia;但是,我对此类算法的经验不足。维基百科还说,您可以使用Kosaraju算法的版本来生成Schwartz集,并且这些算法可以计算Smith集。
Wikpedia也有一些针对Tarjan算法的伪代码,而其他的则没有。它并不特定于此相对敏感的应用程序。我也不确定100%是最容易实现的,它具有实现错误可能性最小的特征。
我想要一些更直接的伪代码来涵盖从这些算法中的一种算法计算Smith和Schwartz集合的情况,并给出一组有等级的选票。当我有一个实际的过程可以走路时,我发现更容易掌握概念。我自己将其转换为实际代码。
请考虑以下数据结构:
Type Ballot {
Array Votes[] {
Candidate Candidate; // We do this in C#
int Rank;
}
}
对于一个选票集合,每个单独的选票将包含一个数组选票,如下所示:
Ballot b.Votes[] =
[ Vote(Alex.ID, 1),
Vote(Chris.ID, 3),
Vote(Sam.ID, 2) ];
这对应于投票者Alex>Sam>Chris
,并且可能还有其他候选人比克里斯受到同样的青睐。
我认为第一步将是汇总个人选票并确定获胜情况。例如:如果100个投票者将Alex排在Sam之上(Alex = 1,Sam> = 2),而50个投票者将Sam排在Alex之上,则Alex击败了Sam。因此,我猜想会有这样的数据结构:
Type GraphNode {
Candidate Candidate;
GraphNode Array Defeats[];
GraphNode Array Ties[];
GraphNode Array DefeatedBy[];
}
因此,Alex的GraphNode在Defeats[]
中将有一个元素指向Sam的GraphNode,反之亦然。
鉴于这些GraphNode,我该如何使用它来识别Smith和Schwartz集?
谢谢。
答案 0 :(得分:1)
我想python已经足够接近伪代码了。
假设我们有n
个候选人,编号从0
到n - 1
。
首先,如果候选人beats[i][j]
胜过候选人True
,而矩阵i
胜过j
,则可以计算等于False
的矩阵for k in range(n):
for i in range(n):
for j in range(n):
beats[i][j] = beats[i][j] or (beats[i][k] and beats[k][j])
。
现在使用Floyd-Warshall算法计算矩阵的传递闭合:
beats[i][j]
此后,矩阵的含义略有不同:i -> c1 -> c2 -> ... -> j
表示存在“拍子路径” i
,使得c1
拍子c1
,c2
胜过j
,依此类推,直到i
。
Schwartz组件是所有对j
,i
都具有双向运行的跳动路径,并且没有其他候选者可以击败任何一个(请参阅Wikipedia上有关属性的部分提到顶部循环)。
基本上针对每个候选人schwartz_components = []
for i in range(n):
schwartz_component = {i}
is_schwartz = True
for j in range(n):
if beats[j][i]:
if beats[i][j]:
schwartz_component.add(j)
else:
is_schwartz = False
if is_schwartz:
schwartz_components.append(schwartz_component)
schwartz_set = set.union(*schwartz_components)
print(schwartz_set)
,尝试围绕它构建一个组件,如下所示:
cannot_beat[i][j] = not beats[i][j]
对于史密斯集,它会有所不同,您需要从i
开始,在其上使用Floyd-Warshall,然后通过添加所有候选项围绕每个cannot_beat
构建集通过smith_candidates = []
for i in range(n):
smith_candidate = {i}
for j in range(n):
if cannot_beat[i][j]:
smith_candidate.add(j)
smith_candidates.append(smith_candidate)
# Take the smallest candidate
smith_set = min(smith_candidates, key=len)
关系到它的路径。
我想它会变成这样(在Floyd-Warshall步骤之后):
OSError[errno 2]
某处可能存在一个错误,但这大概就是这个想法。