推断设备分配列表随时间的变化

时间:2011-05-10 16:06:04

标签: java algorithm

在我的小问题中,我有n个用户和m个设备(m和n~50000)。一个用户一次只能使用一个设备。

我有这种格式的记录列表[ u,e,t ],其中 t (时间)按升序排序。每条记录都意味着用户 u t 时使用 e 设备。记录数量约为5亿。假设具有相同 u e 的两个最近记录表示 u 连续使用 e 。例如:

1, 2, 1  
3, 4, 1    
1, 2, 3
1, 2, 4 
1, 2, 5 
2, 6, 6
3, 2, 6  
3, 2, 8 

意味着用户1使用1到5的设备2.

我想要做的是从这个列表中,以这种格式推断换班时间:[ u,e,st,et ]这意味着用户 u 使用设备 e 从开始时间 st 到结束时间 et

样本数据的结果为:

1, 2, 0, 5  
3, 4, 0, 6  
3, 2, 6, 8

(假设时间从0开始并以max(t)结束,并且当第一次看到一对(u,e)时,u从0开始就已经开始使用e。类似于最后的记录。 )

鉴于大名单(5亿条记录)但m和n足够小,我怎样才能最有效地做到这一点?

@Edit:可能的数据不一致:
1:如果样本数据中只有1个记录(因此没有结束时间),例如[2,6,6]的情况:
---如果这是用户2和设备6出现在数据集中的唯一时间,则忽略数据点 ---如果在该记录之后,用户2使用另一台设备,比如7比10,那么2比6使用6比5 ---如果在该记录之后,设备6被另一个用户使用,比如10比11,那么2比6使用6比11。

3 个答案:

答案 0 :(得分:2)

定义两个结构(我知道这是Java,但让我们假设一个通用算法):

struct user_record {
    int machine_idx;
    int start_time;
}

struct machine_record {
    int user_idx;
    int start_time;
}

鉴于用户不能同时使用多个设备,您可以创建一个user_record s的数组/向量,每个用户一个(你说这是~50k,所以这个应该是易处理的),以及machine_record s的数组/向量,每台机器一个。将所有元素'idx成员初始化为-1(表示当前未激活)。

然后,每次遇到输入记录时,请检查idxuser_record数组中相应machine_record字段的状态。有三种可能性:

  1. 两者都是-1。这是一个起点,因此请将这些元素设置为彼此“指向”,并在每个元素中记录start_time
  2. 两者都不是-1,而且是一致的。这是一个终点,所以只需创建一个输出记录,然后将这些元素的idx字段重置为-1。 / LI>
  3. 至少有一个不是-1,但它们不一致。您需要创建两个输出记录,用新值覆盖元素,还要设置相应的旧机器/用户索引到-1。
  4. 这是 O(N)时间(其中 N 是输入记录的数量)。

    注意:输出将按结束时间排序。

答案 1 :(得分:1)

@ Oli-Charlesworth走在正确的轨道上,但细节不足。

你需要的是有两个向量,一个用于用户,一个用于机器。机器指向用户。用户指向机器。其中一个向量,无论哪个向我使用,都必须跟踪它们第一次关联,以及它们最后一次关联。

初始化所有内容,使每个用户指向-1(无机器),每台机器指向-1(无用户)。以下是如何处理记录的伪代码:

for (user, machine, time) in records:
    # By user.machine I mean look up the machine the user currently points at
    if user.machine <> machine:
        output_record_and_clear(user)
        if machine.user <> user:
            output_record_and_clear(machine.user)
        user.machine = machine
        machine.user = user
        user.start_time = time
    user.end_time = time

def output_record_and_clear (user):
    if -1 <> user.machine and user.start_time < user.end_time:
        emit(user, user.machine, user.start_time, user.end_time)
    user.machine.user = -1
    user.machine = -1

答案 2 :(得分:0)

我会通过用户或机器对文件进行排序来解决这个问题(因为它是一对一的,它应该没关系)然后按时间然后问题很简单,只需逐行排列并输出班次

您还可以在内存中逐行执行此操作,方法是保留正在使用的计算机的哈希表以及上次使用它们时,再次看到计算机时,输出使用的时间并更新表。只有50,000台机器,这应该可以正常工作。