代码之家  ›  专栏  ›  技术社区  ›  Christian Lescuyer

计算序列中下一个集合的算法

  •  4
  • Christian Lescuyer  · 技术社区  · 17 年前

    我正在寻找一种算法来计算序列中的下一组操作。下面是序列的简单定义。

    1. 任务1A将每500小时完成一次
    2. 任务2A将每1000小时完成一次
    3. 任务3A将每1500小时完成一次

    所以在t=500时,做1A。在t=1000时,同时进行1A和2A,在t=1500时,进行1A和3A,但不进行2A,因为1500不是1000的倍数。你明白了。

    如果我有实际的时间,那就很容易了,但我没有。我拥有的是任务的历史记录(例如上次完成[1A+2A])。

    知道最后一次(如[1A+2A])不足以决定:

    • [1A+2A]可能在t=1000时;接下来是[1A+3A]在t=1500时
    • [1A+2A]可能位于t=5000处:接下来是[1A]位于t=5500处

    因为我必须有“3个以上的任务”。

    7 回复  |  直到 17 年前
        1
  •  3
  •   Bill the Lizard    17 年前

        2
  •  2
  •   Andru Luvisi    17 年前

    序列必须重复。对于给定的示例,序列将是1A、1A+2A、1A+3A、1A+2A、1A、1A+2A+3A。在这种情况下,您可以看到最后1A+2A+3A的距离有多远,并将该距离用作数组的索引。在一般情况下,对于长度为N的循环,您总是可以通过对循环的所有旋转测试最后N个事件来完成,但是我怀疑通常会有某种可用的快捷方式,比如上次“做所有事情”事件发生的时间,或者上次“做所有事情”事件发生的时间。

        3
  •  1
  •   Simon Lehmann    17 年前

    蜥蜴比尔是对的。以下是如何从历史中确定任务间隔(在Python中):

    history = [list of tuples like (timestamp, (A, B, ...)), ordered by timestamp]
    lastTaskTime = {}
    taskIntervals = {}
    
    for timestamp, tasks in history:
        for task in tasks:
            if task not in lastTaskTime:
                lastTaskTime[task] = timestamp
            else:
                lastTimestamp = lastTaskTime[task]
                interval = abs(timestamp - lastTimestamp)
                if task not in taskIntervals or interval < taskIntervals[task]:
                    taskIntervals[task] = interval  # Found a shorter interval
    
                # Always remember the last timestamp
                lastTaskTime[task] = timestamp
    
    # taskIntervals contains the shortest time intervals of each tasks executed at least twice in the past
    # lastTaskTime contains the last time each task was executed
    

    要获取下一步将执行的任务集,请执行以下操作:

    nextTime = None
    nextTasks = []
    
    for task in lastTaskTime:
        lastTime = lastTaskTime[task]
        interval = taskIntervals[task]
    
        if not nextTime or lastTime + interval < nextTime:
            nextTime = lastTime + interval
            nextTasks = [task]
        elif lastTime + interval == nextTime:
            nextTasks.append(task)
    
    # nextTime contains the time when the next set of tasks will be executed
    # nextTasks contains the set of tasks to be executed
    
        4
  •  1
  •   dacracot    17 年前

    这似乎是一个最大的共同点问题。

        5
  •  1
  •   ScottStonehouse    17 年前

    啊,你得走另一条路。在这种情况下,正如有人提到的,您可以使用三者中的最小公倍数来计算一个有效的@TimeLastJob

    --注意:使用一些SQL Server 2005 SQL扩展,
    --但仍然可以作为算法的伪代码规范
    声明@constEvaluationPeriodLength int
    声明@constCycleTimeJob1A int
    声明@constCycleTimeJob2A int
    声明@constCycleTimeJob3A int

    设置@constEvaluationPeriodLength=500
    设置@constCycleTimeJob1A=500
    设置@constCycleTimeJob2A=1000


    声明@indicator1arunatalastcyclepoint

    声明@Indicator3ArunataLastCyclePoint


    设置@Indicator2ARunAtLastCyclePoint=0
    设置@indicator3ArunataLastCyclePoint=1

    声明@tblPrimeFactors表(
    TaskId int
    CycleTimePrimeFactor int
    )

    --捕获每个TaskId的主要因素
    如果(@indicator1ArunataLastCyclePoint=1)

    插入@tblPrimeFactors

    TaskId=1
    ,素因子
    来自dbo.tvfGetPrimeFactors(@constCycleTimeJob1A)——留给读取器的表值函数
    终止

    开始
    插入@tblPrimeFactors

    TaskId=2
    ,素因子

    终止

    开始
    插入@tblPrimeFactors

    TaskId=3

    来自dbo.tvgetprimefactors(@constCycleTimeJob3A)——留给读取器的表值函数
    终止




    --(带括号的内部select语句,别名为t0和t1)
    声明@LCM int

    选择
    --具有日志/权力以实现产品聚合功能的乐趣

    从…起

    选择
    主要因素
    ,频率=最大值(频率)
    从…起
    (
    选择
    主要因素

    来自@tblPrimeFactors
    分组
    塔西德
    ,素因子

    )t1

    声明@TimeLastJob int
    声明@TimeNextJob int

    设置@TimeNextJob=@TimeLastJob+@constEvaluationPeriodLength

    选择
    指示符1A=1-符号(@TimeNextJob%@constCycleTimeJob1A)
    ,指示符2a=1-符号(@TimeNextJob%@constCycleTimeJob2A)
    ,指示符3A=1-符号(@TimeNextJob%@constCycleTimeJob3A)

    原件:

    模数运算符A或%应该可以实现此目的

    • t=1000或
    • t=5000

    尝试更改@TimeLastJob,看看下面的脚本是否为您提供了所需的内容

    声明@constEvaluationPeriodLength int
    声明@constCycleTimeJob1A int
    声明@constCycleTimeJob2A int
    声明@constCycleTimeJob3A int

    设置@constEvaluationPeriodLength=500
    设置@constCycleTimeJob1A=500
    设置@constCycleTimeJob2A=1000


    声明@TimeLastJob int
    声明@TimeNextJob int

    设置@TimeLastJob=5000
    设置@TimeNextJob=@TimeLastJob+@constEvaluationPeriodLength


    指示符1A=1-符号(@TimeNextJob%@constCycleTimeJob1A)
    ,指示符2a=1-符号(@TimeNextJob%@constCycleTimeJob2A)
        6
  •  0
  •   HUAGHAGUAH    17 年前

    先决条件:

    1. 计算任务时间的LCM;这是一个完整的周期。
    2. 计算整个周期的事件时间线。

    在每个任务/任务组启动时,在时间线上移动索引。