【问题标题】:How to find all combinations of sets of pairs如何找到对组的所有组合
【发布时间】:2013-07-28 15:47:31
【问题描述】:

我想生成 3 男 2 女对的所有组合。有很多配对示例(例如参见this),但没有一个涉及配对集。

例如,如果我有:

Men   = {'M1', 'M2'};
Women = {'W1', 'W2', 'W3'};

我想要的结果是以下几组:

(M1, W1), (M2, W2)
(M1, W1), (M2, W3)
(M1, W2), (M2, W1)
(M1, W2), (M2, W3)
(M1, W3), (M2, W1)
(M1, W3), (M2, W2)

谢谢。

【问题讨论】:

  • 代码可以扩展到任意数量的人。谢谢
  • 我猜你在'W'和'M'之间翻转了你的例子M3在哪里?怎么会有W3?另外,应该只有6对,否则我不明白你的问题
  • “W3”从何而来? Women 只包含两个元素...
  • 是的,我为翻转的道歉。

标签: matlab set combinations


【解决方案1】:

其实很简单。要填充一组 k 对,您需要 k 个男人和 k 个女人,所以让我们找出所有可能的 k 组合em> 男人和 k 女人优先:

%// Find all possible combinations of sets of k pairs of men and women
k = 2;
idx_m = nchoosek(1:numel(Men), k);             % // Indices of men
idx_w = nchoosek(1:numel(Women), k);           % // Indices of women
idx_w = reshape(idx_w(:, perms(1:k)), [], k);  % // All permutations

然后让我们构建 k 个男人和 k 个女人的集合的所有可能组合:

[idx_comb_w, idx_comb_m] = find(ones(size(idx_w , 1), size(idx_m , 1)));
idx = sortrows([idx_m(idx_comb_m(:), :), idx_w(idx_comb_w(:), :)]);
idx = idx(:, reshape(1:size(idx, 2), k, [])'); %'// Rearrange in pairs

生成的矩阵idx 包含集合中男性和女性的索引(第一列为男性,第二列为女性,第三列为男性,第四列为女性,依此类推...)。

示例

Men = {'M1', 'M2'};
Women = {'W1', 'W2', 'W3'};

%// Find all possible combinations of sets of k pairs of men and women
k = 2;
idx_m = nchoosek(1:numel(Men), k);
idx_w = nchoosek(1:numel(Women), k);
idx_w = reshape(idx_w(:, perms(1:k)), [], k);
[idx_comb_w, idx_comb_m] = find(ones(size(idx_w , 1), size(idx_m , 1)));

%// Construct pairs from indices and print sets nicely
idx = sortrows([idx_m(idx_comb_m(:), :), idx_w(idx_comb_w(:), :)]);
idx = idx(:, reshape(1:size(idx, 2), k, [])');

%// Obtain actual sets
sets = cell(size(idx));
sets(:, 1:2:end) = Men(idx(:, 1:2:end));
sets(:, 2:2:end) = Women(idx(:, 2:2:end));

%// Print sets nicely
sets_t = sets';
fprintf([repmat('(%s, %s), ', 1, k - 1), '(%s, %s)\n'], sets_t{:})

这里生成的数组sets 已经适应了包含来自MenWomen 的实际值。结果是:

(M1, W1), (M2, W2)
(M1, W1), (M2, W3)
(M1, W2), (M2, W1)
(M1, W2), (M2, W3)
(M1, W3), (M2, W1)
(M1, W3), (M2, W2)

【讨论】:

  • 什么是'idx_sets'?这个有价值的东西还没有定义。
  • 对不起,改成idx
  • 是的,这正是我想要的代码。非常感谢。非常感谢!
  • 如果将 Men 和 Women 替换为 1,2 和 101,102,103 之类的数字会怎样,我需要更改哪部分代码?谢谢。
  • 该代码适用于所有值,而不仅仅是字符串。您唯一需要更改的是将字符串说明符%s 更改为整数%d,格式为fprintf。这仅用于显示目的。
【解决方案2】:

这个例子正在使用FEX file allcomb

men = {'M1', 'M2', 'M3'};
women = {'W1', 'W2'};
allPeople = [men, women];
%// Play with vector index because allcomb doesn't work with cell
[~, id_men] = ismember(men,allPeople);
[~, id_women] = ismember(women,allPeople);


%// give all combinations for men/women
setOfMenWomen = allcomb(id_men,id_women);
%// give all combinations of pairs
nComb = size(setOfMenWomen,1);
setOfPair = nchoosek(1:nComb,2);
%// give all combinations for men/women/men/women
setOfPairMenWomen = cell2mat(arrayfun(@(id) setOfMenWomen(id,:), setOfPair, 'UniformOutput', 0));
%// get ids of set of pairs with the same men twice
isDoubleMen = setOfPairMenWomen(:,1) == setOfPairMenWomen(:,3);
%// get ids of set of pairs with the same women twice
isDoubleWomen = setOfPairMenWomen(:,2) == setOfPairMenWomen(:,4);
%// We don't want to have set of pairs with twice same men or same women
cond = isDoubleWomen | isDoubleMen;
setOfPairMenWomen(cond,:) = [];

%//results :
allPeople(setOfPairMenWomen)

【讨论】:

  • 效果很好,但是有重复的组合,正好是两次。
  • 你是对的,目前我没有找到任何优雅的方法来避免这种情况:/ 直到我找到最好的东西,你可以使用数组 setOfPairMenWomen(1:6,:) 的前半部分与最后一部分完全相反。
  • 谢谢。但是当我将成员增加到 3 Men 和 3 Women、4Men 和 3 Women 时,配对的数量应该分别为 6 和 24。但是您的结果不同,这意味着结果并未显示所有组合。你能解决它吗?
  • 3vs3 有 18 种组合,4vs3 有 36 种组合。你如何计算你的组合总数?
  • 我使用了排列,即kPq, k 是男女之间相对较高的数字,q 是较低的数字。对于 3vs2,3P2= 3*2=6,对于 4vs3 = 4*3*2 = 24。对于 3vs3,3P3= 3*2*1=6。这是一个人配对,如果有1男1女,他们应该配对。
【解决方案3】:

我看不出你的问题到底是什么。您是否在 MATLAB 中搜索算法或实现?我会尝试用数学方法来回答。

您可以通过将其表述为graph 问题来解决您的问题:您的一组人就是一组顶点。通过将所有男人与所有女人联系起来形成边缘。现在找到(最大)matchings 的集合。

这在一定程度上取决于您到底想要什么:例如,您是否希望元素 ((M1, W1)) 成为您解决方案的一部分?然后您正在搜索匹配项(请参阅Hosoya index 了解解决方案集中的元素数量)。如果您只想要无法添加进一步配对的元素,那么您只考虑最大匹配。

如果您将问题扩展到通用的非性别对,这可能会有所帮助:http://en.wikipedia.org/wiki/Telephone_number_(mathematics)

【讨论】:

    猜你喜欢
    • 2020-12-24
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 2012-04-09
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    相关资源
    最近更新 更多