Hello everyone,<br><br>So here is what I want to achieve:<br>I'd like a program that calculates the time needed for water to flow out of a circuit made out of tube.<br>The rules are :<br>- There are multiple sources of water and only one exit.<br>
- The water can only take one path from a source to the exit.<br>- Of course, a source of water contains a certain amount of water at the beginning.<br><br>### Algorithm<br>Here's the concept of how it should be working:<br>
<br>#1<br>The tubes are connected together : 1 parent with n childs. This looks really like a tree:<br>data Tree = Leaf { getVolume::Int }<br> | Path { getMaxFlow::Int<br> , getFlow::Int<br>
, getOpen::Bool<br> , getChilds::[Tree}<br> }<br>But this structure doesn't work well :( (see later why)<br><br>When I determine the time taken by the water to flow down to the exit, I need to take water jams (haha) into account.<br>
To do this, the algorithm begins by the exit node and "distribute" it's maximum flow through the childs, but only to open tubes.<br>And the childs distribute their flow to their own child. Repeat until you reach a Leaf.<br>
<br>example :<br>Path 5 0 True [Path 4 0 True [], Path 3 0 True [], Path 3 0 False []]<br>after distribution:<br>Path 5 5 True [Path 4 4 True [], Path 3 2 True [], Path 3 0 False []]<br><br>#2<br>After the distribution, you must get the water out. Easy, the time taken by the water to flow down is, in pseudo code:<br>
max( for all leafs : getVolume * getFlow )<br><br>### Problem<br>My problem, is this : I must be able to change the "distribution" the flow of the parent to its childs:<br>in my example, I said "take the biggest child, give it all you can and give the rest to the other childs, repeat"<br>
but I could have said "give first to the lowest child" or "give a certain percentage depending of the sum of the childs max capacity"<br><br>So I can't map simply over the childs:<br>distribute :: (Int -> Int -> Int) -> Tree -> Tree<br>
distribute _ (Leaf a) = Leaf a<br>distribute f path@(Path _ _ False _) = path<br>distribute f (Path max cur open childs) = Path max (f cur) open (map f childs)<br><br>I must indeed let the distribution function choose to which childs it wants to give:<br>
distribute :: (Int -> [Tree] -> [Tree]) -> Tree -> Tree<br>distribute f (Path max use open child) = Path max use open $ map (distribute (f use)) newChilds<br> where newChilds = f use childs<br><br>And I find this quite awful...<br>
I know Hakell is everything about data structure, so I suppose my data structure is awful too.<br>Do you have any suggestions/remarks to help me?<br><br>Sorry I made it so long, but you needed to know what I wanted to acheive to help me (I hope I made it crystal clear ^^).<br>
Thanks,<br>Ibiz<br>