2

Is there a way to put cluster level limits on clusters? For example, if I run:

FindClusters[{1, 2, 3, 4, 4, 6, 7, 10}]

I get back two lists, {{1, 2, 3, 4, 4}, {6, 7, 10}}. But lets say I only want each cluster to have a sum of 15 or fewer and potentially get {{2, 3, 10}, {6, 3, 1}, {7, 4, 4}}

As far as I can tell, this is not possible to express with a distance function, so maybe clustering is the wrong tool for the job?

Is there a way to do that?

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
soandos
  • 1,030
  • 8
  • 20
  • "I only want each cluster to have a sum of 15 or fewer" is very lax. You still have way too many possible combinations – Dr. belisarius Dec 29 '14 at 18:33
  • @belisarius, That is by design. If possible, I would like to randomly get n solutions to this problem. – soandos Dec 29 '14 at 18:34
  • But ...how many clusters? How many elements per cluster? – Dr. belisarius Dec 29 '14 at 18:36
  • Ideally, I'd like to be able to just give a number of clusters (in the case, 3). Max elements per cluster should not matter unless they meet that limiting condition (also, the inversion of the limiting condition could exist, so that would mean 3 clusters of fewer) – soandos Dec 29 '14 at 18:38
  • 2
    Clustering is based on similarity of elements, but your condition is not explicitly based on similarity. For you, the clusters {4, 5, 6} and {1, 14} each sum to 15, but differ drastically as far as clustering algorithms. It seems you want to use Tuples with constraints, not FindClusters. – David G. Stork Dec 29 '14 at 18:38
  • @DavidG.Stork, any examples on how to do that (can't seem to find anything explicitly designed for solving constraints on sets) – soandos Dec 29 '14 at 18:39

1 Answers1

2
Quiet[<< Combinatorica`;]
l = {1, 2, 3, 4, 4, 6, 7, 10};
f[l_, n_, min_, max_] := Module[{part, s},
                         While[(s = (Tr /@ (part = RandomKSetPartition[l, n])); 
                              Not[And @@ Thread[min < s < max]])];
                         part]
f[l, 3, 5, 15]
(* {{1, 10}, {2, 4, 7}, {3, 4, 6}} *)
Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
  • Is there a way to do this without holding all sets to be the same size? – soandos Dec 29 '14 at 18:49
  • They aren't the same size ... – Dr. belisarius Dec 29 '14 at 18:50
  • Oh, my bad. Looks good then, I'll try on larger data sets and see how performance is. Thank you. – soandos Dec 29 '14 at 18:51
  • This is silly, but I can't seem to bound it both ways (between min and max). Replacing the inside with Module[{part, s}, While[Or @@ Thread[s = (Tr /@ (part = RandomKSetPartition[l, n])) < max && s > min] gives nonsensical answers. – soandos Dec 29 '14 at 19:18
  • @soandos Thread[] doesn't work that way ... – Dr. belisarius Dec 29 '14 at 19:20
  • So I can only bound it on one side (the change I made was inside thread, still returning a boolean)? – soandos Dec 29 '14 at 19:22
  • @soandos Let me see if I can quick-fix the code for that. Not much time right now – Dr. belisarius Dec 29 '14 at 19:24
  • @soandos: I think you still haven't specified your question properly, i.e., in a way that will lead to an answer. Is this what you seek? "Given a list myList containing n integers (possibly non-distinct), with target subset size range [minsize, maxsize], find a partition (all partitions?) of myList such that each subset's elements sum to a value in the specified range [minsum, maxsum], or return a flag stating no such partition of myList exists."? – David G. Stork Dec 29 '14 at 19:28
  • @DavidG.Stork. Would like some way to get some amount of partitions, but will have have a need to prove "ALL" if that matters. Otherwise, spot on – soandos Dec 29 '14 at 19:31
  • @soandos There you go – Dr. belisarius Dec 29 '14 at 19:32
  • @belisarius, thank you, testing now – soandos Dec 29 '14 at 19:36
  • @belisarius pretty sure there is something wrong with the condition (maybe something should be an And? can't seem to be able to fix it), but it doesn't work. f[l, 3, 10, 15] gives {{1, 4}, {2, 3, 4, 10}, {6, 7}} as an answer – soandos Dec 29 '14 at 21:13
  • @soandos I think I fixed it now – Dr. belisarius Dec 30 '14 at 02:42