我正在尝试根据以下思路创建算法:
-创建8位参与者
-每个参与者都有一套兴趣爱好
-与其他兴趣最少的参与者配对
因此,到目前为止,我要做的是创建两个类,即Participant和Interest,其中Interest是可哈希的,这样我就可以用它创建Set。我手动创建了8个具有不同名称和兴趣的参与者。
我已经选择了一组参与者,并且使用了一个基本的for in loop来使用sets的交集()函数将他们稍微配对在一起。不知何故我的索引总是超出范围,我很肯定有更好的方法可以做到这一点,但是它太乱了,我不知道从哪里开始。
for i in 0..<participantsSelected.count {
if participantsSelected[i].interest.intersection(participantsSelected[i+1].interest) == [] {
participantsSelected.remove(at: i)
participantsSelected.remove(at: i+1)
print (participantsSelected.count)
}
}
因此,我的另一个问题是针对此特定算法使用for循环似乎也有些偏离,因为如果它们都具有1个相似的兴趣,那将不等于[] / nil。
基本上,我正在尝试的输出是在配对后将它们从参与者选定的数组中删除,并且要使其配对,它们将必须与彼此兴趣最少的另一个参与者在一起
编辑:更新的代码,这是我尝试改善算法逻辑的尝试
for participant in 0..<participantsSelected {
var maxInterestIndex = 10
var currentIndex = 1
for _ in 0..<participantsSelected {
print (participant)
print (currentIndex)
let score = participantsAvailable[participant].interest.intersection(participantsAvailable[currentIndex].interest)
print ("testing score, \(score.count)")
if score.count < maxInterestIndex {
maxInterestIndex = score.count
print ("test, \(maxInterestIndex)")
} else {
pairsCreated.append(participantsAvailable[participant])
pairsCreated.append(participantsAvailable[currentIndex])
break
// participantsAvailable.remove(at: participant)
// participantsAvailable.remove(at: pairing)
}
currentIndex = currentIndex + 1
}
}
for i in 0..<pairsCreated.count {
print (pairsCreated[i].name)
}
答案 0 :(得分:0)
如果您要寻找的是与您的参与者(所有参与者)最佳匹配的标准,这是一种解决方案:
然后的方法是在参与者图中找到完美的匹配。
创建一个具有n
个顶点的图形,其中n
是参与者的数量。我们可以用u_p
表示与参与者p
相对应的顶点。
然后,如下创建加权边:
对于每对参与者p, q
(p!= q),创建边(u_p, u_q)
,并用这两个参与者共同拥有的兴趣数量对其进行加权。
然后,在图形上运行最小权重完美匹配算法,即可完成工作。您将在多项式时间内获得最佳结果(意味着最好的匹配,或最好的匹配之一)。
最小权重完美匹配算法:该问题严格等效于最大权重匹配算法。找到最大重量的边缘(用C
表示其重量)。然后将每个边的权重w
替换为C-w
,然后在结果图上运行最大权重匹配算法。
我建议您使用Edmond's blossom algorithm在您的图表中找到完美的匹配项。首先是因为它高效且有据可查,其次是因为我相信您可以在大多数现有语言中找到实现,而且还因为它确实是一种非常非常漂亮的算法(它没有花钱就没有花)。
另一种可能性,如果您确定参与者的数量会很少(您提到8个),那么您也可以采用蛮力算法,这意味着可以测试与参与者配对的所有可能方式。 然后该算法将如下所示:
find_best_matching(participants, interests, pairs):
if all participants have been paired:
return sum(cost(p1, p2) for p1, p2 in pairs), pairs // cost(p1, p2) = number of interests in common
else:
p = some participant which is not paired yet
best_sum = + infinite
best_pairs = empty_set
for all participants q which have not been paired, q != p:
add (p, q) to pairs
current_sum, current_pairs = find_best_matching(participants, interests, pairs)
if current_sum < best_sum:
best_sum = current_sum
best_pairs = current_pairs
remove (p, q) from pairs
return best_sum, best_pairs
最初使用find_best_matching(participants, interests, empty_set_of_pairs)
进行调用,以获得匹配参与者的最佳方法。