Arranging group of numbers to fit Specific size total

 ̄綄美尐妖づ 提交于 2019-12-25 05:08:03

问题


I have several different numbers in a group that range in sizes and would like to calculate which group the numbers should go in based on the max size the group can be.

Example of the numbers: 10,20,30,40,50,60

Example of conditions: the maximum total the numbers can add up to in a group is 60

So from the example above the answer would be:

group 1 would have the numbers 10,20,30

group 2 would have the number 40

group 3 would have the number 50

group 4 would have the number 60

Is there a way in matlab/octave or excel/librecalc this can be computed?

PS: A group can also have the number 40 and 20 the group total just can't go over 60. But they can only use each number once.

Is there a math term used for this?


回答1:


EDIT:

The solution below uses a brute-force approach to generating powersets of powersets (although trimmed). Then checks for groups that satisfy the conditions set (namely divide all the numbers into groups such that no group contain a sum of more than 60). I borrowed some code from the powerset.m function in PMTK3 toolbox.

This should work fine for a small problem like this one, but I suspect it would grow exponentially in size for larger input. I'm sure there are better heuristic/algorithms out there, so take this as a starting point...

%# set of numbers
S = [10,20,30,40,50,60];

%# powerset of S (exclude empty set)
b = (dec2bin(2^numel(S)-1:-1:1) == '1');
P = cellfun(@(idx)S(idx), num2cell(b,2), 'UniformOutput',false);

%# keep only sets where the sum is at most 60
P = P(cellfun(@sum,P) <= 60);

%# take the powerset of the powerset, although we can
%# reduce it to no more than numel(S) subsets in each.
%# The idea here is: nchoosek(p,1:numel(s))
b = (dec2bin(2^numel(P)-1:-1:1) == '1');
b = b(sum(b,2)<=numel(S),:);
PP = cellfun(@(idx)P(idx), num2cell(b,2), 'UniformOutput',false);

%# condition: every number appears exactly once in groups
ppp = cellfun(@(x) [x{:}], PP, 'UniformOutput',false);
idx = find(cellfun(@numel,ppp) == numel(S));
idx2 = ismember(sort(cell2mat(ppp(idx)),2), S, 'rows');
PP = PP( idx(idx2) );

%# cleanup, and show result
clearvars -except S PP
celldisp(PP)

This gave me 12 solutions. For example:

>> PP{1}{:}
ans =
    10    20    30
ans =
    40
ans =
    50
ans =
    60

>> PP{6}{:}
ans =
    10    40
ans =
    20
ans =
    30
ans =
    50
ans =
    60

>> PP{12}{:}
ans =
    10
ans =
    20
ans =
    30
ans =
    40
ans =
    50
ans =
    60


来源:https://stackoverflow.com/questions/10950639/arranging-group-of-numbers-to-fit-specific-size-total

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!