Partition a number or optimize

I have the following function to optimize myfunction = max(p `div` c + p `mod` c) Here p is an array of numbers and c is also an array of numbers I need to find c’s which minimize the value of my function. for example if p = [1,10000]. c = 2,8 or c = 1,9 or c=5,5 number of c is length of p which is 2 (in this case). Sum of c is given as a constraint, so for example if sum is 10, then c’s can be 2,8 or 1,9 or 5,5 or 4,6 or…..etc etc. Length of c will be equal to length of p array. Hope the problem statement is clear In haskell terms it will be, let my_min p c = foldl1 max $ zipWith (\p c -> (p `div` c) + (p `mod` c)) p c One way is to use various combinations of c using integer partitioning. Now i wrote a crude parts function to do this nparts 0 = [] nparts n = [n] : [x:xs | x <- [1..n`div`2], xs <- nparts(n - x)] which is a bad bad example of recursion coz it’s slow! *Main> nparts 5 [[5],[1,4],[1,1,3],[1,1,1,2],[1,1,1,1,1],[1,2,2],[1,2,1,1],[2,3],[2,1,2],[2,1,1,1]] I can then filter this with length of p and get the required options of c I can then call the function “ my_min” with this list (simple map application) Problem is if i do *Main> filter (\x->length x == 2) $ nparts 100 [[1,99] and it hangs…for a lot of time….so time constraint? Any other approaches to this problem to make the partitions speedier. I know it’s an optimization problem…but all non linear optizers will use floats…and fail to converge…this is an integer optimizing problem. Any ideas??

Now i wrote a crude parts function to do this
nparts 0 = [] nparts n = [n] : [x:xs | x <- [1..n`div`2], xs <- nparts(n - x)]
which is a bad bad example of recursion coz it’s slow!
It's not the recursion that makes it slow, but its asymptotic runtime, which is O(2^n). This one might run slightly faster: intParts :: Integer -> [[Integer]] intParts n = do x <- [1..n] let r = n - x if r > 0 then map (x :) (intParts (n - x)) else [[x]] Verify that this function takes a lot of time for an argument as small as 20, because it finds 2^19 partitionings. You need to eliminate candidates early. For example if you know that you only need 2-partitionings, then there is no need at all for the recursion and you can get away with O(n). Alternatively you can eliminate certain partitions by changing the third line. x <- [2..n] This finds partitions of at least 2. Or introduce a stop-early condition. Greets, Ertugrul

I did find a better solution but it’s still slow let cities = 6 let clinics = 10 let populations = [1,10000,2,3,400,1] let nparts n k = filter ((==n) . sum) $ replicateM k [1..n] let d2 = nparts clinics cities let d1 = map maximum (map (\x -> zipWith (/) populations (map (\n-> fromIntegral n) x)) $ d2) maximum $ zipWith (\n x -> (n `div` x) + (n `mod` x) ) populations $ d2 !! (head $ filter ((==minimum d1) . (d1 !!)) [0..]) here also nparts take time….if we choose clinics > 10 Heres the problem statement The World Health Organization (WHO) wants to establish a total of B vaccination clinics across Ncities to immunization people against fatal diseases. Every city must have at least 1 clinic, and a clinic can only vaccinate people in the same city where they live. The goal is to minimize the number of vaccination kits needed in the largest clinic. For example, suppose you have: 2 cities and 7 clinics to be opened. If 200,000 is the population of the first city and 500,000 is the population of the second city, then two clinics can open in the first city and five in the second. This way, 100,000 people can be immunized in each of the two clinics in the first city, and 100,000 can be immunized in each clinic in the second city. So the maximum number of people to be immunized in the largest clinic is 100,000 -Animesh
On Apr 27, 2015, at 10:19 PM, Ertugrul Söylemez
wrote: as 20, because it finds 2^19 partitionings. You need to eliminate

You don't want to do full search here. You want to do a "branch and bound"
search, keeping track of the current best value (which suggests the State
monad) and then terminating searches of subtrees when the best possible
value for that subtree is worse than the current global best possible.
I haven't looked into doing this in Haskell, but it should be a lot faster
than trying to search the full tree.
On Mon, Apr 27, 2015 at 9:23 AM, Animesh Saxena
let cities = 6 let clinics = 10 let populations = [1,10000,2,3,400,1] let nparts n k = filter ((==n) . sum) $ replicateM k [1..n] let d2 = nparts clinics cities let d1 = map maximum (map (\x -> zipWith (/) populations (map (\n-> fromIntegral n) x)) $ d2) maximum $ zipWith (\n x -> (n `div` x) + (n `mod` x) ) populations $ d2 !! (head $ filter ((==minimum d1) . (d1 !!)) [0..])
participants (3)
-
Animesh Saxena
-
Ertugrul Söylemez
-
Mike Meyer