def get_intersection_tree(T1, T2): T = Tree(tree=T1, deep=True) T1_bfs = [n for n in T1.expand_tree(mode=1)] T2_bfs = [n for n in T2.expand_tree(mode=1)] for nid in T1_bfs: X = set(get_leaf_node_ids_for_node(T, nid)) diff = min([len(X.symmetric_difference(set( \ get_leaf_node_ids_for_node(T2,i)))) \ for i in T2_bfs]) if diff != 0: par = T.parent(nid).identifier for c in T.children(nid): T.move_node(c.identifier, par) T.remove_subtree(nid) return T
def crossOver(individualA, individualB): tree = None while tree is None or tree.depth(tree.get_node(tree.root)) > TREE_MAX_DEPTH: treeA = Tree(tree = individualA.tree, deep=True) treeB = Tree(tree = individualB.tree, deep=True) regenerate_ids(treeA) regenerate_ids(treeB) removedNode = random.choice(treeA.all_nodes()) addedNode = random.choice(treeB.all_nodes()) addedSubtree = Tree(tree = treeB.subtree(addedNode.identifier), deep=True) if treeA.root == removedNode.identifier: tree = addedSubtree else: parent = treeA.parent(removedNode.identifier) treeA.remove_subtree(removedNode.identifier) treeA.paste(parent.identifier, addedSubtree) tree = treeA return Individual(tree)
def swap(tree): internalNodes = [n for n in tree.all_nodes_itr() if n.var != None] if len(internalNodes) == 1: return tree internalNodes.remove(tree[0]) cNode = random.choice(internalNodes) tagc = (cNode.identifier, cNode.var, cNode.split) pid = cNode.bpointer tree1 = Tree(tree, deep=True) sub = tree1.remove_subtree(pid) tags = recurTag(sub, pid) tagp = tags[0] tags[tags.index(tagc)] = (tagc[0], tagp[1], tagp[2]) tags[0] = (tagp[0], tagc[1], tagc[2]) string = f'{mi} swap {t}: {tags[0]}; ' try: sub1 = genTree(tree[pid], tags) except IndexError: print(string + 'unswappable') return tree #rTransit = 1 rLike = get_like_ratio(tree.R, sub.leaves(), sub1.leaves()) rStruct = get_struct(sub.all_nodes_itr(), sub1.all_nodes_itr()) r = rLike * rStruct print(string + f'{r.round(4)}') if random.uniform(0, 1) < r: if pid > 0: gpid = tree[pid].bpointer tree1.paste(gpid, sub1) tree1[gpid].fpointer = sorted(tree1[gpid].fpointer) else: tree1 = sub1 tree1.w2 = tree.w2 tree1.R = tree.R tree1.leaf = [n.identifier for n in tree1.leaves() if len(n.xvar) > 0] tree1.show() return tree1 return tree
class FTPClient(QtWidgets.QLabel): """ FTP 连接类 """ _signal = pyqtSignal(str) def __del__(self): """ 退出时执行ftp断开 :return: """ print("connect close") self.ftp.close() #self._signal.emit('Del') def __init__(self, host: str, username: str, password: str, port='21'): """ 初始化 FTP 输入主机 端口用户名密码 之后连接FTP服务器 :param host: 主机 :param username: 用户名 :param password: 密码 :param port: 端口 """ print("init") super(FTPClient, self).__init__() self.host = host self.port = int(port) self.username = username self.password = password def startConnect(self): """ 建立FTP连接 :return: """ self.nowDirName = 'root' #建立文件树 和根节点 self.tree = Tree() itemProject = QStandardItem('root') itemProject.setIcon(self.getIcon()) self.tree.create_node('root', 'root', parent=None, data=itemProject) # 连接FTP 连接成功之后 创建root的子目录 self.ftp_connect() self.createTree(self.ftp.nlst(), 'root') #print('pwd',self.ftp.pwd()) # 以下注释部分完成了 在ftp上文件系统内部的跳转 和列出文件系统 #print('cwd0428',self.ftp.cwd('0428')) #print('nlst',self.ftp.nlst()) #print('pwd',self.ftp.pwd()) #print('cwd0428', self.ftp.cwd('Laser')) #print('nlst', self.ftp.nlst()) #print('pwd', self.ftp.pwd()) #self.createTree(self.ftp.nlst(), 'root/0428') self.tree.show() self._signal.emit("OK") # 信号发送 #print("EMIT OK") #print(self.tree.children('root')) #self.download_file('/readme.txt','G:/data_sun/readme.txt') def restartTree(self): print("刷新树") self.tree.remove_subtree('root') itemProject = QStandardItem('root') itemProject.setIcon(self.getIcon()) self.tree.create_node('root', 'root', parent=None, data=itemProject) self.ftp.cwd('/') self.createTree(self.ftp.nlst(), 'root') def createTree(self, chiledList: list, parent: str) -> bool: """ 通过输入的 子目录列表 和父目录的名称 进行建立文件树 :param chiledList: 下一层目录所有的文件列表 :param parent: 父路径名字 :return: 是否创建了子树 0创建失败 1创建成功 """ if self.tree.subtree(parent).depth() == 0: #当前子树深度 为0 那么说明还没有刷新该节点 print("叶节点,开始创建文件子树") else: print("不是叶节点") return 0 #按照列表内部的数据 依此建树 树的名称均为 父路径 + / + 当前文件名称(主要为了实现唯一标识 不然不同文件夹下相同的文件名 就会出错) for i in chiledList: itemProject = QStandardItem((parent + '/' + i)) #print((parent+'/'+i),(parent+'/'+i).split('.')) if len((parent + '/' + i).split('.')) == 1: #如果是文件夹 那么获取系统的文件夹的图标 itemProject.setIcon(self.getIcon()) else: itemProject.setIcon( self.getIcon('.' + (parent + '/' + i).split('.')[-1])) self.tree.create_node( parent + '/' + i.encode('utf-8').decode('utf-8'), parent + '/' + i.encode('utf-8').decode('utf-8'), parent=parent, data=itemProject) # 根节点 return 1 def ftp_connect(self): """ FTP的具体连接类 :return: None """ self.ftp = FTP() # ftp.set_debuglevel(2) #连接主机 self.ftp.connect(self.host, self.port) #实现登录 self.ftp.login(self.username, self.password) self.ftp.encoding = 'utf-8' print("log in success") def getIcon(self, extension='file'): """ 获取扩展名在操作系统下的默认图标 :param extension: 文件扩展名 如果不写默认为是文件 :return: 对应的图标 """ provider = QFileIconProvider() tmpFile = QTemporaryFile('./_aa' + extension) tmpFile.setAutoRemove(False) icon = provider.icon(QFileInfo('./_aa' + extension)) if extension == 'file': # 首先生成一个临时文件 之后获取临时文件的图标返回 fileInfo = QFileInfo("C:\\Users") fileIcon = QFileIconProvider() #print(fileInfo, fileIcon) icon = QIcon(fileIcon.icon(fileInfo)) return icon return icon def download_file(self, remotepath: str, localpath: str): """ 从远程FTP服务器下载文件 到本地路径 :param remotepath: 远端路径 :param localpath: 本地路径 :return: None """ remotepath = remotepath.replace('//', '/') localpath = localpath.replace('//', '/') if os.path.isdir(remotepath) or len(remotepath.split('.')) == 1: #是文件夹 self.download_dir(remotepath, localpath) return print("是文件") bufsize = 1024 fp = open(localpath, 'wb') self.ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize) self.ftp.set_debuglevel(0) fp.close() print("下载远程文件:", remotepath, "\t到本地路径:", localpath, "成功") def download_dir(self, remotedir: str, localdir: str): """ 下载远程的文件夹到本地文件夹 例如 download_dir('/test','G:/ftpdata/test10') 或者download_dir('test','G:/ftpdata/test10') 后面这个会新建一个test文档 之前那个新建/test会报错 因此就不会创建 :param remotedir: 远程文件夹 :param localdir: 本地文件夹 :return: """ try: os.makedirs(localdir) # 由于我之前的处理是 将文件夹直接加到了 本地连接的后面 所以需要先新建一个文件夹 except OSError: print("本地文件已经存在,不进行新建") pass print("开始下载文件夹:从 ", remotedir, " 到 ", localdir) os.chdir(localdir) self.walk(remotedir, localdir) print("文件夹下载结束") def get_dirs_files(self): """ 获取当前目录的文件夹和文件 :return: (当前目录下的文件,当前目录下的文件夹) """ dir_res = [] self.ftp.dir('.', dir_res.append) files = [f.split(None, 8)[-1] for f in dir_res if f.startswith('-')] dirs = [f.split(None, 8)[-1] for f in dir_res if f.startswith('d')] return (files, dirs) def walk(self, remotedir, localdir): """ 在文件夹内部递归 单个传递每一个文件 直到文件夹内部文件全部传递完毕 :param remotedir: 远程文件夹 :param localdir: 本地文件夹 :return: """ print('Walking to', remotedir, os.getcwd()) self.ftp.cwd(remotedir) try: os.mkdir(remotedir) except OSError: print("创建文件夹失败,文件夹可能已经存在") pass os.chdir(localdir) print("now dir", os.getcwd()) ftp_curr_dir = self.ftp.pwd() print("local dir", localdir) files, dirs = self.get_dirs_files() print("FILES: ", files) print("DIRS: ", dirs) for f in files: print(remotedir, ':', f) outf = open(f, 'wb') try: self.ftp.retrbinary('RETR %s' % f, outf.write) finally: outf.close() for d in dirs: print("Dir:", d, ftp_curr_dir) os.chdir(localdir) #self.ftp.cwd(ftp_curr_dir) self.walk(d, os.path.join(localdir, d)) self.ftp.cwd('..') #不加这句的话 只能递归一层 之后会出错 def uploadFile(self, remotepath='./', localpath='./'): print("Upload", localpath, remotepath, os.path.isfile(localpath)) if not os.path.isfile(localpath): return print('+++ upload %s to %s' % (localpath, remotepath)) self.ftp.storbinary('STOR ' + remotepath, open(localpath, 'rb')) def upload_dir(self, remotedir='./', localdir='./'): ''' 实现文件的上传 :param localdir: :param remotedir: :return: ''' if not os.path.isdir(localdir): return print("Upload dir", remotedir, localdir) try: self.ftp.cwd(remotedir) except: self.ftp.mkd(remotedir) self.ftp.cwd(remotedir) print("远程文件夹创建成功") for file in os.listdir(localdir): # src = os.path.join(localdir, file) src = localdir + '/' + file print(src) if os.path.isfile(src): print("is file") self.uploadFile(file, src) elif os.path.isdir(src): try: self.ftp.mkd(file) except: sys.stderr.write('the dir is exists %s' % file) self.upload_dir(file, src) self.ftp.cwd('..') def upload_file(self, remotepath: str, localpath: str): """ 上传本地文件到服务器 :param remotepath: 远端路径 :param localpath: 本地路径 :return: None """ while '//' in remotepath: remotepath = remotepath.replace('//', '/') while '//' in localpath: localpath = localpath.replace('//', '/') print(remotepath, localpath) if os.path.isdir(remotepath) or len(remotepath.split('.')) == 1: #是文件夹 self.upload_dir(remotepath, localpath) return bufsize = 1024 fp = open(localpath, 'rb') self.ftp.storbinary('STOR ' + remotepath, fp, bufsize) self.ftp.set_debuglevel(0) fp.close() print("上传本地文件:", localpath, "\t到远程:", remotepath, "成功")
def change(tree): nidInternal = nidValid(tree) choices = [getChoice(tree, n) for n in nidInternal] n_choices = map(lambda L: sum([len(i) for i in L]), choices) choiceDic = { a: b for (a, b, c) in zip(nidInternal, choices, n_choices) if c > 1 } choices1 = list(choiceDic.keys()) nid = random.choice(choices1) p = tree[nid].data.shape[1] x0 = tree[nid].var s0 = tree[nid].split choices = choiceDic[nid] # choose nid to split if s0 in choices[x0 - 1]: choices[x0 - 1].remove(s0) # remove original split option choices2 = [i for i in range(p - 1) if len(choices[i]) > 0] # choose var to split x = random.choice(choices2) choices3 = choices[x] # choose value to split x += 1 s = random.choice(choices3) tree1 = Tree(tree, deep=True) pid = tree1[nid].bpointer sub = tree1.remove_subtree(nid) tags = recurTag(sub, nid) tags[0] = (nid, x, s) try: sub1 = genTree(sub[nid], tags) except IndexError: print(f'{mi} change {t}: {tags[0]}; unchangable') return tree if pid is not None: tree1.paste(pid, sub1) tree1[pid].fpointer = sorted(tree1[pid].fpointer) else: tree1 = sub1 nidInternal1 = set(nidValid(tree1)) choices1 = set(choices1) choices11 = nidInternal1.intersection(choices1) extra = nidInternal1 - choices1 n_choices = map(lambda L: sum([len(i) for i in L]), [getChoice(tree1, n) for n in extra]) choices11 = list(choices11) + [ a for (a, b) in zip(extra, n_choices) if b > 1 ] choices31 = getChoice(tree1, nid, x0)[x0 - 1] n31 = len(choices31) if (sub1[nid].var == sub[nid].var) and (s0 in choices31): n31 -= 1 rTransit = len(choices1) * len(choices3) / (len(choices11) * n31) rLike = get_like_ratio(tree.R, sub.leaves(), sub1.leaves()) rStruct = get_struct(sub.all_nodes_itr(), sub1.all_nodes_itr()) r = rLike * rTransit * rStruct print(f'{mi} change {t}: {tags[0]}; r={r.round(4)}') if random.uniform(0, 1) < r: tree1.w2 = tree.w2 tree1.R = tree.R tree1.leaf = [n.identifier for n in tree1.leaves() if len(n.xvar) > 0] tree1.show() return tree1 return tree
class BasicTree: def __init__(self, vehsInfo): self.tree = Tree() self.root = self.tree.create_node("Root", "root") # root node self.vehsInfo = vehsInfo self.vehList = list(vehsInfo.keys()) self.i = 1 def _build(self, currentNode, vehList): ''' :param vehList: A dict, keys is the set of vehicles, value is a tuple which represents (lane, position) :param currentNode: The current node in the tree :return: None ''' s = [currentNode.tag.find(vid) for vid in vehList] # the quit contidion in recursion if (np.array(s) >= 0).all(): return for vehId in vehList: if vehId not in currentNode.tag: if currentNode.is_root: prefix = currentNode.tag.replace("Root", "") else: prefix = currentNode.tag self.tree.create_node(prefix + vehId + "-", prefix + vehId, parent=currentNode) for node in self.tree.all_nodes(): if node.is_leaf(): self._build(currentNode=node, vehList=vehList) def _prune(self): laneId = [value[0] for value in self.vehsInfo.values()] sortedList = [] for i in list(set(laneId)): lane_info = {k: v[1] for k, v in self.vehsInfo.items() if v[0] == i} # Vehicles in front are at the front of the lane sortedList.append([vid[0] for vid in sorted(lane_info.items(), key=itemgetter(1), reverse=True)]) pruneList = [sublist for sublist in sortedList if len(sublist) > 1] for subList in pruneList: for index in range(1, len(subList)): # first, prune th subtree which begin with illegal vehicle id self.tree.remove_subtree(subList[index]) # second, delete the nodes which match the illegal pattern pattern = subList[index] + ".*" + subList[0] for node in self.tree.all_nodes(): if re.search(pattern, node.tag): try: self.tree.remove_node(node.identifier) except: pass def build(self): self._build(self.root, self.vehList) self._prune() def show(self): self.tree.show() def _leaves(self): ''' :return: All the plan for vehicle passing currently. ''' all_nodes = self.tree.all_nodes() return [node for node in all_nodes if node.is_leaf()] def legal_orders(self): leaves = self._leaves() orders = [] for pattern in leaves: # upToRight.1-leftToBelow.18-belowToRight.2-belowToRight.3- tmp = pattern.tag.split("-") try: tmp.remove('') except: pass if len(tmp) == self.tree.depth(): orders.append(tmp) return orders