排列组合算法的实现代码

类别:    标签: 编程   阅读次数:   版权: (CC) BY-NC-SA

2014-08-02 17:43:47

有些时候我们需要利用程序实现排列组合算法, 下面是我根据网上的代码改写的awk代码, 可实现排列或是组合, 当然元素数目不能太大.

排列

# Language: bash
awk ' BEGIN {
	Ndat=3
	for(i=1; i<=Ndat; i++) {P[i]=i}
	YesDone=0
	while(!YesDone) {
		for(i=1; i<=Ndat; i++) printf"%d ", P[i]
		print ""
		NextPermut(Ndat, P)
	}
}

function NextPermut(Ndat, P) {
	if (Ndat==0) {YesDone=1; return}
	# 从后向前查找,看有没有后面的数大于前面的数的情况P(i-1)<Pi,若有则停在后一个数的位置。
	# 若没有后面的数大于前面的数的情况,说明已经到了最后一个排列,返回
	for(i=Ndat; i>0 && P[i-1]>P[i]; i--) { }
	Iend=i
	if(Iend==1) { YesDone=1; return }

	# 从后查到Iend,查找大于P(Iend-1)的最小的数,记入Ibeg
	Ibeg=Iend
	for (i=Ndat; i>=Iend; i--) { if (P[Iend-1]< P[i] && P[i]< P[Ibeg]) Ibeg=i }

	#交换p[Ibeg]和p[Iend-1]
	tmp=P[Ibeg]; P[Ibeg]=P[Iend-1]; P[Iend-1]=tmp

	#倒置p[Iend]到p[Ndat]
	j=Ndat
	for(i=Iend; i< j; i++) {
		tmp=P[j]; P[j]=P[i]; P[i]=tmp
		j--
	}
}
'

组合

# Language: bash
awk ' BEGIN {
	m=6; n=4;
	a[1]="A"; a[2]="B"; a[3]="C"; a[4]="D"; a[5]="E"; a[6]="F"

	Comb(m,n)
	#RecComb(m, n, 1, n)
}

function RecComb(m, n, start, count, i,j) { # 递归实现
	for(i=start; i<=m+1-count; i++) {
		b[count]=i
		if(count>1) RecComb(m, n, i+1, count-1);
		else { for(j=n; j>0; j--) printf("%s ",a[b[j]]); print "" }
	}
}

function Comb(m, n) { # 非递归
	idx=1
	p[idx]=1					#取第一个元素
	while(1) {
		if(p[idx]>m) {			#取到底了,回退
			if(idx==1) break	#各种情况取完了,不能再回退了
			idx--				#回退到前一个
			p[idx]++			#替换元素
		} else if(idx==n) {		#取够了,输出
			for(i=1; i<=m; i++) printf("%s ", a[p[i]])
			print ""
			p[idx]++			#替换元素
		} else {				#多取一个元素
			idx++
			p[idx]=p[idx-1]+1
		}
	}
}
'

如果是在Python中, 就容易多了, 可参考下面的代码.

# Language: python
import copy
import random
import itertools

n=6
seqIni=list(itertools.combinations('ABCDEFGHIJ', n))
Nseq=len(seqIni)
print Nseq

fh = open("Comb", "w")

for i in seqIni :
	k=' '.join([str(j) for j in i])
	fh.write(k+"\n")

fh.close()

for Nrnd in range (1):
	seq=copy.deepcopy(seqIni)
	if Nrnd==1:
		tmp=seq[1]
		seq[1]=seq[Nseq-1]
		seq[Nseq-1]=tmp
	if(Nrnd>1): random.shuffle(seq)
	

#	s="%d"%(Nrnd)
#	fh = open("Comb"+s, "w")

#	for i in seq :
#		k=' '.join([str(j) for j in i])
#		fh.write(k+"\n")
#	fh.close()

Ntot=0
for i in range (Nseq):
	if seq[i]!="":
		Ntot += 1
#			if(Ntot>17):
#			print Ntot, seq[i]
#			fh.write("%d "%(Ntot))
#			for kk in seq[i] :
#				k='  '.join([str(jk) for jk in kk])
#				fh.write(k+" ")
#			fh.write("\n")


		for j in range (i+1, Nseq):
			if seq[j]!="":
				Nmat=0
				for ii in range (n):
					for jj in range (n):
						if(seq[i][ii]==seq[j][jj]): Nmat += 1
				if Nmat>=n-1: 
					seq[j]=""
#				else:
#					print " >", j, seq[j], Nmat
if(Ntot<18): print ">>>>", Nrnd, Ntot
fh.close()

网络资源

随意赞赏

微信

支付宝
◆本文地址: , 转载请注明◆
◆评论问题: https://jerkwin.herokuapp.com/category/3/博客, 欢迎留言◆


前一篇: 【转】Griffiths:二十一世纪科学和数学的趋势
后一篇: 用于保存电子书籍的简单脚本

访问人次(2015年7月 9日起): | 最后更新: 2017-06-23 03:12:17 UTC | 版权所有 © 2008 - 2017 Jerkwin