【Rosalind】Enumerating Oriented Gene Orderings - 排列与组合

最近更新比较少,做题也比较慢,因为手头事情多起来了,而且这些题目真是很难了,不静下来在纸上算一会我是真写不出来。今天就分享一道和之前两道题有关的一道习题吧。

Problem

A signed permutation of length nn is some ordering of the positive integers {1,2,…,n} in which each integer is then provided with either a positive or negative sign (for the sake of simplicity, we omit the positive sign). For example, π=(5,−3,−2,1,4) is a signed permutation of length 5.

Given: A positive integer n≤6.

Return: The total number of signed permutations of length n, followed by a list of all such permutations (you may list the signed permutations in any order).

Sample Dataset
2
Sample Output
8
-1 -2
-1 2
1 -2
1 2
-2 -1
-2 1
2 -1
2 1

思路

这道题和之前的一道题非常类似,首先要生成全排列,然后需要对每个位置的正负进行组合。

首先收集(1,2,...,n)的全排列到一个列表里。

然后从(1,-1)这两个元素中随机选n次,得到的所有组合放到一个列表里。

假如n=3,全排列表里应该有个(1,2,3),符号的组合里应该有一个(1,-1,1),我们再把这两个列表里的列表或元组对应相乘,前面这个例子输出就应该是(1,-2,3)

全排列的数量是n!,符号组合的数目是2^n,所以总的输出的可能数应该是n!*(2**n)

我的代码

"""
	Rosalind Problems: Enumerating Oriented Gene Orderings

	Problem ID: SIGN

	http://rosalind.info/problems/sign/

	A signed permutation of length n is some ordering of the positive integers {1,2,…,n} in which each integer is then provided with either a positive or negative sign (for the sake of simplicity, we omit the positive sign). For example, π=(5,−3,−2,1,4) is a signed permutation of length 5.

	Given: A positive integer n≤6.

	Return: The total number of signed permutations of length n, followed by a list of all such permutations (you may list the signed permutations in any order).
"""

from itertools import product

def fac(x):
	if x==1:
		return x
	else:
		return x*fac(x-1)

def perm(n):
	elem = []
	visit = []
	for i in range(1,n+1,1):
		elem.append(i)
		visit.append(True)
	#print(elem)
	temp = [0*n for i in range(len(elem))]
	def dfs(pos):
		if pos == len(elem):
			f = open('perm.txt','a+')
			for i in temp:
				f.write(str(i)+' ')
			f.write('\n')
			f.close()
			return
		
		for x in range(len(elem)):
			if visit[x] == True:
				temp[pos] = elem[x]
				visit[x] = False
				dfs(pos+1)
				visit[x] = True
	dfs(0)

	f = open('perm.txt', 'r')
	data = f.readlines()
	f.close()
	data2 = []
	for lines in data:
		data2.append(lines.replace(' \n', ''))
	allperm = []
	for i in range(fac(n)):
		allperm.append([])
	#print(allperm)
	for i in range(len(data2)):
		for num in data2[i]:
			if num != ' ':
				allperm[i].append(int(num))
	#print(allperm)
	return allperm

def signed(alist):
	num = len(alist)
	ctrl = []
	neg_pos = product([1,-1],repeat=num)
	for i in neg_pos:
		ctrl.append(i)
	#print(ctrl)
	combination = [[] for i in range(2**num)]
	for i in ctrl:
		ind = ctrl.index(i)
		for x in alist:
			pos = alist.index(x)
			combination[ind].append(i[pos]*x)
	#print(combination)
	for i in combination:
		for j in i:
			if i.index(j) != num-1:
				print(j, end=' ')
			else:
				print(j, end='\n')


def main():
	#Given number
	N = 5

	permutations = perm(N)
	#signed([1,2,3])
	print(fac(N)*(2**N))
	for i in permutations:
		signed(i)

if __name__ == '__main__':
	main()

其中,全排列部分我是用上次写的dfs算法写的,然后把结果输出到了中间文件里。符号组合的函数我是用itertools里的product函数完成的。

参考

  1. https://blog.csdn.net/Emmett_Bioinfo/article/details/109274811

  2. https://blog.csdn.net/Emmett_Bioinfo/article/details/109274839

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EmmettPeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值