I have a problem like this . However, it includes many updates, and I'm not sure if the IxSet solution is a solution.
I mainly write an application to optimize the layout of the repository. No database or anything else; it is just data to manipulate and create the file at the end. The warehouse is made of shelves of different sizes; shelves contain boxes of different sizes; and the goal is to find a better location (or at least a good one) where to put the boxes so that they all fit.
Base model (doesn't really matter):
data Dimension = Dimension {length::Double, width::Double, height::Double} data Box = Box {boxId :: Int, boxDim:: Dimension } data Shelf = Shelf {shelfId :: Int, shelfDim :: Dimension, postion :: ... }
Now the first problem is that there is a shelf schedule. Some shelves go back to back. I need to know this because you can adjust the depth of one shelf (which change the back of the rear shelf). I also need to know the opposite shelf and the next.
What is the most efficient way to simulate this?
My first thought:
data Shelf = Shelf { ... , backShelf :: Maybe Shelf , frontShelf :: Maybe Shelf , nextShelf :: Maybe Shelf }
Now the data is immutable in Haskell, so how can I update Shelf
? I mean, imagine that I have a Shelf
list; if I modify it, do I need to update all copies of it?
My second thought is to use identifiers instead:
newtype ShelfId = Int data Shelf = Shelf { ..., backShelfId :: Maybe ShelfId ... }
Or use external graphics? Sort of
back, front, next :: [(shelfId, shelfId)]
The second problem is how to simulate the fact that the field belongs to the shelf.
Possible approaches that come to mind:
data Box = Box { ..., shelf :: Shelf }
or
data Box = Box { ..., shelfId :: Maybe ShelfId }
or
data Shelf = Shelf { ..., boxes = [Box] }
or
data Shelf = Shelf { ..., boxIds = [BoxId] }
External graph
boxToShelf :: [(BoxId, ShelfId)]
In addition, as I said, operations include many updates; I can add boxes one at a time to each shelf, which can be really inefficient with immutable data.
Another solution I thought would use STRef
or the equivalent:
data Box = { ..., shelf :: STRef Shelf }
It seems like using a pointer, so there is probably no good idea.
Update
This is not an XY problem, nor a problem with the toy. This is a real world application for a real warehouse (about 100 shelves and 3,000 boxes). It should be able to draw and load existing data (boxes and their location). Optimization is only a small part of it and is likely to be semi-automatic.
So my question is about representing the relationship between mutable objects, not the main combinatorial problems.