用Lingo解决组合问题
用Lingo解决组合问题 原著:JerryMcManus 翻译:alphachi[问题] 有5张卡片,从中任取3张,列出所有可能的结果。[分析] 输入卡片列表并确定最终组合列表的长度——〉计算组合的总数并生成组合列表——〉输出组合列表[代码] 由于是有关排列组合的问题,必然会涉及到阶乘的计算。为了方便起见,可以先设计一个阶乘计算程序:onmGetFactorial(me,num) factorial=1repeatwithx=numdownto1 factorial=factorial*xendrepeatreturnfactorialend 接下来,就可以利用这个阶乘计算程序得到组合的总数:--计算阶乘listFactorial=me.mGetFactorial(pListCount)subsetFactorial=me.mGetFactorial(pSubsetCount)listMinusSubsetFactorial=me.mGetFactorial(pListCount-pSubsetCount)--计算组合总数pTotal=listFactorial/(subsetFactorial*(listMinusSubsetFactorial))pNumLeft=pTotal 现在,借助一个索引数值,通过循环语句即可生成一个索引列表:onmGetCombination(me)--检测是否为第一次循环ifpNumLeft=pTotalthen--是第一次循环,使用当前子列表 pNumLeft=pNumLeft-1else--不是第一次循环,获取新的子列表x=pSubsetCount--在当前子列表中循环并增值repeatwhilepCurrentSubset[x]=pListCount-pSubsetCount+xx=x-1endrepeat pCurrentSubset[x]=pCurrentSubset[x]+1repeatwithy=(x+1)topSubsetCount pCurrentSubset[y]=pCurrentSubset[x]+y-xendrepeat--获取新的子列表 pNumLeft=pNumLeft-1endifend 之所以没有直接对实际的卡片列表进行直接操作,是为了让程序拥有更强的适应性。因为只要拥有了索引列表,就可以对任何传入的实际列表进行“组合”操作,而不仅仅限于这个卡片列表。当然,只需再添加一些代码,即可生成实际的结果列表:--生成结果列表combination=[]repeatwithx=1topSubsetCount combination.add(pItemList[pCurrentSubset[x]])endrepeat 下面的影片便是完成后的“组合生成器”:播放,以上示例,需下载此插件。点击下载插件[说明] 这项技巧虽然比较简单,但使用的范围却非常广泛,例如卡片的随机抽取或数列的随机生成。此外,在许多涉及到需要列举组合结果的数学问题中都占有一席之地