【问题标题】:Sort using sub-arrays使用子数组排序
【发布时间】:2021-10-02 23:58:52
【问题描述】:

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

我的尝试: 我已经对此进行了模拟,其中提交是来自 0-num 提交的数字,然后我通过采用排序数组并以 75%、50%、25% 和 12% 的概率进行 1、2、3 或 4 次交换来引入一些人为错误.我对算法的第一次尝试如下。我们将数组拆分为 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()

【问题讨论】:

  • 请同时发布您的代码。
  • 你可以使用一个元组列表或者一个 numpy 元组数组。 numpy 使切片变得非常容易,并且可以使用 sort 方法对元组列表进行排序。您可以使用 lambda 函数告诉 python 如何以及根据哪个元素对元组进行排序
  • 我不确定我的问题是否被很好地理解,我的目标是仅使用多个迷你 5 元素子数组排序的信息进行排序。这应该以某种方式对主数组进行排序。 @alexschu98
  • 为了确保我理解正确:你有你的元组数组(num,times_sorted)。您将此数组分割成五个子数组,并根据 times_sorted 对每个子数组进行排序。您从这五个子数组中的每一个中选择具有最低 times_sorted 值的元素,并将它们放入一个新数组中。这个新数组会根据您在帖子中提供的概率进行一些随机交换。新的排序数组被复制回原始索引处的原始数组。我做对了吗?
  • 是的,这是我目前的做法。但是,它似乎不太好用,我想知道如何改进它,或者是否有另一种算法可以让它变得更好。

标签: python arrays algorithm sorting


【解决方案1】:

如果您仍然对使用 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)

我想这是不言自明的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 2012-07-28
    • 2011-12-21
    • 2017-10-15
    • 2012-08-16
    • 2020-01-10
    • 2011-01-29
    相关资源
    最近更新 更多