Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
134 views
in Technique[技术] by (71.8m points)

list - how to generate integer partitions of a specific size

I am trying to write this function

variation_models' nlocations =
  let location_list = [1..nlocations-4]
  in [[x1, x2, x3, x4, x5] |
      x1 <- location_list,
      x2 <- location_list,
      x3 <- location_list,
      x4 <- location_list,
      x5 <- location_list,
      both_conditions (adds_up_to nlocations) num_orderedq [x1, x2, x3, x4, x5]]

but have any number of x's. I want variation_models 5 15 to have a valid answer of [1,1,1,1,11].

My current attempt is

variation_models ncars nlocations =
  filter (both_conditions (adds_up_to nlocations) num_orderedq) $
  replicateM ncars [1..nlocations-ncars+1]

but replicateM seems to make the function take up more and more memory.

Any Ideas on how to write a replacement for replicateM so that it does not consume as much memory?

The rest of the definitions used:

import Control.Monad

orderedq f [] = True
orderedq f (x:[]) = True
orderedq f (x:y:zs) = f x y && orderedq f (y:zs)

num_orderedq = orderedq (<=)

adds_up_to n xs = n == sum xs

both_conditions f g xs = f xs && g xs

variation_models ncars nlocations =
  filter (both_conditions (adds_up_to nlocations) num_orderedq) $
  replicateM ncars [1..nlocations-ncars+1]

variation_models' nlocations =
  let location_list = [1..nlocations-4]
  in [[x1, x2, x3, x4, x5] |
      x1 <- location_list,
      x2 <- location_list,
      x3 <- location_list,
      x4 <- location_list,
      x5 <- location_list,
      both_conditions (adds_up_to nlocations) num_orderedq [x1, x2, x3, x4, x5]]

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It looks like you are using replicateM to generate integer partitions.

integer_partitions :: Int -> Int -> [[Int]]
integer_partitions 0 _ = []
integer_partitions 1 n = [[n]]
integer_partitions k n =
  do x <- [1..n - k + 1]
     map (x:) (integer_partitions (k - 1) (n - x)) 

It seems to have better memory characteristics then the more general replicateM


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...