-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import LeastCommonMultiple | ||
from itertools import combinations | ||
|
||
def findSlice(minSlice = 180, step=60, maxLCM = 43200): | ||
"""计算分片组合 | ||
:param minSlice:最小分片数 | ||
:param step: 分片增量 | ||
:param maxLCM: 最大的最小公倍数,超出这个数即停止运算————预期的在这个数值内保证分片不重复 | ||
:return: | ||
1/0 : 1表示达到maxLCM退出得出的结果;0表示未达到maxLCM退出得到的结果,即完美结果 | ||
subSliceList:得到的分片组合 | ||
lcm:实际的最小公倍数,即实际的在这个数值内保证分片不重复 | ||
""" | ||
#初始化分片组合列表 | ||
sliceList = [] | ||
sliceList.append(minSlice) | ||
#初始化下一个分片数 | ||
nextSlice = minSlice | ||
#初始化已经计算过的分片组合 | ||
usedSliceList = [] | ||
#初始化已经计算过的最小公倍数 | ||
usedLCM = [] | ||
|
||
while 1: #无线循环 | ||
#按照分片增量增加下一个分片数 | ||
nextSlice = nextSlice + step | ||
sliceList.append(nextSlice) | ||
#初始化组合长度 | ||
i = 2 | ||
while i < len(sliceList): # 当组合长度小于分片组合列表长度 | ||
allSubSliceList = list(combinations(sliceList, i)) # 将分片列表按长度进行全量组合(排列组合中的组合) | ||
for subSliceList in allSubSliceList: # 遍历每一个分片组合 | ||
if subSliceList not in usedSliceList and minSlice in subSliceList: #如果当前组合没有计算过 并且 最小分片数在当前分片组合中(为了提升程序效率) | ||
lcm = LeastCommonMultiple.getLCM(subSliceList) #计算当前组合的最小公倍数 | ||
if lcm not in usedLCM: #如何当前组合的最小公倍数没有被计算过 | ||
numSuccess = False # 初始化完美计算成功为False | ||
for num in range(lcm, minSlice - 1, -1): #从大到小遍历最小公倍数 | ||
numSuccess = False # 重置完美计算成功为False | ||
for slice in reversed(subSliceList): #遍历每一个分片数 | ||
if slice / minSlice > 1 and slice % minSlice == 0: #如果当前分片数是最小分片数的倍数 | ||
continue #跳过该分片数 | ||
remainder = num % slice #计算当前分片数的余数 | ||
if remainder == 0 or remainder >= minSlice: #如果能除仅 或者 余数大于最小分片数 | ||
numSuccess = True #当前分片数满足需求,计算成功 | ||
break #不用再计算其他分片数,退出变量分片数循环 | ||
else: | ||
numSuccess = False #当前分片数不满足需求,计算失败 | ||
if numSuccess == False: #如果每一个分片数都计算失败 | ||
break #当前分片组合计算失败,退出当前分片组合计算 | ||
usedLCM.append(lcm) #将当前组合的最小公倍数加入到已计算过的最小公倍数列表(为了提升程序效率) | ||
if numSuccess == True: #当前分片组合的每一个分片数均计算成功,即完美计算 | ||
return 0, subSliceList, lcm #返回完美计算结果 | ||
else: #未完美计算成功 | ||
if lcm > maxLCM: #如果当前计算的最小公倍数已满足我们的最大的最小公倍数要求 | ||
return 1, subSliceList, lcm #返回非完美计算结果,但该结果已能满足要求 | ||
#print(subSliceList) | ||
usedSliceList.append(subSliceList) #将当前分片组合加入已计算过的分片组合列表 | ||
i += 1 #组合长度加1 | ||
|
||
return 2 #非正常退出 | ||
|
||
if __name__ == '__main__': | ||
print(findSlice()) # 找最小分片为3的分片组合 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import math | ||
|
||
""" | ||
获得多个数的最小公倍数 | ||
isPrime(n) | ||
getMutiPrime(n) | ||
getLeastCommonMutible(numList) | ||
""" | ||
|
||
|
||
def isPrime(n): | ||
""" | ||
判断一个数是否是质数 | ||
""" | ||
if n == 2: | ||
return True | ||
if n == 1 or n % 2 == 0: | ||
return False | ||
p = int(math.sqrt(n)) + 1 | ||
i = 3 | ||
while i < p: | ||
if n % i == 0: | ||
return False | ||
i += 2 | ||
return True | ||
|
||
|
||
def getMutiPrime(n): | ||
"""get muti num of n | ||
n=num1*num2...*numx for num1...numx are all prime numbers | ||
将数n进行质因数分解 prime factorization | ||
""" | ||
if n == 2: | ||
resultlist = [2] | ||
else: | ||
list1 = [i for i in range(2, int(math.sqrt(n)) + 1) if isPrime(i)] | ||
# print(list1) | ||
resultlist = [] | ||
tmp = n | ||
while not isPrime(tmp) and tmp != 1: | ||
for i in list1: | ||
if tmp % i == 0: | ||
resultlist.append(i) | ||
tmp = tmp // i | ||
# print(tmp) | ||
# print(resultlist) | ||
if tmp != 1: | ||
resultlist.append(tmp) | ||
return resultlist | ||
|
||
|
||
def isMutillistFill(mutilLsit): | ||
""" | ||
判断一个二维列表中的每一个列表是否都为空 | ||
mutilLsit=[[],[],[]] 返回False | ||
mutilLsit=[[1],[],[]] 返回True | ||
""" | ||
for row in mutilLsit: | ||
if len(row) > 0: | ||
return True | ||
return False | ||
|
||
|
||
def getLeastCommonMutible(numList): | ||
""" | ||
numList 待求数的列表, | ||
返回它们的最小公倍数的质因数列表 | ||
""" | ||
primelists = [] | ||
set1 = set({}) | ||
mutilResult = [] | ||
for i in numList: | ||
primelists.append(getMutiPrime(i)) | ||
set1.update(set(i1 for i1 in getMutiPrime(i))) | ||
# print(primelists) | ||
flag = True | ||
flag1 = False | ||
while flag: | ||
for i in set1: | ||
for row in primelists: | ||
if i in row: | ||
row.remove(i) | ||
flag1 = True | ||
if flag1: | ||
mutilResult.append(i) | ||
flag1 = False | ||
flag = isMutillistFill(primelists) | ||
# print(mutilResult) | ||
return mutilResult | ||
|
||
|
||
def getMutil(numList): | ||
result = 1 | ||
for i in numList: | ||
result *= i | ||
return result | ||
|
||
def getLCM(numList): | ||
return getMutil(getLeastCommonMutible(numList)) | ||
|
||
if __name__ == '__main__': | ||
print(getLCM([3, 4, 5]))# 获取8,12,20的最小公倍数 | ||
print(getLCM([i for i in range(2, 21)])) # 获取1到20的所有数的最小公倍数 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# 欧几里德定理求2个数的最大公约数 | ||
def gcd(a, b): | ||
if b == 0: | ||
return a | ||
else: | ||
return gcd(b, a % b) | ||
|
||
|
||
def mgcd(s): | ||
# 两两求最大公约数,会得到1个数组,在这个数组里再两两求公约数,如此递归,最终会得到1个只有1个数的数组,就是最大公约数 | ||
if len(s) == 1: | ||
return s[0] | ||
elif len(s) == 2: | ||
return gcd(s[0], s[1]) | ||
else: | ||
cd = [] | ||
for i in s: | ||
# 不求自己与自己的最大公约数 | ||
if i != s[0]: | ||
cd.append(gcd(s[0], i)) | ||
# 去除数组中的重复数据 | ||
cd = list(set(cd)) | ||
return mgcd(cd) | ||
|
||
|
||
def greatest_common_divisor(*args): | ||
""" | ||
Find the greatest common divisor | ||
""" | ||
# 两两求最大公约数,会得到1个数组,在这个数组里再两两求公约数,如此递归,最终会得到1个只有1个数的数组,就是最大公约数 | ||
return mgcd(args) | ||
|
||
|
||
if __name__ == '__main__': | ||
# These "asserts" using only for self-checking and not necessary for auto-testing | ||
print(greatest_common_divisor(3, 4)) | ||
print(greatest_common_divisor(3, 4, 5)) | ||
print(greatest_common_divisor(3, 4, 5, 6)) | ||
print(greatest_common_divisor(3, 4, 5, 6, 7)) |