首页 > 解决方案 > 使用子数组排序

问题描述

问题:嘿,我正在尝试创建一个网站,通过让用户提交他们自己的作品,然后对其他五个提交的作品进行排名,从最佳到最差,对某些提交进行排名。

我的尝试:我已经对此进行了模拟,其中提交是来自 0-num 提交的数字,然后我通过采用排序数组并在 75%、50%、25% 和12%的概率。我对算法的第一次尝试如下。我们将数组拆分为 5 个子数组,然后根据每个数字已经排序的次数对每个子数组进行排序,并在每个子数组中挑选最小的数字。然后我用我的模拟错误对它们进行排序,并将它们放回正确的索引中。

例如,如果我将初始数组设置为 (format num:times_been_sorted)

[1:0, 11:0, 29:0, 7:0, 0:0, 21:0, 2:0, 27:0, 25:0, 28:0, 22:0, 5:0, 4 :0, 14:0, 10:0, 20:0]

并根据 5 的拆分和每个数字历史 [0, 3, 6, 9, 12] 选择以下索引

我的初始子数组是这个 [1:0, 7:0, 2:0, 28:0, 4:0]

我的排序子数组是这个 [1:0, 2:0, 4:0, 7:0, 28:0]

我的新数组是这个 [1:1, 11:0, 29:0, 2:1, 9:0, 0:0, 21:0, 4:1, 27:0, 25:0, 7:1 , 22:0, 5:0, 28:1, 14:0, 10:0, 20:0]

我完全自己想出了这个,所以我确信还有改进的空间或其他完全可以使用的算法,并且没有出现在我的研究中。我真的很感激任何形式的指导。谢谢!

编辑:

我的模拟代码在这里:

from random import randrange
import matplotlib.pyplot as plt
from random import randrange
import matplotlib.pyplot as plt
import random
class Submission:
    def __init__(self, num):
        self.num = num 
        self.picks = 0

    def __repr__(self):
        return str(self.num) + ":" + str(self.picks)

def select_idx(arr):
    idxs = []
    top = int(len(arr) / subarray_size)

    for i in range(subarray_size):
        sort = sorted(range(top * i, top * (i + 1)), key=lambda k: arr[k].picks)
        idxs.append(sort[0])

    return idxs

def sort_w_error(arr, err):
    sort = sorted(arr, key=lambda x: x.num)
    rand = random.uniform(0, 1)
    if err: 
        if rand < 0.75:
            sort = swap(sort, randrange(len(arr)), randrange(len(arr)))
            if rand < 0.5:
                sort = swap(sort, randrange(len(arr)), randrange(len(arr)))
                if rand < 0.25:
                    sort = swap(sort, randrange(len(arr)), randrange(len(arr)))
                    if rand < 0.12:
                        sort = swap(sort, randrange(len(arr)), randrange(len(arr)))
    
    return sort

n = 400
subarray_size = 5
submissions_entries = random.sample(range(n), n)
submissions = []
for submission in submissions_entries:
    submissions.insert(randrange(len(submissions) + 1), Submission(submission))
    if len(submissions) > subarray_size:
        random_idxs = select_idx(submissions)
        random_arr = []
        for idx in random_idxs:
            random_arr.append(submissions[idx])
        sort_arr = sort_w_error(random_arr, False)
        sorted_idxs = sorted(random_idxs, key=lambda x: x)
        for i, idx in enumerate(sorted_idxs):
            submissions[idx] = sort_arr[i]
            submissions[idx].picks = submissions[idx].picks + 1
print(submissions)

for idx, submission in enumerate(submissions):
    if submission.picks <= 1:
        plt.plot(idx, submission.num, 'b.')
    elif submission.picks <= 3:
        plt.plot(idx, submission.num, 'c.')
    elif submission.picks <= 5:
        plt.plot(idx, submission.num, 'g.')
    elif submission.picks <= 7:
        plt.plot(idx, submission.num, 'r.')
    else:
        plt.plot(idx, submission.num, 'k.')

plt.show()

标签: pythonarraysalgorithmsorting

解决方案


如果您仍然对使用 elo 系统感兴趣,我有一些直截了当的代码供您使用:

class EloSystem:
    def __init__(self, K=32):
        self.K = K # K factor which gives the max change in the elo number
        self.Players = dict() # empty dict using player name as uniqe id

    def addPlayer(self, name, elo=1500):
        self.Players[name] = elo

    def getWinProbability(self, PlayerA, PlayerB):
        p = (self.Players[PlayerB] - self.Players[PlayerA]) / 400.0
        E = 1.0 / (1.0 + 10**(p))
        return E

    def updatePlayerElo(self, Winner, Loser):
        E = self.getWinProbability(Winner, Loser)
        self.Players[Winner] += self.K * (1.0 - E)
        self.Players[Loser] -= self.K * (1.0 - E)

我想这是不言自明的。


推荐阅读