基于成本字段存储排序项目的数据结构[关闭]

Posted

技术标签:

【中文标题】基于成本字段存储排序项目的数据结构[关闭]【英文标题】:Data structure to store sorted items based on a cost field [closed] 【发布时间】:2021-01-04 20:35:05 【问题描述】:

我需要提高算法的性能,每次迭代最多将 4 个项目添加到列表中,然后取出 1 个成本最低的项目(项目上的属性)。因此,该列表会增加每次迭代,直到算法打破循环。几件物品的成本可能相同,在这种情况下,我只取其中一件。

我应该使用什么数据结构?

我正在考虑创建一个列表,我打算在其中存储已排序的项目。然后对于每次迭代使用某种排序算法(将研究最快)并将新项目插入列表中的正确位置。然后从列表中删除第一项。

【问题讨论】:

"我正在考虑创建一个列表,我打算在其中存储已排序的项目。" - 你的意思是...A SortedList? 我查看了排序列表,打算将我的成本字段用作键,但键不需要唯一吗?我可以拥有几件具有相同成本价值的物品。 听起来你想要的是priority queue。 是的,我正在寻找优先队列。它看起来不像.net 附带一个,所以我将研究如何自己实现一个。谢谢! 您可以将SortedListQueue 组合在一起,例如SortedList<int, Queue<YourItem>>,它按成本排序,然后您将具有相同成本的值排队。 【参考方案1】:

.NET 6 更新PriorityQueue<TElement, TPriority> 类是随 .NET 6 引入的,这使得下面的实现几乎无关紧要。


这是您可以使用的基本PriorityQueue 类。它基于SortedSet<(TSource, TPriority, long)>long 的目的是区分具有相同优先级的项目。

public class PriorityQueue<TSource, TPriority>

    private readonly SortedSet<(TSource, TPriority, long)> _set;
    private long _index;

    public PriorityQueue(IComparer<TPriority> priorityComparer = null)
    
        priorityComparer ??= Comparer<TPriority>.Default;
        var comparer = Comparer<(TSource, TPriority, long)>.Create((x, y) =>
        
            int result = priorityComparer.Compare(x.Item2, y.Item2);
            if (result == 0) result = Comparer<long>.Default.Compare(x.Item3, y.Item3);
            return result;
        );
        _set = new SortedSet<(TSource, TPriority, long)>(comparer);
    

    public void Enqueue(TSource item, TPriority priority)
    
        _set.Add((item, priority, _index++));
    

    public bool TryDequeue(out TSource item)
    
        if (_set.Count == 0)  item = default; return false; 
        var min = _set.Min;
        _set.Remove(min);
        item = min.Item1;
        return true;
    

在您的情况下,优先考虑的是每件商品的成本。成本较低的项目首先出列。较小的TPriority 值表示较高的优先级。

使用示例:

var queue = new PriorityQueue<Item, Decimal>();

//...

queue.Enqueue(item1, item1.Price);
queue.Enqueue(item2, item2.Price);

//...

if (queue.TryDequeue(out var bestPriceItem))
    Console.WriteLine(bestPriceItem);
else
    Console.WriteLine("The warehouse is empty.");

上面的实现对于大量项目应该是相当有效的。 SortedSet&lt;T&gt; 在内部实现为二叉搜索树,基本操作具有相当的 O(log n) 复杂度。但这不是最佳解决方案。如果你想要最好的,你可以看看可能会变成the official Microsoft's implementation,它现在处于“api-approved”阶段(source code)。那是基于heap 而不是二叉搜索树,具有相同的 O(log n) 复杂度,但内存占用更小,每次操作的恒定开销更少。

【讨论】:

以上是关于基于成本字段存储排序项目的数据结构[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

获取firebase图像的URL的成本[关闭]

MongoDB索引管理

严格使用 GraphQL 作为查询语言

大型 MySQL 数据库 [关闭]

在数据库中的一组记录上存储排序顺序的最有效方法是啥? [关闭]

mongoDB_08索引的操作