假期假期如何最大限度地度假?

时间:2013-04-02 13:34:21

标签: algorithm

这更像是一种算法评论: -

问题:假设假期为整数列表,在0-364之间,以及可用的叶数N,如何最大化X假期中的天数,假期是一个日期范围,其中包括假期范围和使用范围为其余的叶子。

我相信使用getMaxVacations(X,0,364,N)的以下伪代码可能适用于一些小修补程序&优化,但我正在寻找其他方法来可视化问题,不一定更快。

available_leaves (N) = 5
holidays = [7, 14, 20, 21, 35, 36]

getMaxVacation (X, start, end, N) {
  if X = 0 return 0;
  for (d : end to start + 1) {
    for (leave : N to 1)
      total = bestSingleVacation(start, d, leave) + getMaxVacation(X-1, d, end, N-leave);
    if max < total
    max = total
  return max
}

bestSingleVacation(start, end, leaves_to_use) {
  maxVacationSize = leaves_to_use
  for (i : start; i < end-maxVacationSize; i++) {
    for (j : i ; j < leaves_to_use) {
      if (!holidays.contains(j)) j++; // use the leave
    }
    if (maxVacationSize < j-i) maxVacationSize = j-i;
  }
  return maxVacationSize;
}

1 个答案:

答案 0 :(得分:1)

这是Haskell使用联邦假期的事情(1月1日至20日在列表的末尾,因此程序将利用寒假来构建假日子序列)。它将从X假期的最长到最短总休假天数输出,利用N天或更少的假期 - 这些假期中的许多是一天的假期(但是可以提供几天假期来增加它们)。如果您正在寻找X假期中最短的假期,可能需要进行一些调整。这是一种过滤的大多数组合方法。


方法:

  1. 列出假期的所有子序列。

  2. 从1开始形成X个子序列的所有组。

  3. 过滤2.使得中间天数(休假天数)不超过N,并按休假天数下降返回。


  4. 样本输出N = 15,X = 4:

    (17,[[1,15],[53],[150],[245]]) -17 days of vacation, 13 days of leave utilized
                                     for the first vacation 
    
    (14,[[15,20],[53],[185],[359,1]]) -14 days of vacation, 10 days of leave utilized
                                       for the first and last vacation
    


    程序代码:

    import Control.Monad(guard)
    import Data.List(sortBy, nub, intersect, sort, inits, tails)
    
    federalHolidays = [53,150,185,245,285,315,332,359,1,15,20]
    n = 15 --days of leave
    x = 4 --number of vacations
    
    differences xs = 
      sum $ map (\x -> x - 1) . tail 
      $ zipWith (\a b -> if a > b then a-b else a + 364 - b) xs ([0] ++ init xs)
    
    countDays vacation = if null (drop 1 vacation) 
                            then 1 
                            else if last vacation > head vacation 
                                    then last vacation - head vacation
                                    else last vacation + 365 - head vacation
    
    maxVacations = 
      sortBy (\a b -> compare (fst b) (fst a)) 
      $ zip (map (\x -> sum (map countDays x)) potentialVacations) 
      $ filter (\y -> sum (map differences y) <= n) potentialVacations
     where potentialVacations = nub (map sort $ solve [])
           holidaySubsequences = 
             filter (not . null) . concatMap inits . tails $ federalHolidays
           solve result = 
             if length result == x
                then [result]
                else do
                  h <- holidaySubsequences
                  guard (
                    differences h <= n 
                    && notElem h result 
                    && all null (map (intersect h) result))
                  solve (h:result)