根据维基百科上的this article,对n个数字列表进行排序的理论最小值为:from operator import attrgetter, methodcaller
from pathlib import Path
sorted(Path('my_directory').glob('*.extension'), key=methodcaller('stat').st_size)
我设法写了一个很大的"大"用于排序到5个元素列表的代码,用于对8个元素列表进行排序的排序树代码将是大约60000行,并且不可能用于编写。
请注意一个分类网络,虽然易于实现既不是我需要的,也不是比较或操作中的极简主义,因为我正在寻找线性排序方法(没有并行性)
我试图找到一种编写程序来编写我需要的程序的方法。我偏袒输出代码在python中。
我的包版
修改 在研磨和管理设计尺寸为8,9,10的树木后,我注意到了它。这是徒劳的。即使用c或直接用汇编级语言实现,因为源代码的大小呈指数级增长。我创建了一个c dll用于排序树n = 8,其大小为10 MB ..对于9达到100 MB而对于10,编译器根本无法在我的系统上创建DLL。如果我将树分解成较小的功能,那么大小会大大减少购买性能会丢失。所以没有必要进一步研究这个话题
这里是sort5的代码,我想获得sort8的类似代码
log (n!)
答案 0 :(得分:0)
此代码基本上构建了一个二叉树,其中特定深度的所有节点都具有a>b
种关系。对于n
参数,将会有n*(n-1)/2
这样的关系,这将是我们树的深度。
现在我们尝试在此树中推送所有n!
个可能的输出数组。请注意,数组可以表示为n-1
a>b
种关系,例如'acb' -> a>c,c>b
。现在将这些依赖项插入树(下面代码中的arr_conds
)就像插入二进制搜索树一样。比如深度为3的所有节点,我们都有c>e
。所以要插入abcde
,我们向左走,aebdc
我们走右边。
此代码已经过最多7个元素的测试(~22k行!!)。它到目前为止工作,但这绝对不是标准排序算法的替代品。有关详细信息,请参阅注释。
from itertools import permutations,combinations
import sys
from copy import deepcopy
sys.stdout = open("file.py","w")
N = 7
params = list(chr(97+i) for i in range(N))
permutes = list(permutations(params)) #all possbl outputs of sort function
conds = list(combinations(params,2)) #n*(n-1)/2 such conditions for each depth
conds = {i:conds[i] for i in range(len(conds))} #assign each to a particular depth
class Node:
def __init__(self,depth):
self.d = depth
self.left = None
self.right = None
def insert(self,arr_conds,arr):
if arr_conds==[]: #all n-1 conditions fulfilled, just insert
self.arr = deepcopy(arr);
return
for c in arr_conds: #one of n-1 conditions directly matched,remove it
if set(conds[self.d])==set(c):
arr_conds.remove(c)
src,dst = conds[self.d] #BST like part,recursive insertion
if arr.index(src)<arr.index(dst):
if not self.left: self.left = Node(self.d+1)
self.left.insert(arr_conds,arr)
else:
if not self.right: self.right = Node(self.d+1)
self.right.insert(arr_conds,arr)
def vis(self,sp=""):
if 'arr' in self.__dict__:
s = ','.join(self.arr)
print(sp,"return [",s,"]",sep='')
else:
x,y = conds[self.d]
if self.left:
print(sp,f"if {x}>{y}:",sep='')
self.left.vis(sp+" "*4)
if self.right:
if self.left:
print(sp,"else:",sep='')
else:
print(sp,f"if {y}>{x}:",sep='')
self.right.vis(sp+" "*4)
root = Node(0)
for p in permutes: #for all possbl answers...
arr_conds = [(p[i],p[i+1]) for i in range(N-1)]
root.insert(arr_conds,p) #insert their n-1 conditions into tree
print(f"def sort({','.join(params)}):")
root.vis(" ") #print actual tree...which is our generated code
print("print(sort(33,122,16,2,88,8,9))")
sys.stdout.close()
输出是同一文件夹中的file.py
。
答案 1 :(得分:0)
这是另一个程序,但它没有经过很好的测试。它产生简单的伪代码。我检查了N = 8,它生成所有8!可能的结果。
而不是a, b, c, ...
它使用索引0, 1, 2, ...
。比较1和2意味着比较第1和第2项。
Ordering
类跟踪数字之间的关系。如果我们不知道两者中的哪一个更大而哪个更小,那么一对数字是无序的。比较使这对配对。当没有无序对时,整个列表完全排序。
代码生成器递归地选择随机无序对并首先更新Ordering
,好像订单是a < b
然后好像订单是相反的a > b
因此创建了两个分支( IF和ELSE)。
我觉得有点棘手的唯一部分是从a > c
和a > b
中推断b > c
。为简单起见,程序为每个数字维护已知较小/较大的两组数字。为了简化代码,相同数字本身也是集合的一部分。
import itertools
class Ordering:
def __init__(self, n):
if isinstance(n, type(self)):
# make a copy
self.unordered = n.unordered.copy()
self.le = {i: le.copy() for i, le in n.le.items()}
self.ge = {i: ge.copy() for i, ge in n.ge.items()}
else:
# initialize for N *distinct* items
self.unordered = set(frozenset(pair) for pair in itertools.combinations(range(n), 2))
self.le = {i: set((i,)) for i in range(n)} # less or equal
self.ge = {i: set((i,)) for i in range(n)} # greater or equal
def a_is_less_than_b(self, a, b):
def discard(x, y):
self.unordered.discard(frozenset((x, y)))
for i in self.le[a]:
for j in self.ge[b]:
self.ge[i].add(j)
discard(i, j)
for i in self.ge[b]:
for j in self.le[a]:
self.le[i].add(j)
discard(i, j)
def final_result(self):
# valid only if self.unordered is empty
return [item[1] for item in sorted((len(le), i) for i, le in self.le.items())]
def codegen(oo, level=0):
def iprint(*args):
print(' ' * (2*level+1), *args) # indented print
if oo.unordered:
x, y = iter(next(iter(oo.unordered))) # random pair from set
copy = Ordering(oo)
iprint("IF [{}] < [{}]:".format(x, y))
oo.a_is_less_than_b(x, y)
codegen(oo, level+1)
iprint("ELSE:" )
copy.a_is_less_than_b(y, x)
codegen(copy, level+1)
else:
iprint("RESULT", oo.final_result());
if __name__ == '__main__':
N=4
codegen(Ordering(N))