Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
kidxiang authored Sep 5, 2019
1 parent bcd05c0 commit 31fe13a
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 0 deletions.
65 changes: 65 additions & 0 deletions FindSlice.py
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的分片组合

103 changes: 103 additions & 0 deletions LeastCommonMultiple.py
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的所有数的最小公倍数
39 changes: 39 additions & 0 deletions MaximumCommonDivisor.py
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))

0 comments on commit 31fe13a

Please sign in to comment.