top-k的应用

top-k的应用

topk指的是,保存一段数据的最大或者最小的k位数,在code中或者工程中右很重要的应用。
举例:
查询超大量数据中 最小或者最大的 第 k位数。
正常使用排序
缺点:内存占用会超出正常范围
相对简单的做法是,遍历K次,每次选出最小(或者最大的)数。最后返回结果
缺点:时间复杂度为KN,而且需要删除原数据中的数或者要在已有数据中进行判断
简化:
形成一个topk的 最大堆。内部使用堆排序的 shiftup 以及 shiftdown。从左到右进行遍历一次。最后pop root即可找到答案。时间复杂度(Nlogk)

215. Kth Largest Element in an Array

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Example 1:

Input: [3,2,1,5,6,4] and k = 2
Output: 5
Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4

代码:

class kheap:
    def __init__(self):
        self.heap = []
        
    def shift_up(self,x):
        self.heap.append(x)
        l = len(self.heap)
        i = l-1
        while i>0:
            root = (i-1)//2
            if self.heap[root]>self.heap[i]:
                self.heap[i],self.heap[root] = self.heap[root],self.heap[i]
            else:
                break
            i = root
    
    def shift_down(self):
        if len(self.heap)==0:
            return 
        elif len(self.heap) == 1:
            return self.heap.pop()
        
        tar = self.heap.pop(0)
        self.heap = [self.heap[-1]] + self.heap[:-1]
        l = len(self.heap)
        i = 0
        while i <= (l-2)//2:
            left = 2*i+1
            right = 2*i+2
            if right <= l-1:
                if self.heap[i]>self.heap[left] and self.heap[left]<=self.heap[right]:
                    self.heap[i],self.heap[left] = self.heap[left],self.heap[i]
                    i=left
                elif self.heap[i]>self.heap[right] and self.heap[right]<=self.heap[left]:
                    self.heap[i],self.heap[right] = self.heap[right],self.heap[i]
                    i=right
                else:
                    break
            else:
                if self.heap[i]>self.heap[left]:
                    self.heap[i],self.heap[left] = self.heap[left],self.heap[i]
                    i=left
                else:
                    break
        return tar

字节跳动面试题:在一个无序数组中,每个元素与排序好的位置距离<=k,对数组进行排序

最小堆然后遍历
代码:

class Solution:
    def k_sort(self,arr,k):
        myheap = kheap()
        for i in range(k):
            if not arr:
                break
            myheap.shift_up(arr.pop(0))
        res = []
        while  arr:
            myheap.shift_up(arr.pop(0))
            res.append(myheap.shift_down())
            #print(res,'#')
        while myheap.heap:
            res.append(myheap.shift_down())
        return res

class kheap:
    def __init__(self):
        self.heap = []

    def shift_up(self, x):
        self.heap.append(x)
        l = len(self.heap)
        i = l - 1
        while i > 0:
            root = (i - 1) // 2
            if self.heap[root] > self.heap[i]:
                self.heap[i], self.heap[root] = self.heap[root], self.heap[i]
            else:
                break
            i = root

    def shift_down(self):
        if len(self.heap) == 0:
            return
        elif len(self.heap) == 1:
            return self.heap.pop()

        tar = self.heap.pop(0)
        self.heap = [self.heap[-1]] + self.heap[:-1]
        l = len(self.heap)
        i = 0
        while i <= (l - 2) // 2:
            left = 2 * i + 1
            right = 2 * i + 2
            if right <= l - 1:
                if self.heap[i] > self.heap[left] and self.heap[left] <= self.heap[right]:
                    self.heap[i], self.heap[left] = self.heap[left], self.heap[i]
                    i = left
                elif self.heap[i] > self.heap[right] and self.heap[right] <= self.heap[left]:
                    self.heap[i], self.heap[right] = self.heap[right], self.heap[i]
                    i = right
                else:
                    break
            else:
                if self.heap[i] > self.heap[left]:
                    self.heap[i], self.heap[left] = self.heap[left], self.heap[i]
                    i = left
                else:
                    break
        return tar

su = Solution()
arr = [2,3,1,6,4,8,7,5,11,9,10]
k = 3
res = su.k_sort(arr,k)
print(res)

节约内存,降低时间复杂度。

### Top-k 和 Top-p 采样方法概述 在自然语言处理领域,特别是生成式模型中,Top-k 和 Top-p 是两种常用的解码策略,用于控制生成文本的概率分布。 #### Top-k 采样的概念及应用 Top-k 采样是从预测的词汇概率分布中选取最高 k 个概率的词汇作为候选集合。具体来说,在每一步生成过程中,只考虑这 k 个最有可能的单词来决定下一步的选择[^1]。这种方法能够有效减少低质量样本的影响,提高输出的一致性和流畅度。 ```python import torch.nn.functional as F def top_k_sampling(logits, k=50): # 获取logits中的top k最大值及其索引 values, indices = logits.topk(k=k, dim=-1) # 将其他位置设为负无穷大 new_logits = logits.clone() new_logits.scatter_(-1, indices, float('-inf')) # 对新的logits做softmax并采样 probabilities = F.softmax(new_logits, dim=-1) next_token_id = torch.multinomial(probabilities, num_samples=1).item() return next_token_id ``` #### Top-p (核) 采样的概念及应用 不同于固定的前 k 名次选择,Top-p 采样依据累积概率阈值 p 来动态调整候选集大小。即按照降序排列后的累积概率达到或超过给定比例 p 的最小数量词汇构成候选列表[^3]。这种方式可以在保持一定随机性的前提下更好地平衡多样性和合理性之间的关系。 ```python def nucleus_sampling(logits, p=0.9): sorted_probs, sorted_indices = torch.sort(F.softmax(logits), descending=True) cumulative_probabilities = torch.cumsum(sorted_probs, dim=-1) cutoff_index = (cumulative_probabilities >= p).nonzero()[0].item() + 1 truncated_probs = sorted_probs[:cutoff_index] truncated_indices = sorted_indices[:cutoff_index] sampled_idx_in_truncated_set = torch.multinomial(truncated_probs, num_samples=1).item() chosen_word_idx = truncated_indices[sampled_idx_in_truncated_set].item() return chosen_word_idx ``` 这两种方法都可以通过调节参数 k 或 p 来改变生成内容的风格——较小的数值倾向于更保守、可预见的结果;而较大的数值则允许更多探索未知的可能性。实际应用时可根据特定任务需求灵活选用合适的配置方案[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值