|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
我写了两段代码,用于返回前 n 个自然数的置换全体:例如当 n = 2 时, 返回 [1,2], [2,1]; n = 3 时, 返回 [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]. 数学上采用同一个原理,区别是一个用numpy的数据结构和方法,另一个用 list.
两段代码如下:
用 numpy 的:
- # permutationGenerator
- # Author: Xing Gu
- # Date: 2021/11/23
- def permutation(n):
- """For a positive integer n, returns all the permutations of n as a generator, each permutation being a list of n
- integers. """
- # Manually yield permutation(n) for n=1,2,3.
- import numpy as np
- if n == 0:
- yield np.arange(0, dtype=int)
- elif n == 1:
- yield np.arange(1,2, dtype=int)
- elif n == 2:
- for item in np.array([[1, 2], [2, 1]], dtype=int):
- yield item
- elif n == 3:
- for item in np.array([[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]], dtype=int):
- yield item
- else:
- # Recursively yield permutation(n) for n>3, the recursion step length being 3.
- for i in range(n):
- for j in range(n):
- if i == j:
- continue
- for k in range(n):
- if j == k or i == k:
- continue
- im123 = np.array([i + 1, j + 1, k + 1])
- # the image of 1,2,3 of the permutation sorted in ascending order
- im123Sorted = np.sort(im123)
- # To obtain im4plus, first acquire the permutation of n-3, and then change the values to skip the
- # images of 1,2,3.
- # the image of 4,..., n of the permutation
- im4PlusSorted = np.arange(1, n - 2) + np.concatenate((np.zeros(im123Sorted[0] - 1), \
- np.ones(im123Sorted[1] - im123Sorted[0] - 1), \
- np.ones(im123Sorted[2] - im123Sorted[1] - 1) * 2, \
- np.ones(n - im123Sorted[2]) * 3))
- for item in permutation(n - 3):
- im4Plus = im4PlusSorted[item - 1]
- yield np.concatenate((im123, im4Plus)).astype(int)
- if __name__ == '__main__':
- import timeit
- counter = 0
- start = timeit.default_timer()
- for item in permutation(10):
- print(item)
- counter += 1
- stop = timeit.default_timer()
- print('Counter: ', counter)
- print('Time: ', stop - start)
复制代码
不用 numpy 的:
- # permutationGeneratorNieve
- # Author: Xing Gu
- # Date: 2021/11/23
- def permutation(n):
- """For a positive integer n, returns all the permutations of n as a generator, each permutation being a list of n
- integers. """
- # Manually yield permutation(n) for n=1,2,3.
- if n == 0:
- yield []
- elif n == 1:
- yield [1]
- elif n == 2:
- for item in ([[1, 2], [2, 1]]):
- yield item
- elif n == 3:
- for item in ([1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]):
- yield item
- else:
- # Recursively yield permutation(n) for n>3, the recursion step length being 3.
- for i in range(n):
- for j in range(n):
- if i == j:
- continue
- for k in range(n):
- if j == k or i == k:
- continue
- im123 = [i + 1, j + 1, k + 1]
- # the image of 1,2,3 of the permutation sorted in ascending order
- im123Sorted = sorted(im123)
- # To obtain im4plus, first acquire the permutation of n-3, and then change the values to skip the
- # images of 1,2,3.
- # the image of 4,..., n of the permutation
- for item in permutation(n - 3):
- im4Plus = []
- for l in item:
- if l > im123Sorted[2] - 3:
- im4Plus.append(l + 3)
- elif l > im123Sorted[1] - 2:
- im4Plus.append(l + 2)
- elif l > im123Sorted[0] - 1:
- im4Plus.append(l + 1)
- else:
- im4Plus.append(l)
- # Yield a permutation of n.
- yield im123 + im4Plus
- if __name__ == '__main__':
- import timeit
- counter = 0
- start = timeit.default_timer()
- for item in permutation(10):
- print(item)
- counter += 1
- stop = timeit.default_timer()
- print('Counter: ', counter)
- print('Time: ', stop - start)
复制代码
按理说 numpy相对于python自带的数据结构优化了许多,然而用以上两段代码分别返回前十个正整数的全体置换(3628800个arraies/lists)时,在同一台设备上,前者用时488.1秒,后者29.3秒。用numpy反而慢了十几倍!
问题:(1)当 n 很大时,第一段代码比第二段是否会有更好的表现?(2)在这个任务中是否有更合理的办法使用numpy? |
|