【发布时间】:2021-07-03 20:17:17
【问题描述】:
我提出这个问题的目的是获得一个工作起点并解决这个问题。我不打算有一个完整的答案来神奇地解决我的问题。
上下文
一家公司有 66 个雇主。然而,由于 COVID 大流行,他们每天只有 41 张办公椅(又名位置)。我所说的天数是指一周(周一、周二、周三、周四、周五)
为了解决这个问题,他们创建了三类工人:
- 有固定地点,没有家庭办公室的人 (10)
- 只有 1 天在家办公的人 (7)
- 将有 2 天在家办公的人 (49)
我需要将所有工人与所有椅子结合起来,这样所有 41 把椅子都会被填满。
有一些限制(还有更多,但为了简单起见,我只说 2 个):
- 员工不能连续几天在家办公
- 工人不能选择在周五和周一在家办公。 (例如:工人 1 有 2 天在家办公,然后他选择星期五和星期一,因此他将在家办公 4 天)
我做了什么
好的,所以我开始考虑如何解决这个问题,但是我被卡住了......
我现在做的是数据模型和一些辅助函数,但是我很难想出一个真正的解决方案。我该如何开始?不是简单的组合题,是我的第一个这种类型。
这是我的数据模型:
data Day = Mon | Tue | Wed | Thu | Fri deriving (Show)
data Category = Fixed | OneDay | TwoDays deriving (Show)
data Function = Director | Manager | Common deriving (Show)
data Worker = W { name :: String
, occupation :: String
, category :: Category
, group :: String
, squad :: String
, function :: Function
} deriving (Show)
data Schedule = S [(Worker, [Day])] deriving (Show)
type Workers = [Worker]
-- | Helpers
numWorkers :: Int
numWorkers = 66
numChairs :: Int
numChairs = 41
days :: [Int]
days = [1..5]
haveNoDays :: Worker -> Bool
haveNoDays W{category=Fixed} = True
haveNoDays _ = False
haveOneDay :: Worker -> Bool
haveOneDay W{category=OneDay} = True
haveOneDay _ = False
haveTwoDays :: Worker -> Bool
haveTwoDays W{category=TwoDays} = True
haveTwoDays _ = False
decreaseCategory :: Worker -> Worker
decreaseCategory w@W{category=c} =
case c of
Fixed -> w
OneDay -> w {category = Fixed}
TwoDays -> w {category = OneDay}
-- | Main functions
schedule :: Workers -> Schedule
schedule _ = S []
【问题讨论】:
-
对于暴力破解,您需要一个函数
schedules :: Int -> Workers -> [Schedule]来生成所有可以想象的 N 周时间表,从每天都没有人在办公室的那些开始到每天每个人都来的那些.然后schedule = head . filter isValidSchedule . schedule 2 -
强烈建议查看像 IBM CPLEX 这样的 CP 求解器(约束编程)。它是为这类事情而构建的。
-
Google OR 工具也是一个不错的选择。
-
我和@MLavrentyev 在一起。不要打扰 Haskell。直接去SAT求解器或类似的; z3 或 yices 都会立即解决这个问题。如果你想要一种类似 Haskell 的语言来编写 SAT 查询,请查看cryptol——可行的方法是编写一个函数式程序,当分配人员到椅子上时,检查该分配是否有效(满足您列出的所有约束)。然后,cryptol repl 中的
:sat将向求解器请求满足约束的分配。 -
我部分同意@DanielWagner,但只是部分同意。是的,我也会使用 SMT 求解器,但通过出色的
sbvHaskell 库。我真的很喜欢用它来解决这样的问题。
标签: haskell functional-programming linear-programming