我正在寻找一种算法来计算序列中的下一组操作。以下是序列的简单定义。
所以在t = 500时,做1A。在t = 1000时,同时执行1A和2A,在t = 1500时执行1A和3A,但不执行2A,因为1500不是1000的倍数。您可以理解。
如果我有实际的时间会很容易,但我没有。我所拥有的是任务的历史(例如上次完成[1A + 2A])。
知道上次(例如[1A + 2A])还不足以决定:
有算法吗?它看起来像一个熟悉的问题(某种筛子?)但我似乎无法找到解决方案。
此外,它必须“缩放”,因为我实际上有超过3个任务。
答案 0 :(得分:3)
如果您有足够的历史记录来完成每项任务的最后两次,您可以重建原始任务序列定义。当它们重合是偶然的。
答案 1 :(得分:2)
序列必须重复。对于给出的示例,序列将是1A,1A + 2A,1A + 3A,1A + 2A,1A,1A + 2A + 3A。在这种情况下,你可以看到最后一个1A + 2A + 3A有多远,并使用该距离作为数组的索引。在一般情况下,对于长度为N的循环,您总是可以通过针对循环的所有旋转测试最后N个事件来做到这一点,但我怀疑通常会有某种可用的快捷方式,例如有多少事件可以支持最后“做一切”事件发生了,或者多久以前最后一次“做一切”事件发生了。
答案 2 :(得分:1)
似乎是一个最大的共同点问题。
答案 3 :(得分:1)
修改
啊,你必须走另一条路。在这种情况下,正如有人提到的那样,您可以使用三个中最小公倍数来计算有效的@TimeLastJob- 注意:使用一些SQL Server 2005 SQL扩展,
- 但仍然可以作为算法的伪代码规范
DECLARE @constEvaluationPeriodLength int
DECLARE @ constCycleTimeJob1A int
DECLARE @ constCycleTimeJob2A int
DECLARE @ constCycleTimeJob3A int
SET @constEvaluationPeriodLength = 500
SET @ constCycleTimeJob1A = 500
SET @ constCycleTimeJob2A = 1000
SET @ constCycleTimeJob3A = 1500
DECLARE @ Indicator1ARunAtLastCyclePoint int
DECLARE @ Indicator2ARunAtLastCyclePoint int
DECLARE @ Indicator3ARunAtLastCyclePoint int
SET @ Indicator1ARunAtLastCyclePoint = 1
SET @ Indicator2ARunAtLastCyclePoint = 0
SET @ Indicator3ARunAtLastCyclePoint = 1
DECLARE @tblPrimeFactors TABLE(
TaskId int
CycleTimePrimeFactor int
)
- 捕获每个TaskId的主要因素
IF(@ Indicator1ARunAtLastCyclePoint = 1)
开始
INSERT @tblPrimeFactors
选择
TaskId = 1
,PrimeFactor
FROM FROM dbo.tvfGetPrimeFactors(@ constCycleTimeJob1A) - 为读者留下的有价值的功能
结束
IF(@ Indicator2ARunAtLastCyclePoint = 1)
开始
INSERT @tblPrimeFactors
选择
TaskId = 2
,PrimeFactor
FROM FROM dbo.tvfGetPrimeFactors(@ constCycleTimeJob2A) - 为读者留下的有价值的功能
结束
IF(@ Indicator3ARunAtLastCyclePoint = 1)
开始
INSERT @tblPrimeFactors
选择
TaskId = 3
,PrimeFactor
FROM dbo.tvfGetPrimeFactors(@ constCycleTimeJob3A) - 为读者留下的有价值的功能
结束
- 计算LCM,这可以作为一个有效的时间
- 利用SQL Server动态表功能
- (内部选择语句在括号中,并给出别名t0和t1以下)
DECLARE @LCM int
SELECT
- 使用日志/功能来实现产品聚合功能
@LCM =功率(总和(log10(功率(PrimeFactor,频率))),10)
FROM
(
选择
PrimeFactor
,频率=最大(频率)
来自
(
选择
PrimeFactor
,频率=计数(*)
FROM @tblPrimeFactors
GROUP BY
TaskId
,PrimeFactor
)t0
)t1
DECLARE @TimeLastJob int
DECLARE @TimeNextJob int
SET @TimeLastJob = @LCM
SET @TimeNextJob = @TimeLastJob + @constEvaluationPeriodLength
SELECT
Indicator1A = 1 - SIGN(@TimeNextJob%@ constCycleTimeJob1A)
,Indicator2A = 1 - SIGN(@TimeNextJob%@ constCycleTimeJob2A)
,Indicator3A = 1 - SIGN(@TimeNextJob%@ constCycleTimeJob3A)
原件:
模数操作数%应该成功
如果我正确读到这个,你确实有上次任务的时间
任务选择评估的频率是每500小时。
尝试改变@TimeLastJob以查看下面的脚本是否为您提供了所需的内容
DECLARE @constEvaluationPeriodLength int
DECLARE @ constCycleTimeJob1A int
DECLARE @ constCycleTimeJob2A int
DECLARE @ constCycleTimeJob3A int
SET @constEvaluationPeriodLength = 500
SET @ constCycleTimeJob1A = 500
SET @ constCycleTimeJob2A = 1000
SET @ constCycleTimeJob3A = 1500
DECLARE @TimeLastJob int
DECLARE @TimeNextJob int
--SET @TimeLastJob = 1000
SET @TimeLastJob = 5000
SET @TimeNextJob = @TimeLastJob + @constEvaluationPeriodLength
SELECT
Indicator1A = 1 - SIGN(@TimeNextJob%@ constCycleTimeJob1A)
,Indicator2A = 1 - SIGN(@TimeNextJob%@ constCycleTimeJob2A)
,Indicator3A = 1 - SIGN(@TimeNextJob%@ constCycleTimeJob3A)
答案 4 :(得分:1)
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
答案 5 :(得分:0)
先决条件:
在启动每个任务/任务组时,通过时间轴移动索引。
答案 6 :(得分:0)
这是伪装的FizzBuzz。
而不是通常的3到“Fizz”和5到“Buzz”的映射,我们有500到任务1A,1000到任务2A和3到任务3A的映射,依此类推。
可以在此处找到详尽的解决方案列表(或接近未命中:)):What is your solution to the FizzBuzz problem?