Algorithm 活动时间表
我有以下任务。有24小时的时间表。还有一些固定长度的事件。我有一个预定义长度的新事件(例如1小时25分钟)。任务是要知道我一天中可以插入此任务多少次(此任务不得与其他事件相交)Algorithm 活动时间表,algorithm,Algorithm,我有以下任务。有24小时的时间表。还有一些固定长度的事件。我有一个预定义长度的新事件(例如1小时25分钟)。任务是要知道我一天中可以插入此任务多少次(此任务不得与其他事件相交) 我们的问题可能被认为有点简单化, 因此,让答案也简单化(在Ruby中): !/usr/bin/ruby 开始日期=0 结束日期=24*60 #现在,繁忙时段作为大小为2的阵列: 繁忙时段=[[9*60,9*60+30],[18*60+30,20*60]] 附加事件长度=1*60+25,即1小时25分钟 #在这个简单的程序
我们的问题可能被认为有点简单化, 因此,让答案也简单化(在Ruby中):
!/usr/bin/ruby
开始日期=0
结束日期=24*60
#现在,繁忙时段作为大小为2的阵列:
繁忙时段=[[9*60,9*60+30],[18*60+30,20*60]]
附加事件长度=1*60+25,即1小时25分钟
#在这个简单的程序中,,
#时间将以一天中的分钟数表示
#要获得更高级的使用,请尝试使用“Time”类
#现在让我们定义一个函数来计算空闲时间列表
#从给定的繁忙时段列表中:
def计算空闲时段(事件列表)
#计算开始时,假设我们一整天都是免费的:
空闲时间=数组[[开始日期,结束日期]]
#现在,让我们一个接一个地去掉繁忙的时段:
列出所有事件。每个具有对象空闲时间段的事件都有忙碌时间段、空闲时间段|
#我们使用'each'枚举器的'each_with_object'版本
#空闲时间段列表作为外部对象传入
#这样我们就可以逐渐地把每一段繁忙的时间从它身上移开
#让我们首先注意最后一个空闲时间段的结束时间
#([-1]表示空闲时间列表的最后一个元素,
#大小为2的数组的第二个元素的后续[1])
最后一个空闲时段结束=空闲时段[-1][1]
#现在,让我们把最后一个自由期按
#当前繁忙时段(假定繁忙时段不重叠且
#按升序排序)
#首先,将最后一个空闲时间段的结束时间设置为开始时间
在这个迭代中我们考虑的忙碌周期:
空闲时间[-1][1]=繁忙时间[0]
#然后,附加的空闲时间将附加到
“自由周期”和“你尝试了什么?我尝试了微不足道的解决方案,但现在我寻找特殊的ALGOS。没有任何算法可以考虑,因为已经天真的算法完成了O(n):))中的任务。但是,等等,可能有一件事-牺牲内存以提高性能,将计数作为每个空闲时间段的一个数组来维护,当您的日常日程发生变化时,只更新那些空闲时间段,而这些时间段已经发生了变化。不过,除非你的一天中有像DNA这样的百万个片段,否则在那里收获不多
#! /usr/bin/ruby
DAY_START = 0
DAY_END = 24*60
# now, busy periods as array of size-2 arrays:
BUSY_PERIODS = [[9*60, 9*60+30], [18*60+30, 20*60]]
ADDITIONAL_EVENT_LENGTH = 1*60 + 25 # that is, 1 hour and 25 minutes
# in this simple program,
# time will be expressed as a number of minutes of the day
# for more advanced use, try to use "Time" class
# now let define a function to compute the list of free periods
# from a given list of busy periods:
def compute_free_periods( list_of_events )
# at the begining of the calculation, our whole day is assumed free:
free_periods = Array[ [ DAY_START, DAY_END] ]
# now, one by one, let us take away the busy periods:
list_of_events.each_with_object free_periods do | busy_period, free_periods |
# we use 'each_with_object' version of 'each' enumerator
# list of free_periods is passed in as an external object
# so that we can gradually take each busy period away from it
# let us first note the end time for the last free period
# ( [-1] refers to the last element of the list of free periods,
# subsequent [1] to the second element of the size-2 array )
last_free_period_end = free_periods[-1][1]
# and now, let us split this last free period into two by the
# current busy period (busy periods assumed non-overlapping and
# sorted in ascending order)
# first, end time of the last free period is set to the beginning
# of the busy period that we consider in this iteration:
free_periods[-1][1] = busy_period[0]
# then, additional free period is appended to the list of
# free periods usind << operator, starting when the busy period ends:
free_periods << [ busy_period[1], last_free_period_end ]
end
end
# now, let us use the function we just defined:
free_periods = compute_free_periods( BUSY_PERIODS )
# Now, for each free period we will count how many times we can stuff
# in the desired additional event:
free_period_capacities = free_periods.map { |free_period|
# we are using map function for this, which will return
# an array of the same length as free_periods, having
# performed prescribed modifications on each element:
# first, we calculate how many minutes a free period has
period_length = free_period[1] - free_period[0]
# then, we will use whole-number division to get the number
# of additional events that can fit in:
period_length / ADDITIONAL_EVENT_LENGTH
# (in Ruby, whole number division is the default behavior of / operator)
}
# and finally, we sum up the free period capacities for our new event:
total_events_possible = free_period_capacities.reduce( :+ )
# (summing is done elegantly by using reduce function with + operator)
# the last remaining thing we can do to consider program finished is to
puts total_events_possible # print the result on the screen
#! /usr/bin/ruby
DAY_START, DAY_END = 0, 24*60
BUSY_PERIODS = [[9*60, 9*60+30], [18*60+30, 20*60]]
ADDITIONAL_EVENT_LENGTH = 1*60 + 25
def compute_free_periods( list_of_events )
free_periods = Array[ [ DAY_START, DAY_END] ]
list_of_events.each_with_object free_periods do | busy_period, free_periods |
last_free_period_end = free_periods[-1][1]
free_periods[-1][1] = busy_period[0]
free_periods << [ busy_period[1], last_free_period_end ] end
end
free_periods = compute_free_periods( BUSY_PERIODS )
free_period_capacities = free_periods.map { |free_period|
period_length = free_period[1] - free_period[0]
period_length / ADDITIONAL_EVENT_LENGTH }
puts ( total_events_possible = free_period_capacities.reduce( :+ ) )