用于排序对象列表的算法

假设您有一个对象列表。 用户在工作时主要使用所有对象。 如何订购对象列表,以便列表适应订单,用户主要使用? 您可以使用什么算法?

编辑:许多答案建议计算对象的使用次数。 这不起作用,因为所有对象的使用量相同,只是顺序不同。

在对象内部,保留usedCount。 无论何时使用该对象,都要增加此计数。 然后你可以简单地这样做:

 objects.OrderByDescending(o => o.UsedCount); 

我将保持对象的使用次数以及使用顺序的运行次数。

因此,如果对象X使用第3个,则将其与运行计数平均,并将结果用作列表中的位置。

例如:

物品使用使用顺序
 ---------------------------------------
对象X 10 1,2,3,1,2,1,3,1,2,2(18)
对象Y 10 3,1,2,3,3,3,1,3,3,1(23)
对象Z 10 2,3,1,2,1,2,2,2,2,3(20)

用户将是用户使用对象的次数,使用顺序将是订单中项目使用位置的列表(或总和)。

单独使用每个订单的列表可能会遇到一些性能问题,因此您可能只想保留一个位置的总和。 如果保留一个总和,只需在每次使用该对象时将该顺序添加到该总和。

要计算头寸,您只需使用头寸总和除以使用次数即可获得平均值。 此时您需要做的就是按平均顺序排列列表。

在上面的示例中,您将获得以下平均值(和顺序):

对象X 1.8
对象Z 2.0
对象Y 2.3

添加用户访问对象的日期时间列表。 每次用户使用对象时,都要添加日期时间。

现在只计算列表中的日期时间条目数w(现在 – x天)并按此排序。 您可以删除>(现在 – x天)的日期时间。

用户可能在一个月内使用不同的项目,这将反映这些更改。

您可以在对象类中添加number_of_views字段,每次使用对象时都会添加++,并按该字段对列表进行排序。 当所有对象的number_of_views相同但不为0时,您应该将此字段= 0设置为所有对象。

我还会为每个对象使用一个计数器来监视它的使用,但是不是在每次使用后重新排序整个列表,我建议只是在“本地”对列表进行排序。 就像在冒泡排序中一样,我只是将计数器刚刚增加的对象与上层对象进行比较,并根据需要进行交换。 如果交换,我会比较对象及其新的上层对象,依此类推。

但是,如果正确实现排序,它与以前的方法没有太大差别。

如果您的User类如下所示:

 class User { Collection algosUsed = new List(); //Won't compile, used for explanation ... } 

你的Algo课程看起来像这样:

 class Algo { int usedCount; ... } 

您应该能够将Algo对象的特定实例绑定到User对象,以允许记录它的使用频率。 在最基本的级别,您可以将信息序列化为文件或流。 您很可能希望数据库跟踪正在使用的内容。 然后当你抓住你的User并调用一个sort函数时,你可以通过AlgousedCount参数命令UserusedCount参数

听起来你想要一个缓存。 我想你可以看一下缓存使用的算法,然后拿出关于上下文切换的整个业务……有一种叫做“时钟扫描”的算法…但是对于你想要的东西来说可能都太复杂了。 为了采用懒惰的方式,我只想制作一个“二手物品”的散列:num_of_uses或者,在你的类中,每次使用对象时都有一个var ++。

每隔一段时间用num_of_uses或对象按++的变量值对哈希进行排序。

来自https://stackoverflow.com/a/2619065/1429439 :

也许使用OrderedMultiDictionary,其中usedCount作为键,对象作为值。

编辑:添加订单优先!!! 看看代码

我不喜欢卡拉所说的最后使用的方法,因为它造成了许多令人困惑的排序变化。

count_accessed字段要好得多,不过我认为它应该被调平
用户在最后XX分钟/小时/天内访问此项目的次数等等…

最好的数据结构肯定是

  static TimeSpan TIME_TO_LIVE; static int userOrderFactor = 0; LinkedList> myAccessList = new LinkedList>(); private void Access_Detected() { userOrderFactor++; myAccessList.AddLast(new KeyValuePair(DateTime.Now, userOrderFactor)); myPriority += userOrderFactor; // take total count differential, so we dont waste time summing the list } private int myPriority = 0; public int MyPriority { get { DateTime expiry = DateTime.Now.Subtract(TIME_TO_LIVE); while (myAccessList.First.Value.Key < expiry) { myPriority += myAccessList.First.Value.Value; // take care of the Total Count myAccessList.RemoveFirst(); } return myPriority; } } 

希望这有帮助...它几乎总是O(1)BTW ......
让我想起操作系统的睡眠机制

当用户与对象交互时,保存在该第二个对象上作用的上一个对象的ID,以便始终在任何给定对象之前具有指向所用对象的指针。

此外,存储最常使用的对象的ID,以便您知道从哪里开始。

在构建要显示的对象列表时,首先要将您存储的对象列表作为最常用的对象,然后搜索其上存储有第一个使用的对象ID的对象,然后再显示该对象。