from math import sqrt import matplotlib.pyplot as plt import os def is_number(s): try: float(s) return True except ValueError: pass try: import unicodedata unicodedata.numeric(s) return True except (TypeError,ValueError): pass return False def convertToFloat(DataSet): for i in range(len(DataSet)): for j in range(len(DataSet[i])): if is_number(DataSet[i][j]): DataSet[i][j] = float(DataSet[i][j]) return DataSet def caculateDistance(a: list, b: tuple): d = sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) return d def readLine(m = 0, n = 2, offset = 1): global DataSet lenth = int(DataSet[m][n]) line = [] for i in range(lenth): line.append(DataSet[i + offset]) return line class Person: priority:float def __init__(self, infomationLine): self.name, self.score, self.weightOfGift, self.x_position, self.y_position = infomationLine def getPosition(self): return (self.x_position, self.y_position) def getScore(self): global Score Score += self.score def caculatePriority(self): return self.score / (self.weightOfGift * caculateDistance([0,0], (self.x_position, self.y_position))) class People: info = [] def __init__(self): global DataSet line = readLine(m = 0, n = 3, offset = 1 + int(DataSet[0][2])) for i in line: self.info.append(Person(i)) def visualization(self): x = [] y = [] for i in self.info: x.append(i.x_position) y.append(i.y_position) plt.plot(x, y, 'o') plt.show() class Santa: tableauDeDistribution = [] position = [0.0,0.0] speed = [0.0,0.0] weightOfCarrots:int = 0 weightOfGift:int = 0 def __init__(self): global DataSet self.timeLimit = int(DataSet[0][0]) self.deliveryDistanceLimit = int(DataSet[0][1]) self.speedLimitTable = readLine() def getPosition(self): return self.position def getWeight(self): return self.weightOfCarrots + self.weightOfGift def nowSpeedLimit(self): w = self.getWeight() assert w >= 0 for i in range(len(self.speedLimitTable)): if w < self.speedLimitTable[i][0]: return self.speedLimitTable[i][1] return 0 # DONE 此速度限制speedLimit为限制表不是当前限制,我们下一步要定义nowspeedLimit def isAllowedBySpeedLimit(self, s): return s <= self.nowSpeedLimit() def consumeCarrot(self): assert self.weightOfCarrots >= 1 self.weightOfCarrots -= 1 def AccUp(self, s): if self.timeLimit>0: assert self.isAllowedBySpeedLimit(s) self.speed[1] += s self.consumeCarrot() print("AccUp",int(s), file=output) else: pass def AccDown(self, s): if self.timeLimit>0: assert self.isAllowedBySpeedLimit(s) self.speed[1] -= s self.consumeCarrot() print("AccDown",int(s), file=output) else: pass def AccRight(self, s): if self.timeLimit>0: assert self.isAllowedBySpeedLimit(s) self.speed[0] += s self.consumeCarrot() print("AccRight",int(s), file=output) else: pass def AccLeft(self, s): if self.timeLimit>0: assert self.isAllowedBySpeedLimit(s) self.speed[0] -= s self.consumeCarrot() print("AccLeft",int(s), file=output) else: pass def LoadCarrots(self, w): self.weightOfCarrots += w def LoadGift(self, w): self.weightOfGift += w def DiliveryGift(self,p: Person): if self.timeLimit >=0 and caculateDistance(self.getPosition(), p.getPosition()) <= self.deliveryDistanceLimit: assert caculateDistance(self.getPosition(), p.getPosition()) <= self.deliveryDistanceLimit self.weightOfGift -= p.weightOfGift assert self.weightOfGift >= 0 p.getScore() print("DeliverGift",p.name, file=output) else: pass def Float(self, t:int = 1): if (self.timeLimit - t) >=0: self.position[0] += self.speed[0] * t self.position[1] += self.speed[1] * t self.timeLimit -= t print("Float",int(t), file=output) else: self.timeLimit -= self.timeLimit def getSituation(self): print("Now position is:",self.position) print("Now speed is:",self.speed) print("Now timeLimit is:",self.timeLimit) print("Now weightOfGift is:",self.weightOfGift) print("Now weightOfCarrots is:",self.weightOfCarrots) def generateTableauDeDistribution(self, pp: People): self.tableauDeDistribution = sorted(pp.info, key=lambda x: x.caculatePriority(), reverse=True) return self.tableauDeDistribution def kidoneWay(self,x:int,p:Person): v = self.nowSpeedLimit() if isinstance(x/v,int) and x > 0 : t = x/v self.AccUp(v) self.Float(t) self.AccDown(v) self.Float(1) self.DiliveryGift(p) v = self.nowSpeedLimit() t = x/v self.AccDown(v) self.Float(t) self.AccUp(v) self.Float(1) elif isinstance(x/v,int) and x < 0 : t = abs(x)/v self.AccDown(v) self.Float(t) self.AccUp(v) self.Float(1) self.DiliveryGift(p) v = self.nowSpeedLimit() t = abs(x)/v self.AccUp(v) self.Float(t) self.AccDown(v) self.Float(1) elif x < v and x > 0 : v = x self.AccUp(v) self.Float(1) self.AccDown(v) self.Float(1) self.DiliveryGift(p) v = self.nowSpeedLimit() v = x self.AccDown(v) self.Float() self.AccUp(v) self.Float(1) elif abs(x) < v and x < 0 : v = abs(x) self.AccDown(v) self.Float(1) self.AccUp(v) self.Float(1) self.DiliveryGift(p) v = self.nowSpeedLimit() v = abs(x) self.AccUp(v) self.Float(1) self.AccDown(v) self.Float(1) elif x > v and x > 0 : t = x//v v1 = v - (x - t*v) self.AccUp(v) self.Float(t) self.AccDown(v1) self.Float() self.AccDown(v - v1) self.Float(1) self.DiliveryGift(p) v = self.nowSpeedLimit() t = x//v v1 = v - (x - t*v) self.AccDown(v) self.Float(t) self.AccUp(v1) self.Float(1) self.AccUp(v - v1) self.Float(1) elif abs(x) > v and x < 0 : t = abs(x)//v v1 = v - (abs(x) - t*v) self.AccDown(v) self.Float(t) self.AccUp(v1) self.Float(1) self.AccUp(v - v1) self.Float(1) self.DiliveryGift(p) v = self.nowSpeedLimit() t = abs(x)//v v1 = v - (abs(x) - t*v) self.AccUp(v) self.Float(t) self.AccDown(v1) self.Float(1) self.AccDown(v - v1) self.Float(1) else: self.DiliveryGift(p) def oneWay(self, p:Person): if self.timeLimit >0: self.LoadCarrots(12) print("LoadCarrots 12", file=output) self.LoadGift(p.weightOfGift) print("LoadGift",p.name, file=output) v = self.nowSpeedLimit() if isinstance(p.x_position/v,int) and p.x_position > 0 : t = p.x_position/v self.AccRight(v) self.Float(t) self.AccLeft(v) self.Float(1) self.kidoneWay(p.y_position,p) t = p.x_position/v self.AccLeft(v) self.Float(t) self.AccRight(v) self.Float(1) elif isinstance(p.x_position/v,int) and p.x_position < 0: t = abs(p.x_position)/v self.AccLeft(v) self.Float(t) self.AccRight(v) self.Float(1) self.kidoneWay(p.y_position,p) t = abs(p.x_position)/v self.AccRight(v) self.Float(t) self.AccLeft(v) self.Float(1) elif p.x_position < v and p.x_position > 0 : v = p.x_position self.AccRight(v) self.Float(1) self.AccLeft(v) self.Float(1) self.kidoneWay(p.y_position,p) v = p.x_position self.AccLeft(v) self.Float(1) self.AccRight(v) self.Float(1) elif abs(p.x_position) < v and p.x_position < 0 : v = abs(p.x_position) self.AccLeft(v) self.Float(1) self.AccRight(v) self.Float(1) self.kidoneWay(p.y_position,p) v = abs(p.x_position) self.AccRight(v) self.Float(1) self.AccLeft(v) self.Float(1) elif p.x_position > v and p.x_position > 0 : t = p.x_position//v v1 = v - (p.x_position - t*v) self.AccRight(v) self.Float(t) self.AccLeft(v1) self.Float(1) self.AccLeft(v - v1) self.Float(1) self.kidoneWay(p.y_position,p) t = p.x_position//v v1 = v - (p.x_position - t*v) self.AccLeft(v) self.Float(t) self.AccRight(v1) self.Float(1) self.AccRight(v - v1) self.Float(1) elif abs(p.x_position) > v and p.x_position < 0 : t = abs(p.x_position)//v v1 = v - (abs(p.x_position) - t*v) self.AccLeft(v) self.Float(t) self.AccRight(v1) self.Float(1) self.AccRight(v - v1) self.Float(1) self.kidoneWay(p.y_position,p) t = abs(p.x_position)//v v1 = v - (abs(p.x_position) - t*v) self.AccRight(v) self.Float(t) self.AccLeft(v1) self.Float(1) self.AccLeft(v - v1) self.Float(1) elif p.x_position == 0 : self.kidoneWay(p.y_position,p) def line_prepender(f, line): content = f.read() f.seek(0, 0) f.write(line.rstrip('\r\n') + '\n' + content) File_Directory = 'DataSet/' Output_File_Directory = 'Output/' files = os.listdir(File_Directory) out_files = os.listdir(Output_File_Directory) for File_Name in files: File_Path = File_Directory+File_Name Output_File_Path = Output_File_Directory+File_Name.replace("in", "out") DataSet = [line.strip().split() for line in open(File_Path, "r")] DataSet = convertToFloat(DataSet) Score:int = 0 s = Santa() pp = People() s.generateTableauDeDistribution(pp) output = open(Output_File_Path, "w+") try: for i in s.generateTableauDeDistribution(pp): s.oneWay(i) except: print("Error in this dataset", file=output) else: pass def line_prepender(filename, line): with open(filename, 'r+') as f: content = f.read() f.seek(0, 0) f.write(line.rstrip('\r\n') + '\n' + content) # count Action for out_file in out_files: Output_File_Path = Output_File_Directory + out_file count = 0 with open(Output_File_Path, 'r') as fp: for count, line in enumerate(fp): pass print(out_file, count + 1) line_prepender(Output_File_Path, str(count+1))