找回密码
 注册
Simdroid-非首页
查看: 303|回复: 9

[编程进阶] 寻求快速获得不同的排列组合的函数

[复制链接]
发表于 2010-3-24 13:58:44 | 显示全部楼层 |阅读模式 来自 北京
本帖最后由 ggggwhw 于 2010-3-24 13:59 编辑

有5个不同人,要从其中选出3个参加比赛,不同的选法有哪些?
转化成数学描述就是,从集合{1,2,3,4,5},从中任意取出3个数字组成新的集合,该集合可以有哪些不同情况?这是一个组合的问题,下面是我实现的代码:
  1. In[1]:= arr = Table[j, {j, 1, 5}];
  2. brr = Tuples[arr, 3];
  3. crr = Select[brr, #[[1]] < #[[2]] < #[[3]] &]
  4. Length@crr

  5. Out[3]= {{1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}, {1,
  6.   4, 5}, {2, 3, 4}, {2, 3, 5}, {2, 4, 5}, {3, 4, 5}}

  7. Out[4]= 10

复制代码
如果考虑参赛顺序的话,就成了排列的问题了:
  1. In[5]:= arr = Table[j, {j, 1, 5}];
  2. brr = Tuples[arr, 3];
  3. crr = Select[brr, #[[1]] != #[[2]] != #[[3]] &]
  4. Length@crr

  5. Out[7]= {{1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {1, 3, 2}, {1, 3, 4}, {1,
  6.   3, 5}, {1, 4, 2}, {1, 4, 3}, {1, 4, 5}, {1, 5, 2}, {1, 5, 3}, {1, 5,
  7.    4}, {2, 1, 3}, {2, 1, 4}, {2, 1, 5}, {2, 3, 1}, {2, 3, 4}, {2, 3,
  8.   5}, {2, 4, 1}, {2, 4, 3}, {2, 4, 5}, {2, 5, 1}, {2, 5, 3}, {2, 5,
  9.   4}, {3, 1, 2}, {3, 1, 4}, {3, 1, 5}, {3, 2, 1}, {3, 2, 4}, {3, 2,
  10.   5}, {3, 4, 1}, {3, 4, 2}, {3, 4, 5}, {3, 5, 1}, {3, 5, 2}, {3, 5,
  11.   4}, {4, 1, 2}, {4, 1, 3}, {4, 1, 5}, {4, 2, 1}, {4, 2, 3}, {4, 2,
  12.   5}, {4, 3, 1}, {4, 3, 2}, {4, 3, 5}, {4, 5, 1}, {4, 5, 2}, {4, 5,
  13.   3}, {5, 1, 2}, {5, 1, 3}, {5, 1, 4}, {5, 2, 1}, {5, 2, 3}, {5, 2,
  14.   4}, {5, 3, 1}, {5, 3, 2}, {5, 3, 4}, {5, 4, 1}, {5, 4, 2}, {5, 4, 3}}

  15. Out[8]= 60
复制代码
问题是Mathematica 有没有现成的函数可以实现类似的两种结果呢?
发表于 2010-3-24 15:39:27 | 显示全部楼层 来自 北京海淀
Simdroid开发平台
组合的问题可以用Subsets
  1. In[1]:= Subsets[Range[5], {3}]

  2. Out[1]= {{1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}, {1, 4,
  3.    5}, {2, 3, 4}, {2, 3, 5}, {2, 4, 5}, {3, 4, 5}}
复制代码
回复 不支持

使用道具 举报

发表于 2010-3-24 19:26:10 | 显示全部楼层 来自 河南郑州
本帖最后由 chyanog 于 2010-3-26 13:13 编辑

组合问题:
In[2]:=
  1. Binomial[5, 3]
复制代码

Out[2]= 10
排列问题:
In[3]:=
  1. FactorialPower[5, 3]
复制代码

Out[3]= 60
回复 不支持

使用道具 举报

发表于 2010-3-24 20:21:34 | 显示全部楼层 来自 北京海淀
排列问题:
Permutations[Range[5], {3}]
回复 不支持

使用道具 举报

发表于 2010-3-24 20:38:50 | 显示全部楼层 来自 北京海淀
4# fresh 这个方法挺好
回复 不支持

使用道具 举报

 楼主| 发表于 2010-3-24 21:26:43 | 显示全部楼层 来自 北京

  1. Subsets[Range[5], {3}]

  2. Permutations[Range[5], {3}]
复制代码
正是我想要的结果.
那么再问一个问题:
从5个人中选择4个人去参加比赛,其中2个人,参加一百米比赛,另外2个人参加二百米比赛.有哪些组合呢?不是问种类数,要求输出所以满足条件的结果.
  1. In[34]:= arr = Subsets[Range[5], {2}];
  2. brr = Permutations[arr, {2}];
  3. crr = Select[brr, Length@Union[#[[1]], #[[2]]] == 4 &]
  4. Length@crr

  5. Out[36]= {{{1, 2}, {3, 4}}, {{1, 2}, {3, 5}}, {{1, 2}, {4, 5}}, {{1,
  6.    3}, {2, 4}}, {{1, 3}, {2, 5}}, {{1, 3}, {4, 5}}, {{1, 4}, {2,
  7.    3}}, {{1, 4}, {2, 5}}, {{1, 4}, {3, 5}}, {{1, 5}, {2, 3}}, {{1,
  8.    5}, {2, 4}}, {{1, 5}, {3, 4}}, {{2, 3}, {1, 4}}, {{2, 3}, {1,
  9.    5}}, {{2, 3}, {4, 5}}, {{2, 4}, {1, 3}}, {{2, 4}, {1, 5}}, {{2,
  10.    4}, {3, 5}}, {{2, 5}, {1, 3}}, {{2, 5}, {1, 4}}, {{2, 5}, {3,
  11.    4}}, {{3, 4}, {1, 2}}, {{3, 4}, {1, 5}}, {{3, 4}, {2, 5}}, {{3,
  12.    5}, {1, 2}}, {{3, 5}, {1, 4}}, {{3, 5}, {2, 4}}, {{4, 5}, {1,
  13.    2}}, {{4, 5}, {1, 3}}, {{4, 5}, {2, 3}}}

  14. Out[37]= 30
复制代码
问题是:有没有更简单的写法呢?注意是计算量少,需要内存小,单纯的形式简单不是我想要的.
回复 不支持

使用道具 举报

发表于 2010-3-26 00:41:28 | 显示全部楼层 来自 台湾
Flatten[Table[{#,i},{i,Subsets[Complement[Range[5],#],{2}]}]&/@Subsets[Range[5],{2}],1]
回复 不支持

使用道具 举报

 楼主| 发表于 2010-3-26 12:42:59 | 显示全部楼层 来自 北京
本帖最后由 ggggwhw 于 2010-3-26 12:47 编辑
Flatten,#],{2}]}]&/@Subsets[Range[5],{2}],1]
chungyuandye 发表于 2010-3-26 00:41

我实在是没有理解这种算法,具体体现在我不能将上面的写法改造成等效于下面写法的形式,下面的形式是我把我的代码中的变量全部移到前面后得到的结果那么上面的代码如果将变量提前后会是什么样子呢?

  1. 总人数 = 9;
  2. 比赛项目数 = 3;
  3. 各项比赛人数 = 2;
  4. 参赛人数 = 各项比赛人数*比赛项目数;
  5. arr = Subsets[Range[总人数], {各项比赛人数}];
  6. brr = Permutations[arr, {比赛项目数}];
  7. crr = Select[brr, Length@Union[Flatten[#]] == 参赛人数 &]
  8. Length@crr

复制代码
回复 不支持

使用道具 举报

发表于 2010-3-26 20:10:41 | 显示全部楼层 来自 台湾
Flatten[Tuples[{{#},Subsets[Complement[Range[5],Flatten@#],{2}]}]&/@Subsets[Range[5],{2}],1]//Length

Flatten[Tuples@{{#[[1]]},{#[[2]]},Subsets[Complement[Range[9],Flatten@#],{2}]}&/@Tuples@{{#},Subsets[Complement[Range[9],#],{2}]}&/@Subsets[Range[9],{2}],2]//Length
回复 不支持

使用道具 举报

 楼主| 发表于 2010-3-27 13:07:48 | 显示全部楼层 来自 北京
9# chungyuandye
我测试了一下,楼上的速度要快一些,但是看着两种不同情况下的代码,我觉得还是写自己的代码形式了,至少形式是统一的.只需改变初值而已.
而楼上的还要改变代码长度.
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2026-1-7 03:51 , Processed in 0.031239 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表