如何大声选择数组中的k个最小元素?

时间:2013-09-19 17:29:48

标签: algorithm

所以我编写了一个函数来查找具有最小度数的图的k个节点。它看起来像这样:

def smallestKNodes(G, k):
    leastK = []
    for i in range(G.GetMxNId()):
        # Produces an iterator to the node
        node = G.GetNI(i)
        for j in range(k):
            if j >= len(leastK):
                leastK.append(node)
                break
            elif node.GetDeg() < leastK[j].GetDeg():
                leastK.insert(j, node)
                leastK = leastK[0:k]
                break
    return leastK[0:k]

我的问题是当所有节点具有相同的度数时,它每次都选择相同的节点。我怎样才能使所有节点都具有零度或其他值,然后随机选择k个节点?

规定:

(1)假设k = 7,那么如果3个节点的度数为0,10个节点的度数为1,我想选择度数为0的所有节点,但随机选择4个度数为1的节点。

(2)如果可能的话,我不想两次访问任何节点,因为可能有太多节点无法容纳到内存中。可能还存在具有最小程度的非常大量的节点。在某些情况下,可能还会有非常少量的节点。

2 个答案:

答案 0 :(得分:2)

存储满足条件的所有节点,并随机选择k个节点。您可以通过对阵列进行混洗来执行随机选择(例如Fisher-Yatesstd::shufflerandperm等)并选择第一个k节点(例如)。

答案 1 :(得分:1)

您可能希望进行两次传递,第一次传递以发现您必须随机化的相关度数,选择该度数的节点数以及具有该度数的节点总数。然后,在节点上进行第二次传递,只选择那些具有所需度数的节点。

要选择总共kn节点,以便每个节点都有一个合理的概率(k/n),循环相关节点,并选择概率为1,1的每个节点。 。,1,k /(k + 1),k /(k + 2),...,k / n。选择节点时,如果已选择k个节点,则随机丢弃其中一个节点。

def randomNodesWithSpecificDegree(G, d, k, n):
    result = []
    examined = 0
    for i in range(G.GetMxNId()):
        # Produces an iterator to the node
        node = G.GetNI(i)
        if node.GetDeg() = d:
            examined = examined + 1
            if len(result) < k:
                result.append(node)
            elif random(0...1) < k / examined
                index = random(0...k-1)
                result[index] = node
    assert(examined = n)
    return result

k很小且n很大(看起来像你的情况)时,这个伪代码很好。