基本上,我正在编写一个应用程序来优化仓库布局。没有数据库或其他任何东西;只是需要操纵和生成文件的简单数据。仓库由不同尺寸的货架组成,货架上放置了不同尺寸的盒子,目标是找到最佳的布局(或至少是一个好的布局),让所有盒子都适合。
基本模型(实际上并不重要)是:
data Dimension = Dimension {length::Double, width::Double, height::Double}
data Box = Box {boxId :: Int, boxDim:: Dimension }
data Shelf = Shelf {shelfId :: Int, shelfDim :: Dimension, postion :: ... }
现在,第一个问题是有一个货架图。有些货架是背靠背的。我需要知道这一点,因为一个货架的深度可以调整(这会相反地修改背面的货架)。我还需要知道相对的货架和下一个货架。
最有效的建模方法是什么?
我的第一个想法是:
data Shelf = Shelf { ... , backShelf :: Maybe Shelf
, frontShelf :: Maybe Shelf
, nextShelf :: Maybe Shelf
}
现在,在Haskell中,数据是不可变的,那么我该如何更新
Shelf
?我的意思是,想象一下,如果我有一个Shelf
列表;如果我修改一个Shelf
,那么我需要更新所有副本吗?我的第二个想法是使用id代替:
newtype ShelfId = Int
data Shelf = Shelf { ..., backShelfId :: Maybe ShelfId ... }
或者我应该使用外部图表?例如
back, front, next :: [(shelfId, shelfId)]
第二个问题是如何建模一个盒子属于一个货架的事实。
可能的方法有:
data Box = Box { ..., shelf :: Shelf }
或者
data Box = Box { ..., shelfId :: Maybe ShelfId }
或
data Shelf = Shelf { ..., boxes = [Box] }
或者
data Shelf = Shelf { ..., boxIds = [BoxId] }
一个外部图表。
boxToShelf :: [(BoxId, ShelfId)]
此外,正如我所说的,这些操作涉及大量的更新;我可能会逐个向每个架子添加盒子,这在不可变数据中可能非常低效。
我想到的另一种解决方案是使用STRef或等效物:
data Box = { ..., shelf :: STRef Shelf }
感觉使用指针,所以可能不是一个好主意。
更新
这不是XY问题,也不是玩具问题。这是一个真实的应用程序,用于一个真实的仓库(大约有100个货架和3000个箱子)。它需要能够绘制和加载现有数据(箱子及其位置)。优化只是其中的一部分,可能会半手动完成。
因此,我的问题是关于表示可变对象之间关系而不是基本的组合问题。
data Shelf = ... boxes :: [Box], backShelf :: Maybe Shelf}
中,修改一个盒子涉及到修改包含该盒子的货架以及所有引用它的货架,以及引用它们的货架等等... - mb14