Python复现:HS2:Active learning over hypergraphs with pointwise and pairwise queries

本文详细介绍了HS2算法在超图上的应用,通过Swendsen-Wang采样构建超图,并利用主动学习策略选择关键样本点。在去除截超边后,采用最短路径寻找关键超边,通过MSSP(最小割超边选择)方法选取无标记顶点。代码实现中包含了广度优先搜索和随机选点策略,用于在有限预算下进行样本选择。实验结果显示了HS2算法在不同预算下的运行情况。
摘要由CSDN通过智能技术生成

目标文献:

I (Eli) Chien,Huozhi Zhou and Pan Li . HS2:Active learning over hypergraphs with pointwise and pairwise queries. In:  Proceedings of the 22nd International Conference on Artificial Intelligence and Statistics (AISTATS) 2019, Naha,
Okinawa, Japan.  【CCF C类会议】

存在的case:

作者在文中没有交代通过MSSP找到最短路径中的中间超边后,如何从中间超边中选择关键样本点。所以代码中使用随机选点法获取中间超边中的任意一个无标记顶点。

要点:

- 超图构建使用了SWS(Swendsen-Wang Sampling)构建order=5,edgeNum=样本数的超图,这里调用matlab代码。ps:需要python3.6以下版本

- 使用了广度优先所有BFS(Breadth-first search)寻找两个不同类别已标记样本的之间的最短路径。

- 使用MSSP获取关键超边,使用Random choice获取关键超边的关键样本顶点。

 

写了一整天才搞出来,都成代码复现机器人了,太累了!

不懂可与我交流。包括HS2的存在不足!

本稿未提供sws超图构建的matlab代码!原因你懂!别人的东东!

import numpy as np
import matlab
import matlab.engine
from copy import deepcopy
from itertools import combinations,product
from collections import OrderedDict,deque
from sklearn.datasets import load_iris
from scipy.spatial.distance import pdist,squareform
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import StratifiedKFold

engine = matlab.engine.start_matlab()

class PWHS2():
    def __init__(self,X,y,neiNum,Labeled,Budget,X_test,y_test):
        self.X = X
        self.y = y
        self.labels = np.unique(y)
        self.labNum = len(self.labels)
        self.labeled = list(Labeled)
        self.label_pair = list(combinations(self.labels, 2))
        self.labeled_dict = self.init_labeled_dict()
        self.N = len(y)
        self.budget = deepcopy(Budget)
        self.budgetLeft = deepcopy(Budget)
        self.recordNote = [i for i in np.arange(self.labNum, self.budget + 1, self.labNum)]
        self.initNum = len(self.labels)
        self.unlabeled = self.init_unlabeled()
        self.neiNum = neiNum
        self.dist_matrix = squareform(pdist(X=X, metric='euclidean'))
        self.X_test = X_test
        self.y_test = y_test
        self.nn_matrix = np.zeros((self.N,self.neiNum))
        self.nn_list = []
        self.nn_cost = []
        self.hyper_graph = self.init_hyper_graph()
        ###--------------------------
        self.AccList = []
        self.MAEList = []
        self.QYRList = []

    class tree(object):
        def __init__(self, edx):
            self.edx = edx
            self.parent = None
            self.children = []

    def init_unlabeled(self):
        unlabeled = [_ for _ in range(self.N)]
        for idx in self.labeled:
            unlabeled.remove(idx)
        return unlabeled

    def init_labeled_dict(self):
        labeled_dict = OrderedDict()
        for idx in self.labeled:
            labeled_dict[self.y[idx]] = []
        for idx in self.labeled:
            labeled_dict[self.y[idx]].append(idx)
        return labeled_dict

    def init_hyper_graph(self):
        nn_list = []
        nn_cost = []
        for i in range(self.N):
            ord_idx = np.argsort(self.dist_matrix[i])
            neibor = []
            for j in range(self.neiNum + 1):
                if i != ord_idx[j]:
                    neibor.append(ord_idx[j])
            neibor = np.array(neibor)
            self.nn_matrix[i] = neibor

        for i in range(self.N-1):
            for j in range(i,self.N):
                if i in self.nn_matrix[j] or j in self.nn_matrix[i]:
                    nn_list.append([i,j])
                    nn_cost.append(self.dist_matrix[i,j])
        ###调整为matlab索引:所有索引+1
        for i in range(len(nn_list)):
            nn_list[i][0] += 1
            nn_list[i][1] += 1
        nn_list = np.array(nn_list)
        # print("边的个数=",len(nn_list))
        nn_cost = np.array(nn_cost)
        nn_cost = np.vstack(nn_cost)

        e = matlab.double(nn_list.tolist())
        cost = matlab.double(nn_cost.tolist())
        #####调用SWS采样法构建超图################
        hyper_edges = engine.sws(e, cost, self.N)
        hyper_edges = np.array(hyper_edges)
        hyper_edges = hyper_edges.T
        ####调整为python索引:所有索引减去1
        for i in range(hyper_edges.shape[0]):
            for j in range(hyper_edges.shape[1]):
                hyper_edges[i,j] -= 1
        ########################################
        hyper_graph = OrderedDict()
        for idx in range(len(hyper_edges)):
            hyper_graph[idx] = hyper_edges[idx]

        return hyper_graph

    def remove_cuts(self):
        diff_pair_list = []
        for labpair in self.label_pair:
            idx_pair = product(self.labeled_dict[labpair[0]], self.labeled_dict[labpair[1]])
            for pair in idx_pair:
                diff_pair_list.append(pair)
        ### 当一个超边中有diff_pair 则删除这个边
        cut_edge_idxs = []
        for idx, edge in self.hyper_graph.items():
            for pair in diff_pair_list:
                if pair[0] in edge and pair[1] in edge:
                    cut_edge_idxs.append(idx)
                    break
                else:
                    continue
        ###如果cutedge存在,开始删除cutedge
        print("发现截超边CutEdges=",cut_edge_idxs)
        if cut_edge_idxs:
            for idx in cut_edge_idxs:
                del self.hyper_graph[idx]

    def find_children_edge(self,edge):
        children = []
        for idx in self.hyper_graph[edge]:
            for edx, hyperedge in self.hyper_graph.items():
                if idx in hyperedge:
                    children.append(edx)
        return children

    def BFS(self,pair):
        source = pair[0]
        target = pair[1]
        ###########获取目标顶点所在的边####################
        target_visited = []
        for edx, edge in self.hyper_graph.items():
            if target in edge:
                target_visited.append(edx)
        ###如果目标顶点不存在于任何边直接返回空
        if len(target_visited) == 0:
            return []
        ################################################

        ###########获取源头顶点所在的边###################
        source_edges = []
        for edx, edge in self.hyper_graph.items():
            if source in edge:
                source_edges.append(edx)
        ###如果源头顶点不存在于任何边直接返回空
        if len(source_edges) == 0:
            return []
        ####################正式开始#####################
        visited = []
        for edx in source_edges:
            visited.append(edx)

        queue = deque([])
        TreeDict = OrderedDict()
        target_edge = None
        for edx in source_edges:
            children = self.find_children_edge(edx)
            queue.append([edx,children])
            TreeDict[edx] = self.tree(edx)
            TreeDict[edx].children = children

        while queue:
            parent, children = queue.popleft()
            if parent in target_visited:
                target_edge = parent
                break
            for child in children:
                if child not in visited:
                    visited.append(child)
                    grandsons = self.find_children_edge(child)
                    queue.append((child,grandsons))
                    TreeDict[child] = self.tree(child)
                    TreeDict[child].children = grandsons
                    TreeDict[child].parent = parent

        if target_edge == None:
            return []
        else:
            path = []
            current_edge = target_edge
            while current_edge != None:
                path.append(current_edge)
                current_edge = TreeDict[current_edge].parent
            return path



    def mssp(self):
        edge_len_dict = OrderedDict()
        edge_path_dict = OrderedDict()
        for labpair in self.label_pair:
            idx_pairs = product(self.labeled_dict[labpair[0]], self.labeled_dict[labpair[1]])
            for pair in idx_pairs:
                edge_path_dict[pair] = self.BFS(pair)
                if edge_path_dict[pair]:
                    edge_len_dict[pair] = len(edge_path_dict[pair])
                else:
                    edge_len_dict[pair] = np.inf

        tar_pair = min(edge_len_dict,key=edge_len_dict.get)
        vertex = None
        if edge_path_dict[tar_pair]:
            path_jdx = int(np.floor(edge_len_dict[tar_pair]/2))
            mid_edge = edge_path_dict[tar_pair][path_jdx]
            mid_edge_samples = list(deepcopy(self.hyper_graph[mid_edge]))
            while mid_edge_samples:
                vertex = np.random.choice(mid_edge_samples,size=1,replace=False)[0]
                mid_edge_samples.remove(vertex)
                if vertex not in self.labeled:
                    break
                else:
                    vertex = None
                    continue
        return vertex


    def pairwise_HS2(self):
        self.remove_cuts()
        while self.budgetLeft > 0:
            print("进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算{}>>>>>>>>>>>>>>>>>>>>>>>>>>".format(self.budgetLeft))
            vertex = self.mssp()
            if vertex == None:
                vertex = np.random.choice(self.unlabeled, size=1, replace=False)[0]
                print("执行了随机选点获取无标记顶点:",vertex)
            else:
                print("执行MSSP选点获取无标记顶点:",vertex)

            vertex = int(vertex)  ###强制类型转换为int

            current_budget = len(self.labels)
            for lab in self.labels:
                if self.budgetLeft <= 0:
                    break
                else:
                    self.budgetLeft -= 1
                    current_budget -= 1
                    #####测试并保存分类指标
                    if (self.budget - self.budgetLeft) in self.recordNote:
                        self.pred()
                    #####################
                if current_budget <= 1:
                    self.labeled.append(vertex)
                    self.labeled_dict[self.y[vertex]].append(vertex)
                    self.unlabeled.remove(vertex)
                    break
                else:
                    if self.y[vertex] == lab:
                        self.labeled.append(vertex)
                        self.labeled_dict[self.y[vertex]].append(vertex)
                        self.unlabeled.remove(vertex)
                        break
                    else:
                        continue
            print("已标记列表",self.labeled)
            print("已标记字典",self.labeled_dict)

            self.remove_cuts()
            if self.budget <= 0:
                break

    def pred(self):
        model = LogisticRegression(solver='newton-cg', penalty='l2')
        model.fit(self.X[self.labeled],self.y[self.labeled])
        y_pred = model.predict(self.X_test)
        self.AccList.append(accuracy_score(y_true=self.y_test,y_pred=y_pred))
        self.MAEList.append(np.mean(abs(self.y_test - y_pred)))
        self.QYRList.append((len(self.labeled)-self.initNum)/(self.budget-self.budgetLeft))

if __name__ == '__main__':

    X, y = load_iris(return_X_y=True)
    class_num = len(np.unique(y))
    budget = 10 * class_num
    round = 5
    ACC = np.zeros(int(budget/class_num))
    MAE = np.zeros(int(budget/class_num))
    QYR = np.zeros(int(budget/class_num))
    for t in range(round):
        SKF = StratifiedKFold(n_splits=10, shuffle=True)
        for train_idx, test_idx in SKF.split(X, y):
            train_X = X[train_idx]
            train_y = y[train_idx]
            test_X = X[test_idx]
            test_y = y[test_idx]
            labeled = []
            label_dict = OrderedDict()
            for lab in np.unique(train_y):
                label_dict[lab] = []
            for idx in range(len(train_y)):
                label_dict[train_y[idx]].append(idx)
            for idxlist in label_dict.values():
                for jdx in np.random.choice(idxlist,size=1,replace=False):
                    labeled.append(jdx)
            print("标记预算",budget)
            pwhs2 = PWHS2(X=train_X,y=train_y,neiNum=5,Labeled=labeled,Budget=budget,X_test=test_X,y_test=test_y)
            print(pwhs2.hyper_graph)
            print(len(pwhs2.hyper_graph))
            pwhs2.remove_cuts()
            print(pwhs2.hyper_graph)
            print(len(pwhs2.hyper_graph))

            print("开始执行HS2")
            pwhs2.pairwise_HS2()
            print("剩余标记预算",pwhs2.budgetLeft)

            break
        break

输出:

标记预算 30
OrderedDict([(0, array([34.,  1., 35., 21., 14.])), (1, array([111.,  66.,  69., 127.,  62.])), (2, array([14., 13., 43., 29.,  1.])), (3, array([ 54., 106.,  86., 111.,  64.])), (4, array([31., 15., 27., 32., 43.])), (5, array([20., 32., 17., 16., 37.])), (6, array([ 94.,  63.,  78., 131.,  84.])), (7, array([ 70., 106., 126.,  99.,  57.])), (8, array([18., 13.,  4., 26., 31.])), (9, array([ 56., 126., 120., 117.,  48.])), (10, array([109.,  78.,  83.,  75.,  46.])), (11, array([ 86.,  83., 134., 133.,  91.])), (12, array([ 70., 132.,  74.,  87., 119.])), (13, array([ 86., 118.,  93.,  51., 130.])), (14, array([ 54.,  52., 108.,  64.,  80.])), (15, array([101., 126.,  99., 133., 102.])), (16, array([119.,  85., 117.,  66., 102.])), (17, array([43., 42., 20., 18., 36.])), (18, array([ 70.,  82., 109., 115.,  77.])), (19, array([124.,  56.,  58., 130., 107.])), (20, array([14., 22., 30., 18., 19.])), (21, array([27., 24., 28.,  4., 11.])), (22, array([ 0.,  4., 42., 13., 35.])), (23, array([ 87., 112.,  45.,  95.,  67.])), (24, array([100.,  70.,  65., 104.,  51.])), (25, array([ 81.,  45., 127.,  90., 121.])), (26, array([ 46.,  93., 119., 127., 106.])), (27, array([ 78.,  73., 115., 131.,  63.])), (28, array([ 49.,  54., 118.,  84.,  76.])), (29, array([ 84.,  99., 131., 105., 119.])), (30, array([ 54., 110.,  57., 122.,  46.])), (31, array([37.,  7.,  8., 38., 41.])), (32, array([113.,  46., 103.,  63.,  96.])), (33, array([ 85.,  50., 103., 106., 102.])), (34, array([ 1., 12., 13., 35., 43.])), (35, array([38.,  3., 21.,  4., 34.])), (36, array([32., 23., 11., 36., 22.])), (37, array([ 5., 20., 25.,  9., 39.])), (38, array([14.,  1., 42., 22.,  9.])), (39, array([29., 23., 22., 33., 20.])), (40, array([ 92., 109.,  88.,  52., 104.])), (41, array([38., 22., 36.,  2., 13.])), (42, array([14., 15., 17., 32., 12.])), (43, array([ 50., 105.,  48.,  95., 121.])), (44, array([114.,  56., 101.,  50., 127.])), (45, array([105., 121.,  82.,  88.,  67.])), (46, array([20., 12., 23., 32., 33.])), (47, array([ 51.,  70., 107.,  67.,  57.])), (48, array([127., 109., 113.,  75.,  48.])), (49, array([ 98.,  92., 113., 111.,  73.])), (50, array([ 83., 111., 131., 108.,  54.])), (51, array([15., 23., 29., 25., 35.])), (52, array([35.,  7., 12., 14., 27.])), (53, array([ 89.,  92.,  64., 112.,  68.])), (54, array([30., 24., 12., 41., 35.])), (55, array([35., 34., 22.,  7.,  1.])), (56, array([32., 27., 28., 16., 23.])), (57, array([28., 35.,  2., 31., 13.])), (58, array([103., 121.,  95., 123.,  70.])), (59, array([34.,  2., 27., 33., 32.])), (60, array([19.,  8., 15., 18.,  6.])), (61, array([56., 54., 51., 81., 68.])), (62, array([ 52., 100., 106., 111.,  78.])), (63, array([14.,  9., 24., 36., 38.])), (64, array([ 9., 22., 41., 26.,  8.])), (65, array([42., 29., 32., 11., 28.])), (66, array([10., 17.,  2., 41., 31.])), (67, array([108.,  80., 101., 104., 119.])), (68, array([31., 34., 23.,  8.,  0.])), (69, array([26., 22., 16., 33., 34.])), (70, array([30., 16., 19., 43., 21.])), (71, array([ 69., 114.,  98., 101., 126.])), (72, array([16., 12., 10.,  7.,  6.])), (73, array([32., 36., 13.,  0., 34.])), (74, array([108.,  78.,  56., 127., 104.])), (75, array([14.,  2.,  7., 23., 35.])), (76, array([ 53.,  62., 115.,  52.,  61.])), (77, array([13., 34., 12.,  0., 25.])), (78, array([ 4., 43., 44., 33., 34.])), (79, array([117., 100.,  73.,  67., 113.])), (80, array([ 64.,  48.,  98., 110.,  67.])), (81, array([ 9., 39., 24.,  7., 20.])), (82, array([114.,  85., 105., 108.,  65.])), (83, array([30., 33.,  0., 27.,  2.])), (84, array([ 9., 27., 30., 13., 10.])), (85, array([29., 35., 44., 34.,  6.])), (86, array([ 96.,  56., 109.,  79.,  51.])), (87, array([18.,  6.,  5., 43.,  1.])), (88, array([ 5., 23., 32., 44., 12.])), (89, array([ 53.,  67.,  60., 100.,  61.])), (90, array([23., 36., 44., 30., 29.])), (91, array([104., 103.,  50.,  99., 127.])), (92, array([118.,  84.,  99.,  50.,  49.])), (93, array([44., 16.,  4., 25., 19.])), (94, array([95., 50., 85., 76., 84.])), (95, array([ 99., 131., 133.,  77., 123.])), (96, array([ 90., 128.,  49.,  62., 127.])), (97, array([103., 113., 107., 128.,  65.])), (98, array([132., 107.,  84.,  79.,  85.])), (99, array([10., 18., 15., 14.,  2.])), (100, array([16., 14.,  4., 28., 22.])), (101, array([123., 130., 114.,  54., 100.])), (102, array([116., 118.,  76.,  82.,  55.])), (103, array([20., 17., 44., 18.,  2.])), (104, array([15.,  4., 33., 35., 41.])), (105, array([18., 13., 43.,  2., 15.])), (106, array([31., 13., 15.,  9., 38.])), (107, array([19.,  4.,  2., 35., 31.])), (108, array([118., 105.,  99.,  57.,  96.])), (109, array([ 1., 28., 13., 17.,  2.])), (110, array([39.,  2.,  8., 36., 23.])), (111, array([56., 70., 55., 86., 89.])), (112, array([ 93.,  78.,  88., 113.,  54.])), (113, array([39., 13., 16., 24., 18.])), (114, array([ 68.,  48.,  67., 117., 116.])), (115, array([12., 21., 30., 34., 27.])), (116, array([21., 35., 22., 15., 26.])), (117, array([28., 25., 30., 14., 41.])), (118, array([124.,  79., 103., 127.,  64.])), (119, array([ 3., 12., 15.,  5.,  8.])), (120, array([28., 39., 32., 22.,  9.])), (121, array([ 99.,  82.,  50., 112., 122.])), (122, array([40., 18., 31., 30., 38.])), (123, array([43., 38., 40.,  1.,  4.])), (124, array([12., 13., 31., 26., 27.])), (125, array([116.,  53., 119.,  50.,  63.])), (126, array([34., 20., 44., 31., 12.])), (127, array([130., 118., 105., 111.,  76.])), (128, array([11., 20., 10.,  7., 14.])), (129, array([19., 20., 27.,  4.,  7.])), (130, array([ 60.,  57., 125., 117.,  81.])), (131, array([43., 14., 22., 12., 23.])), (132, array([31., 18., 38., 37., 34.])), (133, array([16., 26., 44.,  9.,  1.])), (134, array([114.,  89., 129.,  48.,  60.]))])
135
截超边= []
OrderedDict([(0, array([34.,  1., 35., 21., 14.])), (1, array([111.,  66.,  69., 127.,  62.])), (2, array([14., 13., 43., 29.,  1.])), (3, array([ 54., 106.,  86., 111.,  64.])), (4, array([31., 15., 27., 32., 43.])), (5, array([20., 32., 17., 16., 37.])), (6, array([ 94.,  63.,  78., 131.,  84.])), (7, array([ 70., 106., 126.,  99.,  57.])), (8, array([18., 13.,  4., 26., 31.])), (9, array([ 56., 126., 120., 117.,  48.])), (10, array([109.,  78.,  83.,  75.,  46.])), (11, array([ 86.,  83., 134., 133.,  91.])), (12, array([ 70., 132.,  74.,  87., 119.])), (13, array([ 86., 118.,  93.,  51., 130.])), (14, array([ 54.,  52., 108.,  64.,  80.])), (15, array([101., 126.,  99., 133., 102.])), (16, array([119.,  85., 117.,  66., 102.])), (17, array([43., 42., 20., 18., 36.])), (18, array([ 70.,  82., 109., 115.,  77.])), (19, array([124.,  56.,  58., 130., 107.])), (20, array([14., 22., 30., 18., 19.])), (21, array([27., 24., 28.,  4., 11.])), (22, array([ 0.,  4., 42., 13., 35.])), (23, array([ 87., 112.,  45.,  95.,  67.])), (24, array([100.,  70.,  65., 104.,  51.])), (25, array([ 81.,  45., 127.,  90., 121.])), (26, array([ 46.,  93., 119., 127., 106.])), (27, array([ 78.,  73., 115., 131.,  63.])), (28, array([ 49.,  54., 118.,  84.,  76.])), (29, array([ 84.,  99., 131., 105., 119.])), (30, array([ 54., 110.,  57., 122.,  46.])), (31, array([37.,  7.,  8., 38., 41.])), (32, array([113.,  46., 103.,  63.,  96.])), (33, array([ 85.,  50., 103., 106., 102.])), (34, array([ 1., 12., 13., 35., 43.])), (35, array([38.,  3., 21.,  4., 34.])), (36, array([32., 23., 11., 36., 22.])), (37, array([ 5., 20., 25.,  9., 39.])), (38, array([14.,  1., 42., 22.,  9.])), (39, array([29., 23., 22., 33., 20.])), (40, array([ 92., 109.,  88.,  52., 104.])), (41, array([38., 22., 36.,  2., 13.])), (42, array([14., 15., 17., 32., 12.])), (43, array([ 50., 105.,  48.,  95., 121.])), (44, array([114.,  56., 101.,  50., 127.])), (45, array([105., 121.,  82.,  88.,  67.])), (46, array([20., 12., 23., 32., 33.])), (47, array([ 51.,  70., 107.,  67.,  57.])), (48, array([127., 109., 113.,  75.,  48.])), (49, array([ 98.,  92., 113., 111.,  73.])), (50, array([ 83., 111., 131., 108.,  54.])), (51, array([15., 23., 29., 25., 35.])), (52, array([35.,  7., 12., 14., 27.])), (53, array([ 89.,  92.,  64., 112.,  68.])), (54, array([30., 24., 12., 41., 35.])), (55, array([35., 34., 22.,  7.,  1.])), (56, array([32., 27., 28., 16., 23.])), (57, array([28., 35.,  2., 31., 13.])), (58, array([103., 121.,  95., 123.,  70.])), (59, array([34.,  2., 27., 33., 32.])), (60, array([19.,  8., 15., 18.,  6.])), (61, array([56., 54., 51., 81., 68.])), (62, array([ 52., 100., 106., 111.,  78.])), (63, array([14.,  9., 24., 36., 38.])), (64, array([ 9., 22., 41., 26.,  8.])), (65, array([42., 29., 32., 11., 28.])), (66, array([10., 17.,  2., 41., 31.])), (67, array([108.,  80., 101., 104., 119.])), (68, array([31., 34., 23.,  8.,  0.])), (69, array([26., 22., 16., 33., 34.])), (70, array([30., 16., 19., 43., 21.])), (71, array([ 69., 114.,  98., 101., 126.])), (72, array([16., 12., 10.,  7.,  6.])), (73, array([32., 36., 13.,  0., 34.])), (74, array([108.,  78.,  56., 127., 104.])), (75, array([14.,  2.,  7., 23., 35.])), (76, array([ 53.,  62., 115.,  52.,  61.])), (77, array([13., 34., 12.,  0., 25.])), (78, array([ 4., 43., 44., 33., 34.])), (79, array([117., 100.,  73.,  67., 113.])), (80, array([ 64.,  48.,  98., 110.,  67.])), (81, array([ 9., 39., 24.,  7., 20.])), (82, array([114.,  85., 105., 108.,  65.])), (83, array([30., 33.,  0., 27.,  2.])), (84, array([ 9., 27., 30., 13., 10.])), (85, array([29., 35., 44., 34.,  6.])), (86, array([ 96.,  56., 109.,  79.,  51.])), (87, array([18.,  6.,  5., 43.,  1.])), (88, array([ 5., 23., 32., 44., 12.])), (89, array([ 53.,  67.,  60., 100.,  61.])), (90, array([23., 36., 44., 30., 29.])), (91, array([104., 103.,  50.,  99., 127.])), (92, array([118.,  84.,  99.,  50.,  49.])), (93, array([44., 16.,  4., 25., 19.])), (94, array([95., 50., 85., 76., 84.])), (95, array([ 99., 131., 133.,  77., 123.])), (96, array([ 90., 128.,  49.,  62., 127.])), (97, array([103., 113., 107., 128.,  65.])), (98, array([132., 107.,  84.,  79.,  85.])), (99, array([10., 18., 15., 14.,  2.])), (100, array([16., 14.,  4., 28., 22.])), (101, array([123., 130., 114.,  54., 100.])), (102, array([116., 118.,  76.,  82.,  55.])), (103, array([20., 17., 44., 18.,  2.])), (104, array([15.,  4., 33., 35., 41.])), (105, array([18., 13., 43.,  2., 15.])), (106, array([31., 13., 15.,  9., 38.])), (107, array([19.,  4.,  2., 35., 31.])), (108, array([118., 105.,  99.,  57.,  96.])), (109, array([ 1., 28., 13., 17.,  2.])), (110, array([39.,  2.,  8., 36., 23.])), (111, array([56., 70., 55., 86., 89.])), (112, array([ 93.,  78.,  88., 113.,  54.])), (113, array([39., 13., 16., 24., 18.])), (114, array([ 68.,  48.,  67., 117., 116.])), (115, array([12., 21., 30., 34., 27.])), (116, array([21., 35., 22., 15., 26.])), (117, array([28., 25., 30., 14., 41.])), (118, array([124.,  79., 103., 127.,  64.])), (119, array([ 3., 12., 15.,  5.,  8.])), (120, array([28., 39., 32., 22.,  9.])), (121, array([ 99.,  82.,  50., 112., 122.])), (122, array([40., 18., 31., 30., 38.])), (123, array([43., 38., 40.,  1.,  4.])), (124, array([12., 13., 31., 26., 27.])), (125, array([116.,  53., 119.,  50.,  63.])), (126, array([34., 20., 44., 31., 12.])), (127, array([130., 118., 105., 111.,  76.])), (128, array([11., 20., 10.,  7., 14.])), (129, array([19., 20., 27.,  4.,  7.])), (130, array([ 60.,  57., 125., 117.,  81.])), (131, array([43., 14., 22., 12., 23.])), (132, array([31., 18., 38., 37., 34.])), (133, array([16., 26., 44.,  9.,  1.])), (134, array([114.,  89., 129.,  48.,  60.]))])
135
开始执行HS2
截超边= []
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算30>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 70.0
已标记列表 [1, 55, 103, 70]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70]), (2, [103])])
截超边= [58]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算28>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 57.0
已标记列表 [1, 55, 103, 70, 57]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57]), (2, [103])])
截超边= []
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算26>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 106.0
已标记列表 [1, 55, 103, 70, 57, 106]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57]), (2, [103, 106])])
截超边= [7]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算24>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 89.0
已标记列表 [1, 55, 103, 70, 57, 106, 89]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89]), (2, [103, 106])])
截超边= []
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算22>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 86.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86]), (2, [103, 106])])
截超边= [3]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算20>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 104.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86]), (2, [103, 106, 104])])
截超边= [24]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算18>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 56.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56]), (2, [103, 106, 104])])
截超边= [74]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算16>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 67.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67]), (2, [103, 106, 104])])
截超边= []
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算14>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 107.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67, 107]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67]), (2, [103, 106, 104, 107])])
截超边= [19, 47]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算12>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 132.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67, 107, 132]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67]), (2, [103, 106, 104, 107, 132])])
截超边= [12]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算10>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 109.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67, 107, 132, 109]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67]), (2, [103, 106, 104, 107, 132, 109])])
截超边= [18, 86]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算8>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 46.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67, 107, 132, 109, 46]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67, 46]), (2, [103, 106, 104, 107, 132, 109])])
截超边= [10, 26, 32]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算6>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 118.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67, 107, 132, 109, 46, 118]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67, 46]), (2, [103, 106, 104, 107, 132, 109, 118])])
截超边= [13, 102, 108]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算4>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 110.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67, 107, 132, 109, 46, 118, 110]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67, 46]), (2, [103, 106, 104, 107, 132, 109, 118, 110])])
截超边= [30, 80]
进入S2>>>>>>>>>>>>>>>>>>>>>>>>>剩余预算2>>>>>>>>>>>>>>>>>>>>>>>>>>
执行MSSP选点获取无标记顶点: 112.0
已标记列表 [1, 55, 103, 70, 57, 106, 89, 86, 104, 56, 67, 107, 132, 109, 46, 118, 110, 112]
已标记字典 OrderedDict([(0, [1]), (1, [55, 70, 57, 89, 86, 56, 67, 46]), (2, [103, 106, 104, 107, 132, 109, 118, 110, 112])])
截超边= [23, 53]
剩余标记预算 0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeniuHe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值