# -*- coding: utf-8 -*-
"""
Created on Tue Jun 29 20:09:47 2021

@author: OuYang
"""
import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
import seaborn as sns
import os
import Models
import Utils
import Test
import Embeddings
import warnings

warnings.filterwarnings('ignore')
sns.set_style('ticks')
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'

if __name__ == '__main__':
    # set seed
    Utils.setup_seed(5)
    # load networks
    # load training networks
    # In[1]
    BA_1000_4 = Utils.load_graph('./Networks/training/Train_1000_4.txt')
    BA_1000_4_sir = pd.read_csv('./SIR results/Train_1000_4/BA_1000_4.csv')
    BA_1000_4_label = dict(zip(np.array(BA_1000_4_sir['Node'],dtype=str),BA_1000_4_sir['SIR']))
    BA_1000_10 = Utils.load_graph('./Networks/training/BA_1000_10.txt')
    BA_1000_20 = Utils.load_graph('./Networks/training/BA_1000_20.txt')

    BA_2000_4 = Utils.load_graph('./Networks/training/BA_2000_4.txt')
    BA_2000_10 = Utils.load_graph('./Networks/training/BA_2000_10.txt')
    BA_2000_20 = Utils.load_graph('./Networks/training/BA_2000_20.txt')

    BA_3000_4 = Utils.load_graph('./Networks/training/BA_3000_4.txt')
    BA_3000_10 = Utils.load_graph('./Networks/training/BA_3000_10.txt')
    BA_3000_20 = Utils.load_graph('./Networks/training/BA_3000_20.txt')

    # load real-world networks
    PowerGrid = Utils.load_graph('./Networks/real/powergrid.txt')
    GrQ = Utils.load_graph('./Networks/real/CA-GrQc.txt')
    Facebook = Utils.load_graph('./Networks/real/facebook_combined.txt')
    Ham = Utils.load_graph('./Networks/real/Peh_edge.txt')
    Hep = Utils.load_graph('./Networks/real/CA-HepTh.txt')
    LastFM = Utils.load_graph('./Networks/real/LastFM.txt')
    Figeys = Utils.load_graph('./Networks/real/figeys.txt')
    Vidal = Utils.load_graph('./Networks/real/vidal.txt')
    Sex = Utils.load_graph('./Networks/real/sex.txt')

    # remove selfloops of real-world networks
    Figeys.remove_edges_from(nx.selfloop_edges(Figeys))
    Vidal.remove_edges_from(nx.selfloop_edges(Vidal))
    GrQ.remove_edges_from(nx.selfloop_edges(GrQ))
    Hep.remove_edges_from(nx.selfloop_edges(Hep))
    LastFM.remove_edges_from(nx.selfloop_edges(LastFM))
    PowerGrid.remove_edges_from(nx.selfloop_edges(PowerGrid))

    # load labels
    # load labels of BA networks
    BA_1000_10_label = Utils.load_sir_list('./SIR results/BA_1000_10/BA_1000_10_')[0]
    BA_1000_20_label = Utils.load_sir_list('./SIR results/BA_1000_20/BA_1000_20_')[0]
    BA_2000_4_label = Utils.load_sir_list('./SIR results/BA_2000_4/BA_2000_4_')[0]
    BA_2000_10_label = Utils.load_sir_list('./SIR results/BA_2000_10/BA_2000_10_')[0]
    BA_2000_20_label = Utils.load_sir_list('./SIR results/BA_2000_20/BA_2000_20_')[0]
    BA_3000_4_label = Utils.load_sir_list('./SIR results/BA_3000_4/BA_3000_4_')[0]
    BA_3000_10_label = Utils.load_sir_list('./SIR results/BA_3000_10/BA_3000_10_')[0]
    BA_3000_20_label = Utils.load_sir_list('./SIR results/BA_3000_20/BA_3000_20_')[0]

    # load labels of real-world networks
    Facebook_SIR = Utils.load_sir_list('./SIR results/Facebook/Facebook_')
    Ham_SIR = Utils.load_sir_list('./SIR results/Ham/Ham_')
    GrQ_SIR = Utils.load_sir_list('./SIR results/GrQ/GrQ_')
    Hep_SIR = Utils.load_sir_list('./SIR results/Hep/Hep_')
    LastFM_SIR = Utils.load_sir_list('./SIR results/LastFM/LastFM_')
    Figeys_SIR = Utils.load_sir_list('./SIR results/Figeys/Figeys_')
    Vidal_SIR = Utils.load_sir_list('./SIR results/vidal/vidal_')
    PowerGrid_SIR = Utils.load_sir_list('./SIR results/powergrid/powergrid_')
    Sex_SIR = Utils.load_sir_list('./SIR results/Sex/Sex_')

    # community division
    _,BA_1000_4_community,_ = Utils.Louvain(BA_1000_4)
    _,Facebook_community,_ = Utils.Louvain(Facebook)
    _,Ham_community,_ = Utils.Louvain(Ham)
    _,Hep_community,_ = Utils.Louvain(Hep)
    _,LastFM_community,_ = Utils.Louvain(LastFM)
    _,Sex_community,_ = Utils.Louvain(Sex)
    _,Figeys_community,_ = Utils.Louvain(Figeys)
    _,PowerGrid_community,_ = Utils.Louvain(PowerGrid)
    _,GrQ_community,_ = Utils.Louvain(GrQ)
    _,Vidal_community,_ = Utils.Louvain(Vidal)

    # basic info of real-world networks
    print('Facebook Network:\n',nx.info(Facebook))
    print('---------------------------')
    print('Ham Network:\n',nx.info(Ham))
    print('---------------------------')
    print('GrQ Network:\n',nx.info(GrQ))
    print('---------------------------')
    print('Hep Network:\n',nx.info(Hep))
    print('---------------------------')
    print('LastFM Network:\n',nx.info(LastFM))
    print('---------------------------')
    print('Figeys Network:\n',nx.info(Ham))
    print('---------------------------')
    print('Vidal Network:\n',nx.info(Hep))
    print('---------------------------')
    print('PowerGrid Network:\n',nx.info(PowerGrid))
    print('---------------------------')
    print('Sex Network:\n',nx.info(Sex))
    # In[2]
    # train model
    # parameters
    L1=28
    L2=28
    batch_size= 32
    num_epochs = 500
    lr = 0.001
    a_list = np.arange(1,2,0.1)
    # construct input
    BA_1000_rcnn = Embeddings.main(BA_1000_4,L1)
    BA_1000_mrcnn = Embeddings.main1(BA_1000_4,L2,BA_1000_4_community)
    BA_1000_mrcnn_com = Embeddings.main2(BA_1000_4,L2,BA_1000_4_community,method='community')
    BA_1000_mrcnn_shell = Embeddings.main2(BA_1000_4,L2,BA_1000_4_community,method='shell')

    # generate DataLoader
    rcnn_loader = Utils.Get_DataLoader(BA_1000_rcnn,BA_1000_4_label,batch_size,L1)
    mrcnn_loader = Utils.Get_DataLoader1(BA_1000_mrcnn,BA_1000_4_label,batch_size,L2)
    mrcnn_loader_com = Utils.Get_DataLoader2(BA_1000_mrcnn_com,BA_1000_4_label,batch_size,L2)
    mrcnn_loader_shell = Utils.Get_DataLoader2(BA_1000_mrcnn_shell,BA_1000_4_label,batch_size,L2)
    # initializing models
    rcnn= Models.CNN(L1)
    mrcnn = Models.CNN1(L2)
    mrcnn_com = Models.CNN2(L2)
    mrcnn_shell = Models.CNN2(L2)
    # train
    RCNN,RCNN_loss = Utils.train_model(rcnn_loader,rcnn,num_epochs,lr,L1)
    MRCNN,MRCNN_loss = Utils.train_model(mrcnn_loader,mrcnn,num_epochs,lr,L2)
    MRCNN_com,MRCNN_com_loss = Utils.train_model(mrcnn_loader_com,mrcnn_com,num_epochs,lr,L2)
    MRCNN_shell,MRCNN_shell_loss = Utils.train_model(mrcnn_loader_shell,mrcnn_shell,num_epochs,lr,L2)
    # test
    # In[3] Experiment 1: Node ranking capability
    Facebook_RCNN_tau,Facebook_MRCNN_tau,Facebook_dc_tau,Facebook_ks_tau,Facebook_nd_tau,Facebook_bc_tau,Facebook_vc_tau = Test.compare_tau(Facebook,L1,L2,Facebook_SIR,Facebook_community,RCNN,MRCNN)
    GrQ_RCNN_tau,GrQ_MRCNN_tau,GrQ_dc_tau,GrQ_ks_tau,GrQ_nd_tau,GrQ_bc_tau,GrQ_vc_tau = Test.compare_tau(GrQ,L1,L2,GrQ_SIR,GrQ_community,RCNN,MRCNN)
    Ham_RCNN_tau,Ham_MRCNN_tau,Ham_dc_tau,Ham_ks_tau,Ham_nd_tau,Ham_bc_tau,Ham_vc_tau = Test.compare_tau(Ham,L1,L2,Ham_SIR,Ham_community,RCNN,MRCNN)
    Hep_RCNN_tau,Hep_MRCNN_tau,Hep_dc_tau,Hep_ks_tau,Hep_nd_tau,Hep_bc_tau,Hep_vc_tau = Test.compare_tau(Hep,L1,L2,Hep_SIR,Hep_community,RCNN,MRCNN)
    LastFM_RCNN_tau,LastFM_MRCNN_tau,LastFM_dc_tau,LastFM_ks_tau,LastFM_nd_tau,LastFM_bc_tau,LastFM_vc_tau = Test.compare_tau(LastFM,L1,L2,LastFM_SIR,LastFM_community,RCNN,MRCNN)
    Figeys_RCNN_tau,Figeys_MRCNN_tau,Figeys_dc_tau,Figeys_ks_tau,Figeys_nd_tau,Figeys_bc_tau,Figeys_vc_tau = Test.compare_tau(Figeys,L1,L2,Figeys_SIR,Figeys_community,RCNN,MRCNN)
    Vidal_RCNN_tau,Vidal_MRCNN_tau,Vidal_dc_tau,Vidal_ks_tau,Vidal_nd_tau,Vidal_bc_tau,Vidal_vc_tau = Test.compare_tau(Vidal,L1,L2,Vidal_SIR,Vidal_community,RCNN,MRCNN)
    PowerGrid_RCNN_tau,PowerGrid_MRCNN_tau,PowerGrid_dc_tau,PowerGrid_ks_tau,PowerGrid_nd_tau,PowerGrid_bc_tau,PowerGrid_vc_tau = Test.compare_tau(PowerGrid,L1,L2,PowerGrid_SIR,PowerGrid_community,RCNN,MRCNN)
    Sex_RCNN_tau,Sex_MRCNN_tau,Sex_dc_tau,Sex_ks_tau,Sex_nd_tau,Sex_bc_tau,Sex_vc_tau = Test.compare_tau(Sex,L1,L2,Sex_SIR,Sex_community,RCNN,MRCNN)
    # visualize results
    plt.figure(figsize=(20,17),dpi=120)
    plt.subplot(331)
    plt.plot(a_list,Facebook_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,Facebook_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,Facebook_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,Facebook_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,Facebook_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,Facebook_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,Facebook_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.title('Facebook',fontsize=20,fontweight='bold')
    plt.ylabel(r'$\tau$',fontsize=24,fontweight='bold')
    plt.text(0.97,0.94,'(a)',fontsize=16,fontweight='bold')

    plt.subplot(332)
    plt.plot(a_list,LastFM_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,LastFM_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,LastFM_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,LastFM_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,LastFM_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,LastFM_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,LastFM_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('LastFM',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.97,0.94,'(b)',fontsize=16,fontweight='bold')

    plt.subplot(333)
    plt.plot(a_list,Sex_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,Sex_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,Sex_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,Sex_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,Sex_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,Sex_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,Sex_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('Sex',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.97,0.94,'(c)',fontsize=16,fontweight='bold')

    plt.subplot(334)
    plt.plot(a_list,Figeys_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,Figeys_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,Figeys_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,Figeys_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,Figeys_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,Figeys_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,Figeys_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.ylabel(r'$\tau$',fontsize=24,fontweight='bold')
    plt.title('Figeys',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.97,0.94,'(d)',fontsize=16,fontweight='bold')

    plt.subplot(335)
    plt.plot(a_list,Hep_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,Hep_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,Hep_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,Hep_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,Hep_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,Hep_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,Hep_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('Hep',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.97,0.94,'(e)',fontsize=16,fontweight='bold')

    plt.subplot(336)
    plt.plot(a_list,Vidal_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,Vidal_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,Vidal_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,Vidal_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,Vidal_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,Vidal_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,Vidal_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('Vidal',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.97,0.94,'(f)',fontsize=16,fontweight='bold')

    plt.subplot(337)
    plt.plot(a_list,GrQ_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,GrQ_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,GrQ_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,GrQ_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,GrQ_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,GrQ_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,GrQ_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('GrQC',fontsize=20,fontweight='bold')
    plt.ylabel(r'$\tau$',fontsize=24,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.xlabel(r'$β/β_{th}$',fontsize=20,fontweight='bold')
    plt.text(0.97,0.94,'(g)',fontsize=16,fontweight='bold')

    plt.subplot(338)
    plt.plot(a_list,Ham_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,Ham_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,Ham_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,Ham_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,Ham_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,Ham_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,Ham_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('Hamster',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.xlabel(r'$β/β_{th}$',fontsize=20,fontweight='bold')
    plt.text(0.97,0.94,'(h)',fontsize=16,fontweight='bold')

    plt.subplot(339)
    plt.plot(a_list,PowerGrid_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,PowerGrid_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,PowerGrid_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,PowerGrid_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,PowerGrid_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,PowerGrid_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,PowerGrid_MRCNN_tau,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('PowerGrid',fontsize=20,fontweight='bold')
    plt.xlabel(r'$β/β_{th}$',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.97,0.94,'(i)',fontsize=16,fontweight='bold')
    plt.tight_layout()
    plt.legend(bbox_to_anchor=(0.4,-0.15),ncol=7,fontsize=18)
    plt.show()

    # In[4] Experiment 2: Impact of the size of neighborhood networks
    # train models based different L
    L_list = [4,8,16,28,32,40,48,56,64]
    MRCNN_model_list = Utils.compare_L(BA_1000_4,BA_1000_4_label,BA_1000_4_community,L_list)
    Facebook_MRCNN_tau4_list,Facebook_MRCNN_tau4 = Test.compare_tau1(Facebook,4,Facebook_SIR,Facebook_community,MRCNN_model_list[0],p=0.1)
    GrQ_MRCNN_tau4_list,GrQ_MRCNN_tau4 = Test.compare_tau1(GrQ,4,GrQ_SIR,GrQ_community,MRCNN_model_list[0],p=0.1)
    Ham_MRCNN_tau4_list,Ham_MRCNN_tau4 = Test.compare_tau1(Ham,4,Ham_SIR,Ham_community,MRCNN_model_list[0],p=0.1)
    Hep_MRCNN_tau4_list,Hep_MRCNN_tau4 = Test.compare_tau1(Hep,4,Hep_SIR,Hep_community,MRCNN_model_list[0],p=0.1)
    LastFM_MRCNN_tau4_list,LastFM_MRCNN_tau4 = Test.compare_tau1(LastFM,4,LastFM_SIR,LastFM_community,MRCNN_model_list[0],p=0.1)
    Figeys_MRCNN_tau4_list,Figeys_MRCNN_tau4 = Test.compare_tau1(Figeys,4,Figeys_SIR,Figeys_community,MRCNN_model_list[0],p=0.1)
    Vidal_MRCNN_tau4_list,Vidal_MRCNN_tau4 = Test.compare_tau1(Vidal,4,Vidal_SIR,Vidal_community,MRCNN_model_list[0],p=0.1)
    PowerGrid_MRCNN_tau4_list,PowerGrid_MRCNN_tau4 = Test.compare_tau1(PowerGrid,4,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[0],p=0.1)
    Sex_MRCNN_tau4_list,Sex_MRCNN_tau4 = Test.compare_tau1(Sex,4,Sex_SIR,Sex_community,MRCNN_model_list[0],p=0.1)

    Facebook_MRCNN_tau8_list,Facebook_MRCNN_tau8 = Test.compare_tau1(Facebook,8,Facebook_SIR,Facebook_community,MRCNN_model_list[1],p=0.1)
    GrQ_MRCNN_tau8_list,GrQ_MRCNN_tau8 = Test.compare_tau1(GrQ,8,GrQ_SIR,GrQ_community,MRCNN_model_list[1],p=0.1)
    Ham_MRCNN_tau8_list,Ham_MRCNN_tau8 = Test.compare_tau1(Ham,8,Ham_SIR,Ham_community,MRCNN_model_list[1],p=0.1)
    Hep_MRCNN_tau8_list,Hep_MRCNN_tau8 = Test.compare_tau1(Hep,8,Hep_SIR,Hep_community,MRCNN_model_list[1],p=0.1)
    LastFM_MRCNN_tau8_list,LastFM_MRCNN_tau8 = Test.compare_tau1(LastFM,8,LastFM_SIR,LastFM_community,MRCNN_model_list[1],p=0.1)
    Figeys_MRCNN_tau8_list,Figeys_MRCNN_tau8 = Test.compare_tau1(Figeys,8,Figeys_SIR,Figeys_community,MRCNN_model_list[1],p=0.1)
    Vidal_MRCNN_tau8_list,Vidal_MRCNN_tau8 = Test.compare_tau1(Vidal,8,Vidal_SIR,Vidal_community,MRCNN_model_list[1],p=0.1)
    PowerGrid_MRCNN_tau8_list,PowerGrid_MRCNN_tau8 = Test.compare_tau1(PowerGrid,8,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[1],p=0.1)
    Sex_MRCNN_tau8_list,Sex_MRCNN_tau8 = Test.compare_tau1(Sex,8,Sex_SIR,Sex_community,MRCNN_model_list[1],p=0.1)

    Facebook_MRCNN_tau16_list,Facebook_MRCNN_tau16 = Test.compare_tau1(Facebook,16,Facebook_SIR,Facebook_community,MRCNN_model_list[2],p=0.1)
    GrQ_MRCNN_tau16_list,GrQ_MRCNN_tau16 = Test.compare_tau1(GrQ,16,GrQ_SIR,GrQ_community,MRCNN_model_list[2],p=0.1)
    Ham_MRCNN_tau16_list,Ham_MRCNN_tau16 = Test.compare_tau1(Ham,16,Ham_SIR,Ham_community,MRCNN_model_list[2],p=0.1)
    Hep_MRCNN_tau16_list,Hep_MRCNN_tau16 = Test.compare_tau1(Hep,16,Hep_SIR,Hep_community,MRCNN_model_list[2],p=0.1)
    LastFM_MRCNN_tau16_list,LastFM_MRCNN_tau16 = Test.compare_tau1(LastFM,16,LastFM_SIR,LastFM_community,MRCNN_model_list[2],p=0.1)
    Figeys_MRCNN_tau16_list,Figeys_MRCNN_tau16 = Test.compare_tau1(Figeys,16,Figeys_SIR,Figeys_community,MRCNN_model_list[2],p=0.1)
    Vidal_MRCNN_tau16_list,Vidal_MRCNN_tau16 = Test.compare_tau1(Vidal,16,Vidal_SIR,Vidal_community,MRCNN_model_list[2],p=0.1)
    PowerGrid_MRCNN_tau16_list,PowerGrid_MRCNN_tau16 = Test.compare_tau1(PowerGrid,16,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[3],p=0.1)
    Sex_MRCNN_tau16_list,Sex_MRCNN_tau16 = Test.compare_tau1(Sex,16,Sex_SIR,Sex_community,MRCNN_model_list[2],p=0.1)

    Facebook_MRCNN_tau28_list,Facebook_MRCNN_tau28 = Test.compare_tau1(Facebook,28,Facebook_SIR,Facebook_community,MRCNN_model_list[3],p=0.1)
    GrQ_MRCNN_tau28_list,GrQ_MRCNN_tau28 = Test.compare_tau1(GrQ,28,GrQ_SIR,GrQ_community,MRCNN_model_list[3],p=0.1)
    Ham_MRCNN_tau28_list,Ham_MRCNN_tau28 = Test.compare_tau1(Ham,28,Ham_SIR,Ham_community,MRCNN_model_list[3],p=0.1)
    Hep_MRCNN_tau28_list,Hep_MRCNN_tau28 = Test.compare_tau1(Hep,28,Hep_SIR,Hep_community,MRCNN_model_list[3],p=0.1)
    LastFM_MRCNN_tau28_list,LastFM_MRCNN_tau28 = Test.compare_tau1(LastFM,28,LastFM_SIR,LastFM_community,MRCNN_model_list[3],p=0.1)
    Figeys_MRCNN_tau28_list,Figeys_MRCNN_tau28 = Test.compare_tau1(Figeys,28,Figeys_SIR,Figeys_community,MRCNN_model_list[3],p=0.1)
    Vidal_MRCNN_tau28_list,Vidal_MRCNN_tau28 = Test.compare_tau1(Vidal,28,Vidal_SIR,Vidal_community,MRCNN_model_list[3],p=0.1)
    PowerGrid_MRCNN_tau28_list,PowerGrid_MRCNN_tau28 = Test.compare_tau1(PowerGrid,28,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[3],p=0.1)
    Sex_MRCNN_tau28_list,Sex_MRCNN_tau28 = Test.compare_tau1(Sex,28,Sex_SIR,Sex_community,MRCNN_model_list[3],p=0.1)

    Facebook_MRCNN_tau32_list,Facebook_MRCNN_tau32 = Test.compare_tau1(Facebook,32,Facebook_SIR,Facebook_community,MRCNN_model_list[4],p=0.1)
    GrQ_MRCNN_tau32_list,GrQ_MRCNN_tau32 = Test.compare_tau1(GrQ,32,GrQ_SIR,GrQ_community,MRCNN_model_list[4],p=0.1)
    Ham_MRCNN_tau32_list,Ham_MRCNN_tau32 = Test.compare_tau1(Ham,32,Ham_SIR,Ham_community,MRCNN_model_list[4],p=0.1)
    Hep_MRCNN_tau32_list,Hep_MRCNN_tau32 = Test.compare_tau1(Hep,32,Hep_SIR,Hep_community,MRCNN_model_list[4],p=0.1)
    LastFM_MRCNN_tau32_list,LastFM_MRCNN_tau32 = Test.compare_tau1(LastFM,32,LastFM_SIR,LastFM_community,MRCNN_model_list[4],p=0.1)
    Figeys_MRCNN_tau32_list,Figeys_MRCNN_tau32 = Test.compare_tau1(Figeys,32,Figeys_SIR,Figeys_community,MRCNN_model_list[4],p=0.1)
    Vidal_MRCNN_tau32_list,Vidal_MRCNN_tau32 = Test.compare_tau1(Vidal,32,Vidal_SIR,Vidal_community,MRCNN_model_list[4],p=0.1)
    Sex_MRCNN_tau32_list,Sex_MRCNN_tau32 = Test.compare_tau1(Sex,32,Sex_SIR,Sex_community,MRCNN_model_list[4],p=0.1)
    PowerGrid_MRCNN_tau32_list,PowerGrid_MRCNN_tau32 = Test.compare_tau1(PowerGrid,32,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[4],p=0.1)

    Facebook_MRCNN_tau40_list,Facebook_MRCNN_tau40 = Test.compare_tau1(Facebook,40,Facebook_SIR,Facebook_community,MRCNN_model_list[5],p=0.1)
    GrQ_MRCNN_tau40_list,GrQ_MRCNN_tau40 = Test.compare_tau1(GrQ,40,GrQ_SIR,GrQ_community,MRCNN_model_list[5],p=0.1)
    Ham_MRCNN_tau40_list,Ham_MRCNN_tau40 = Test.compare_tau1(Ham,40,Ham_SIR,Ham_community,MRCNN_model_list[5],p=0.1)
    Hep_MRCNN_tau40_list,Hep_MRCNN_tau40 = Test.compare_tau1(Hep,40,Hep_SIR,Hep_community,MRCNN_model_list[5],p=0.1)
    LastFM_MRCNN_tau40_list,LastFM_MRCNN_tau40 = Test.compare_tau1(LastFM,40,LastFM_SIR,LastFM_community,MRCNN_model_list[5],p=0.1)
    Figeys_MRCNN_tau40_list,Figeys_MRCNN_tau40 = Test.compare_tau1(Figeys,40,Figeys_SIR,Figeys_community,MRCNN_model_list[5],p=0.1)
    Vidal_MRCNN_tau40_list,Vidal_MRCNN_tau40 = Test.compare_tau1(Vidal,40,Vidal_SIR,Vidal_community,MRCNN_model_list[5],p=0.1)
    PowerGrid_MRCNN_tau40_list,PowerGrid_MRCNN_tau40 = Test.compare_tau1(PowerGrid,40,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[5],p=0.1)
    Sex_MRCNN_tau40_list,Sex_MRCNN_tau40 = Test.compare_tau1(Sex,40,Sex_SIR,Sex_community,MRCNN_model_list[5],p=0.1)

    Facebook_MRCNN_tau48_list,Facebook_MRCNN_tau48 = Test.compare_tau1(Facebook,48,Facebook_SIR,Facebook_community,MRCNN_model_list[6],p=0.1)
    GrQ_MRCNN_tau48_list,GrQ_MRCNN_tau48 = Test.compare_tau1(GrQ,48,GrQ_SIR,GrQ_community,MRCNN_model_list[6],p=0.1)
    Ham_MRCNN_tau48_list,Ham_MRCNN_tau48 = Test.compare_tau1(Ham,48,Ham_SIR,Ham_community,MRCNN_model_list[6],p=0.1)
    Hep_MRCNN_tau48_list,Hep_MRCNN_tau48 = Test.compare_tau1(Hep,48,Hep_SIR,Hep_community,MRCNN_model_list[6],p=0.1)
    LastFM_MRCNN_tau48_list,LastFM_MRCNN_tau48 = Test.compare_tau1(LastFM,48,LastFM_SIR,LastFM_community,MRCNN_model_list[6],p=0.1)
    Figeys_MRCNN_tau48_list,Figeys_MRCNN_tau48 = Test.compare_tau1(Figeys,48,Figeys_SIR,Figeys_community,MRCNN_model_list[6],p=0.1)
    Vidal_MRCNN_tau48_list,Vidal_MRCNN_tau48 = Test.compare_tau1(Vidal,48,Vidal_SIR,Vidal_community,MRCNN_model_list[6],p=0.1)
    PowerGrid_MRCNN_tau48_list,PowerGrid_MRCNN_tau48 = Test.compare_tau1(PowerGrid,48,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[6],p=0.1)
    Sex_MRCNN_tau48_list,Sex_MRCNN_tau48 = Test.compare_tau1(Sex,48,Sex_SIR,Sex_community,MRCNN_model_list[6],p=0.1)

    Facebook_MRCNN_tau56_list,Facebook_MRCNN_tau56 = Test.compare_tau1(Facebook,56,Facebook_SIR,Facebook_community,MRCNN_model_list[7],p=0.1)
    GrQ_MRCNN_tau56_list,GrQ_MRCNN_tau56 = Test.compare_tau1(GrQ,56,GrQ_SIR,GrQ_community,MRCNN_model_list[7],p=0.1)
    Ham_MRCNN_tau56_list,Ham_MRCNN_tau56 = Test.compare_tau1(Ham,56,Ham_SIR,Ham_community,MRCNN_model_list[7],p=0.1)
    Hep_MRCNN_tau56_list,Hep_MRCNN_tau56 = Test.compare_tau1(Hep,56,Hep_SIR,Hep_community,MRCNN_model_list[7],p=0.1)
    LastFM_MRCNN_tau56_list,LastFM_MRCNN_tau56 = Test.compare_tau1(LastFM,56,LastFM_SIR,LastFM_community,MRCNN_model_list[7],p=0.1)
    Figeys_MRCNN_tau56_list,Figeys_MRCNN_tau56 = Test.compare_tau1(Figeys,56,Figeys_SIR,Figeys_community,MRCNN_model_list[7],p=0.1)
    Vidal_MRCNN_tau56_list,Vidal_MRCNN_tau56 = Test.compare_tau1(Vidal,56,Vidal_SIR,Vidal_community,MRCNN_model_list[7],p=0.1)
    PowerGrid_MRCNN_tau56_list,PowerGrid_MRCNN_tau56 = Test.compare_tau1(PowerGrid,56,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[7],p=0.1)
    Sex_MRCNN_tau56_list,Sex_MRCNN_tau56 = Test.compare_tau1(Sex,56,Sex_SIR,Sex_community,MRCNN_model_list[7],p=0.1)

    Facebook_MRCNN_tau64_list,Facebook_MRCNN_tau64 = Test.compare_tau1(Facebook,64,Facebook_SIR,Facebook_community,MRCNN_model_list[8],p=0.1)
    GrQ_MRCNN_tau64_list,GrQ_MRCNN_tau64 = Test.compare_tau1(GrQ,64,GrQ_SIR,GrQ_community,MRCNN_model_list[8],p=0.1)
    Ham_MRCNN_tau64_list,Ham_MRCNN_tau64 = Test.compare_tau1(Ham,64,Ham_SIR,Ham_community,MRCNN_model_list[8],p=0.1)
    Hep_MRCNN_tau64_list,Hep_MRCNN_tau64 = Test.compare_tau1(Hep,64,Hep_SIR,Hep_community,MRCNN_model_list[8],p=0.1)
    LastFM_MRCNN_tau64_list,LastFM_MRCNN_tau64 = Test.compare_tau1(LastFM,64,LastFM_SIR,LastFM_community,MRCNN_model_list[8],p=0.1)
    Figeys_MRCNN_tau64_list,Figeys_MRCNN_tau64 = Test.compare_tau1(Figeys,64,Figeys_SIR,Figeys_community,MRCNN_model_list[8],p=0.1)
    Vidal_MRCNN_tau64_list,Vidal_MRCNN_tau64 = Test.compare_tau1(Vidal,64,Vidal_SIR,Vidal_community,MRCNN_model_list[8],p=0.1)
    PowerGrid_MRCNN_tau64_list,PowerGrid_MRCNN_tau64 = Test.compare_tau1(PowerGrid,64,PowerGrid_SIR,PowerGrid_community,MRCNN_model_list[8],p=0.1)
    Sex_MRCNN_tau64_list,Sex_MRCNN_tau64 = Test.compare_tau1(Sex,64,Sex_SIR,Sex_community,MRCNN_model_list[8],p=0.1)

    L_all = pd.DataFrame({'L':L_list
                ,'Facebook':[Facebook_MRCNN_tau4,Facebook_MRCNN_tau8,Facebook_MRCNN_tau16,Facebook_MRCNN_tau28,Facebook_MRCNN_tau32,Facebook_MRCNN_tau40,Facebook_MRCNN_tau48,Facebook_MRCNN_tau56,Facebook_MRCNN_tau64]
                ,'GrQ':[GrQ_MRCNN_tau4,GrQ_MRCNN_tau8,GrQ_MRCNN_tau16,GrQ_MRCNN_tau28,GrQ_MRCNN_tau32,GrQ_MRCNN_tau40,GrQ_MRCNN_tau48,GrQ_MRCNN_tau56,GrQ_MRCNN_tau64]
                ,'Ham':[Ham_MRCNN_tau4,Ham_MRCNN_tau8,Ham_MRCNN_tau16,Ham_MRCNN_tau28,Ham_MRCNN_tau32,Ham_MRCNN_tau40,Ham_MRCNN_tau48,Ham_MRCNN_tau56,Ham_MRCNN_tau64]
                ,'Hep':[Hep_MRCNN_tau4,Hep_MRCNN_tau8,Hep_MRCNN_tau16,Hep_MRCNN_tau28,Hep_MRCNN_tau32,Hep_MRCNN_tau40,Hep_MRCNN_tau48,Hep_MRCNN_tau56,Hep_MRCNN_tau64]
                ,'LastFM':[LastFM_MRCNN_tau4,LastFM_MRCNN_tau8,LastFM_MRCNN_tau16,LastFM_MRCNN_tau28,LastFM_MRCNN_tau32,LastFM_MRCNN_tau40,LastFM_MRCNN_tau48,LastFM_MRCNN_tau56,LastFM_MRCNN_tau64]
                ,'Vidal':[Vidal_MRCNN_tau4,Vidal_MRCNN_tau8,Vidal_MRCNN_tau16,Vidal_MRCNN_tau28,Vidal_MRCNN_tau32,Vidal_MRCNN_tau40,Vidal_MRCNN_tau48,Vidal_MRCNN_tau56,Vidal_MRCNN_tau64]
                ,'PowerGrid':[PowerGrid_MRCNN_tau4,PowerGrid_MRCNN_tau8,PowerGrid_MRCNN_tau16,PowerGrid_MRCNN_tau28,PowerGrid_MRCNN_tau32,PowerGrid_MRCNN_tau40,PowerGrid_MRCNN_tau48,PowerGrid_MRCNN_tau56,PowerGrid_MRCNN_tau64]
                ,'Sex':[Sex_MRCNN_tau4,Sex_MRCNN_tau8,Sex_MRCNN_tau16,Sex_MRCNN_tau28,Sex_MRCNN_tau32,Sex_MRCNN_tau40,Sex_MRCNN_tau48,Sex_MRCNN_tau56,Sex_MRCNN_tau64]})

    # visualize results
    plt.figure(figsize=(12,5),dpi=120)

    plt.subplot(121)
    plt.plot(L_all['L'],L_all['Facebook'],marker='o',markersize=8,c='r',label=r'Facebook($G_{C_V}$%=100,$G_{C_E}$%=100)')
    plt.plot(L_all['L'],L_all['LastFM'],marker='s',markersize=8,c='fuchsia',label=r'LastFM($G_{C_V}$%=100,$G_{C_E}$%=100)')
    plt.plot(L_all['L'],L_all['Sex'],marker='<',markersize=8,c='b',label=r'Sex($G_{C_V}$%=100,$G_{C_E}$%=100)')
    plt.plot(L_all['L'],L_all['PowerGrid'],marker='>',markersize=8,c='brown',label=r'PowerGrid($G_{C_V}$%=100,$G_{C_E}$%=100)')
    plt.ylabel(r'$\overline{\tau}$',fontsize=16,fontweight='bold')
    plt.xlabel(r'$L$',fontsize=16,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=12)
    plt.xticks(np.arange(4,68,8),fontsize=12)
    plt.text(3,0.94,'(a)',fontsize=14,fontweight='bold')
    plt.legend(loc='best')

    plt.subplot(122)
    plt.plot(L_all['L'],L_all['Figeys'],marker='>',markersize=8,c='black',label=r'Figeys($G_{C_V}$%=99.01,$G_{C_E}$%=99.78)')
    plt.plot(L_all['L'],L_all['Hep'],marker='o',markersize=8,c='g',label=r'Hep($G_{C_V}$%=87.46,$G_{C_E}$%=95.51)')
    plt.plot(L_all['L'],L_all['Vidal'],marker='s',markersize=8,c='gold',label=r'Vidal($G_{C_V}$%=88.83,$G_{C_E}$%=97.96)')
    plt.plot(L_all['L'],L_all['GrQ'],marker='<',markersize=8,c='tomato',label=r'GrQC($G_{C_V}$%=79.32,$G_{C_E}$%=92.67)')
    plt.plot(L_all['L'],L_all['Ham'],marker='h',markersize=8,c='navy',label=r'Hamster($G_{C_V}$%=82.44,$G_{C_E}$%=96.80)')

    plt.xlabel(r'$L$',fontsize=16,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=12)
    plt.xticks(np.arange(4,68,8),fontsize=12)
    plt.text(3,0.94,'(b)',fontsize=14,fontweight='bold')
    plt.legend(loc='best')
    plt.tight_layout()
    plt.show()

    # Performance of M-RCNN when L=4
    plt.figure(figsize=(12,5.5),dpi=120)
    plt.plot(a_list,GrQ_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,GrQ_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,GrQ_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,GrQ_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,GrQ_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,GrQC_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,GrQ_MRCNN_tau4_list,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('GrQC',fontsize=20,fontweight='bold')
    plt.ylabel(r'$\tau$',fontsize=24,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.xlabel(r'$β/β_{th}$',fontsize=20,fontweight='bold')
    plt.text(0.97,0.94,'(g)',fontsize=16,fontweight='bold')

    plt.subplot(339)
    plt.plot(a_list,PowerGrid_RCNN_tau,marker='o',markersize=10,c='b',label='RCNN')
    plt.plot(a_list,PowerGrid_dc_tau,marker='<',markersize=10,c='fuchsia',label='DC')
    plt.plot(a_list,PowerGrid_ks_tau,marker='>',markersize=10,c='g',label='K-core')
    plt.plot(a_list,PowerGrid_nd_tau,marker='p',markersize=10,c='black',label='ND')
    plt.plot(a_list,PowerGrid_bc_tau,marker='h',markersize=10,c='y',label='BC')
    plt.plot(a_list,PowerGrid_vc_tau,marker='H',markersize=10,c='orange',label='Vc')
    plt.plot(a_list,PowerGrid_tau4_list,marker='s',markersize=10,c='r',label='M-RCNN')
    plt.title('PowerGrid',fontsize=20,fontweight='bold')
    plt.xlabel(r'$β/β_{th}$',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,1.1,0.2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.97,0.94,'(i)',fontsize=16,fontweight='bold')
    plt.tight_layout()
    plt.legend(bbox_to_anchor=(0.4,-0.15),ncol=7,fontsize=18)
    plt.show()

    # In[5] Experiment 3: Two-channel M-RCNN
    Facebook_improve_com = Test.calculate_improve(Facebook,L1,L2,Facebook_SIR,Facebook_community,RCNN,MRCNN_com,method='community')
    Facebook_improve_shell = Test.calculate_improve(Facebook,L1,L2,Facebook_SIR,Facebook_community,RCNN,MRCNN_com,method='shell')

    LastFM_improve_com = Test.calculate_improve(LastFM,L1,L2,LastFM_SIR,LastFM_community,RCNN,MRCNN_com,method='community')
    LastFM_improve_shell = Test.calculate_improve(LastFM,L1,L2,LastFM_SIR,LastFM_community,RCNN,MRCNN_com,method='shell')

    Sex_improve_com = Test.calculate_improve(Sex,L1,L2,Sex_SIR,Sex_community,RCNN,MRCNN_com,method='community')
    Sex_improve_shell = Test.calculate_improve(Sex,L1,L2,Sex_SIR,Sex_community,RCNN,MRCNN_com,method='shell')

    Hep_improve_com = Test.calculate_improve(Hep,L1,L2,Hep_SIR,Hep_community,RCNN,MRCNN_com,method='community')
    Hep_improve_shell = Test.calculate_improve(Hep,L1,L2,Hep_SIR,Hep_community,RCNN,MRCNN_com,method='shell')

    Ham_improve_com = Test.calculate_improve(Ham,L1,L2,Ham_SIR,Ham_community,RCNN,MRCNN_com,method='community')
    Ham_improve_shell = Test.calculate_improve(Ham,L1,L2,Ham_SIR,Ham_community,RCNN,MRCNN_com,method='shell')

    Vidal_improve_com = Test.calculate_improve(Vidal,L1,L2,Vidal_SIR,Vidal_community,RCNN,MRCNN_com,method='community')
    Vidal_improve_shell = Test.calculate_improve(Vidal,L1,L2,Vidal_SIR,Vidal_community,RCNN,MRCNN_com,method='shell')

    PowerGrid_improve_com = Test.calculate_improve(PowerGrid,L1,L2,PowerGrid_SIR,PowerGrid_community,RCNN,MRCNN_com,method='community')
    PowerGrid_improve_shell = Test.calculate_improve(PowerGrid,L1,L2,PowerGrid_SIR,PowerGrid_community,RCNN,MRCNN_com,method='shell')

    GrQ_improve_com = Test.calculate_improve(GrQ,L1,L2,GrQ_SIR,GrQ_community,RCNN,MRCNN_com,method='community')
    GrQ_improve_shell = Test.calculate_improve(GrQ,L1,L2,GrQ_SIR,GrQ_community,RCNN,MRCNN_com,method='shell')

    Figeys_improve_com = Test.calculate_improve(Figeys,L1,L2,Figeys_SIR,Figeys_community,RCNN,MRCNN_com,method='community')
    Figeys_improve_shell = Test.calculate_improve(Figeys,L1,L2,Figeys_SIR,Figeys_community,RCNN,MRCNN_com,method='shell')

    # visualize results:

    plt.subplot(331)
    plt.plot(a_list,Facebook_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,Facebook_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.yticks(np.arange(0,12,2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.title('Facebook',fontsize=20,fontweight='bold')
    plt.ylabel(r'$Improvement$ $ratio(\tau) \%$',fontsize=20,fontweight='bold')
    plt.text(0.98,9.2,'(a)',fontsize=16,fontweight='bold')

    plt.subplot(332)
    plt.plot(a_list,LastFM_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,LastFM_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.title('LastFM',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,10,2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.98,7.4,'(b)',fontsize=16,fontweight='bold')

    plt.subplot(333)
    plt.plot(a_list,Sex_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,Sex_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.title('Sex',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,10,2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.98,7.4,'(c)',fontsize=16,fontweight='bold')

    plt.subplot(334)
    plt.plot(a_list,Figeys_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,Figeys_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.ylabel(r'$Improvement$ $ratio(\tau) \% $',fontsize=20,fontweight='bold')
    plt.title('Figeys',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,25,5),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.98,20.5,'(d)',fontsize=16,fontweight='bold')

    plt.subplot(335)
    plt.plot(a_list,Hep_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,Hep_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.title('Hep',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(0,10,2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.98,7.4,'(e)',fontsize=16,fontweight='bold')

    plt.subplot(336)
    plt.plot(a_list,Vidal_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,Vidal_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.title('Vidal',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(-2,10,2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.98,7.25,'(f)',fontsize=16,fontweight='bold')

    plt.subplot(337)
    plt.plot(a_list,GrQ_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,GrQ_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.title('GrQC',fontsize=20,fontweight='bold')
    plt.ylabel(r'$Improvement$ $ratio(\tau)\%$',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(-10,10,2),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.xlabel(r'$β/β_{th}$',fontsize=24,fontweight='bold')
    plt.text(0.98,6.6,'(g)',fontsize=16,fontweight='bold')

    plt.subplot(338)
    plt.plot(a_list,Ham_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,Ham_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.title('Hamster',fontsize=20,fontweight='bold')
    plt.yticks(np.arange(-1,2.5,1),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.xlabel(r'$β/β_{th}$',fontsize=24,fontweight='bold')
    plt.text(0.98,1.9,'(h)',fontsize=16,fontweight='bold')

    plt.subplot(339)
    plt.plot(a_list,PowerGrid_improve_com,marker='v',markersize=10,c='darkgreen',label='M-RCNN(ND+N_Com)')
    plt.plot(a_list,PowerGrid_improve_shell,marker='^',markersize=10,c='darkred',label='M-RCNN(ND+K-Shell)')
    plt.title('PowerGrid',fontsize=20,fontweight='bold')
    plt.xlabel(r'$β/β_{th}$',fontsize=24,fontweight='bold')
    plt.yticks(np.arange(0,80,10),fontsize=18)
    plt.xticks(np.arange(1,2,0.3),fontsize=18)
    plt.text(0.98,68,'(i)',fontsize=16,fontweight='bold')
    plt.tight_layout()
    plt.legend(bbox_to_anchor=(0.04,-0.2),ncol=2,fontsize=18)
    plt.show()

    # In[6] Experiment 4: Node ranking similarity and discrimination ability
    Facebook_sim = Test.calculate_similarity(Facebook,L1,L2,Facebook_SIR[4],Facebook_community,RCNN,MRCNN)
    LastFM_sim = Test.calculate_similarity(LastFM,L1,L2,LastFM_SIR[4],LastFM_community,RCNN,MRCNN)
    Sex_sim = Test.calculate_similarity(Sex,L1,L2,Sex_SIR[4],Sex_community,RCNN,MRCNN)
    Figeys_sim = Test.calculate_similarity(Figeys,L1,L2,Figeys_SIR[4],Figeys_community,RCNN,MRCNN)
    Hep_sim = Test.calculate_similarity(Hep,L1,L2,Hep_SIR[4],Hep_community,RCNN,MRCNN)
    Vidal_sim = Test.calculate_similarity(Vidal,L1,L2,Vidal_SIR[4],Vidal_community,RCNN,MRCNN)
    GrQ_sim = Test.calculate_similarity(GrQc,L1,L2,GrQ_SIR[4],GrQ_community,RCNN,MRCNN_model_list[0])
    Ham_sim = Test.calculate_similarity(Hamster,L1,L2,Ham_SIR[4],Ham_community,RCNN,MRCNN)
    PowerGrid_sim = Test.calculate_similarity(PowerGrid,L1,L2,PowerGrid_SIR[4],PowerGrid_community,RCNN,MRCNN_model_list[0])

    # normalize
    Facebook_sim = Utils.normalization(Facebook_sim)
    LastFM_sim = Utils.normalization(LastFM_sim)
    Ham_sim = Utils.normalization(Ham_sim)
    Sex_sim = Utils.normalization(Sex_sim)
    Hep_sim = Utils.normalization(Hep_sim)
    Vidal_sim = Utils.normalization(Vidal_sim)
    PowerGrid_sim = Utils.normalization(PowerGrid_sim)
    GrQ_sim = Utils.normalization(GrQ_sim)
    Figeys_sim = Utils.normalization(Figeys_sim)

    # visualize results
    plt.figure(figsize=(20,16),dpi=120)
    plt.subplot(331)
    S1 = plt.scatter(Facebook_sim['MRCNN'],Facebook_sim['RCNN'],c=Facebook_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('Facebook',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.ylabel('RCNN',fontsize=20,fontweight='bold')
    plt.text(-0.1,1.05,'(a)',fontsize=20,fontweight='bold')
    plt.colorbar(S1)

    plt.subplot(332)
    S2 = plt.scatter(LastFM_sim['MRCNN'],LastFM_sim['RCNN'],c=LastFM_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('LastFM',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(b)',fontsize=20,fontweight='bold')
    plt.colorbar(S2)

    plt.subplot(333)
    S3 = plt.scatter(Sex_sim['MRCNN'],Sex_sim['RCNN'],c=Sex_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('Sex',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(c)',fontsize=20,fontweight='bold')
    plt.colorbar(S3)

    plt.subplot(334)
    S4 = plt.scatter(Figeys_sim['MRCNN'],Figeys_sim['RCNN'],c=Figeys_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('Figeys',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(d)',fontsize=20,fontweight='bold')
    plt.ylabel('RCNN',fontsize=20,fontweight='bold')
    plt.colorbar(S4)

    plt.subplot(335)
    S5 = plt.scatter(Hep_sim['MRCNN'],Hep_sim['RCNN'],c=Hep_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('Hep',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(e)',fontsize=20,fontweight='bold')
    plt.colorbar(S5)

    plt.subplot(336)
    S6 = plt.scatter(Vidal_sim['MRCNN'],Vidal_sim['RCNN'],c=Vidal_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('Hep',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(f)',fontsize=20,fontweight='bold')
    plt.colorbar(S6)

    plt.subplot(337)
    S7 = plt.scatter(GrQ_sim['MRCNN'],GrQ_sim['RCNN'],c=GrQ_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('GrQC',fontsize=20,fontweight='bold')
    plt.xlabel('M-RCNN',fontsize=20,fontweight='bold')
    plt.ylabel('RCNN',fontsize=20,fontweight='bold')
    plt.colorbar(S7)
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(g)',fontsize=20,fontweight='bold')

    plt.subplot(338)
    S8 = plt.scatter(Ham_sim['MRCNN'],Ham_sim['RCNN'],c=Ham_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('Hamster',fontsize=20,fontweight='bold')
    plt.xlabel('M-RCNN',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(h)',fontsize=20,fontweight='bold')
    plt.colorbar(S8)

    plt.subplot(339)
    S9 = plt.scatter(PowerGrid_sim['MRCNN'],PowerGrid_sim['RCNN'],c=PowerGrid_sim['SIR'],cmap='jet')
    plt.plot(np.arange(-0.1,1.1,0.1),np.arange(-0.1,1.1,0.1),color='black',linewidth=5,linestyle='--')
    plt.title('PowerGrid',fontsize=20,fontweight='bold')
    plt.xlabel('M-RCNN',fontsize=20,fontweight='bold')
    plt.xticks(fontsize=18)
    plt.yticks(fontsize=18)
    plt.text(-0.1,1.05,'(i)',fontsize=20,fontweight='bold')
    plt.colorbar(S9)
    plt.tight_layout()
    plt.show()

    # In[7] Experiment 5:
    L_list = [8,16,24,32,40,48,56,64]
    # time needed to construct input
    RCNN_time_1000_4= Test.cal_input_time(BA_1000_4,BA_1000_4_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_1000_10 = Test.cal_input_time(BA_1000_10,BA_1000_10_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_1000_20 = Test.cal_input_time(BA_1000_20,BA_1000_20_label,L_list,batch_size,num_epochs,lr)

    RCNN_time_2000_4 = Test.cal_input_time(BA_2000_4,BA_2000_4_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_2000_10 = Test.cal_input_time(BA_2000_10,BA_2000_10_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_2000_20 = Test.cal_input_time(BA_2000_20,BA_2000_20_label,L_list,batch_size,num_epochs,lr)

    RCNN_time_3000_4 = Test.cal_input_time(BA_3000_4,BA_3000_4_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_3000_10 = Test.cal_input_time(BA_3000_10,BA_3000_10_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_3000_20 = Test.cal_input_time(BA_3000_20,BA_3000_20_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_pd = pd.DataFrame({'RCNN_1000_4':RCNN_time_1000_4,'RCNN_1000_10':RCNN_time_1000_10,'RCNN_1000_20':RCNN_time_1000_20,'RCNN_2000_4':RCNN_time_2000_4,'RCNN_2000_10':RCNN_time_2000_10,'RCNN_2000_20':RCNN_time_2000_20,'RCNN_3000_4':RCNN_time_3000_4,'RCNN_3000_10':RCNN_time_3000_10,'RCNN_3000_20':RCNN_time_3000_20})

    MRCNN_time_1000_4 = Test.cal_input_time2(BA_1000_4,BA_1000_4_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_1000_10 = Test.cal_input_time2(BA_1000_10,BA_1000_10_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_1000_20 = Test.cal_input_time2(BA_1000_20,BA_1000_20_label,L_list,batch_size,num_epochs,lr)

    MRCNN_time_2000_4 = Test.cal_input_time2(BA_2000_4,BA_2000_4_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_2000_10 = Test.cal_input_time2(BA_2000_10,BA_2000_10_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_2000_20= Test.cal_input_time2(BA_2000_20,BA_2000_20_label,L_list,batch_size,num_epochs,lr)

    MRCNN_time_3000_4 = Test.cal_input_time2(BA_3000_4,BA_3000_4_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_3000_10= Test.cal_input_time2(BA_3000_10,BA_3000_10_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_3000_20 = Test.cal_input_time2(BA_3000_20,BA_3000_20_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_pd = pd.DataFrame({'MRCNN_1000_4':MRCNN_time_1000_4,'MRCNN_1000_10':MRCNN_time_1000_10,'MRCNN_1000_20':MRCNN_time_1000_20,'MRCNN_2000_4':MRCNN_time_2000_4,'MRCNN_2000_10':MRCNN_time_2000_10,'MRCNN_2000_20':MRCNN_time_2000_20,'MRCNN_3000_4':MRCNN_time_3000_4,'MRCNN_3000_10':MRCNN_time_3000_10,'MRCNN_3000_20':MRCNN_time_3000_20})

    # time needed to construct input and training
    RCNN_train_time_1000_4= Test.cal_training_time(BA_1000_4,BA_1000_4_label,L_list,batch_size,num_epochs,lr)
    RCNN_train_time_1000_10 = Test.cal_training_time(BA_1000_10,BA_1000_10_label,L_list,batch_size,num_epochs,lr)
    RCNN_train_time_1000_20 = Test.cal_training_time(BA_1000_20,BA_1000_20_label,L_list,batch_size,num_epochs,lr)

    RCNN_train_time_2000_4 = Test.cal_training_time(BA_2000_4,BA_2000_4_label,L_list,batch_size,num_epochs,lr)
    RCNN_train_time_2000_10 = Test.cal_training_time(BA_2000_10,BA_2000_10_label,L_list,batch_size,num_epochs,lr)
    RCNN_train_time_2000_20 = Test.cal_training_time(BA_2000_20,BA_2000_20_label,L_list,batch_size,num_epochs,lr)

    RCNN_train_time_3000_4 = Test.cal_training_time(BA_3000_4,BA_3000_4_label,L_list,batch_size,num_epochs,lr)
    RCNN_train_time_3000_10 = Test.cal_training_time(BA_3000_10,BA_3000_10_label,L_list,batch_size,num_epochs,lr)
    RCNN_train_time_3000_20 = Test.cal_training_time(BA_3000_20,BA_3000_20_label,L_list,batch_size,num_epochs,lr)
    RCNN_time_train_pd = pd.DataFrame({'RCNN_1000_4':RCNN_train_time_1000_4,'RCNN_1000_10':RCNN_train_time_1000_10,'RCNN_1000_20':RCNN_train_time_1000_20,'RCNN_2000_4':RCNN_train_time_2000_4,'RCNN_2000_10':RCNN_train_time_2000_10,'RCNN_2000_20':RCNN_train_time_2000_20,'RCNN_3000_4':RCNN_train_time_3000_4,'RCNN_3000_10':RCNN_train_time_3000_10,'RCNN_3000_20':RCNN_train_time_3000_20})

    MRCNN_train_time_1000_4 = Test.cal_training_time2(BA_1000_4,BA_1000_4_label,L_list,batch_size,num_epochs,lr)
    MRCNN_train_time_1000_10 = Test.cal_training_time2(BA_1000_10,BA_1000_10_label,L_list,batch_size,num_epochs,lr)
    MRCNN_train_time_1000_20 = Test.cal_training_time2(BA_1000_20,BA_1000_20_label,L_list,batch_size,num_epochs,lr)

    MRCNN_train_time_2000_4 = Test.cal_training_time2(BA_2000_4,BA_2000_4_label,L_list,batch_size,num_epochs,lr)
    MRCNN_train_time_2000_10 = Test.cal_training_time2(BA_2000_10,BA_2000_10_label,L_list,batch_size,num_epochs,lr)
    MRCNN_train_time_2000_20= Test.cal_training_time2(BA_2000_20,BA_2000_20_label,L_list,batch_size,num_epochs,lr)

    MRCNN_train_time_3000_4 = Test.cal_training_time2(BA_3000_4,BA_3000_4_label,L_list,batch_size,num_epochs,lr)
    MRCNN_train_time_3000_10= Test.cal_training_time2(BA_3000_10,BA_3000_10_label,L_list,batch_size,num_epochs,lr)
    MRCNN_train_time_3000_20 = Test.cal_training_time2(BA_3000_20,BA_3000_20_label,L_list,batch_size,num_epochs,lr)
    MRCNN_time_train_pd = pd.DataFrame({'MRCNN_1000_4':MRCNN_train_time_1000_4,'MRCNN_1000_10':MRCNN_train_time_1000_10,'MRCNN_1000_20':MRCNN_train_time_1000_20,'MRCNN_2000_4':MRCNN_train_time_2000_4,'MRCNN_2000_10':MRCNN_train_time_2000_10,'MRCNN_2000_20':MRCNN_train_time_2000_20,'MRCNN_3000_4':MRCNN_train_time_3000_4,'MRCNN_3000_10':MRCNN_train_time_3000_10,'MRCNN_3000_20':MRCNN_train_time_3000_20})
    # visualize results
    l_list = np.array([1,2,3,4,5,6,7,8,9])
    L_list = l_list-0.2
    # time needed (input)
    plt.figure(figsize=(20,16),dpi=200)
    plt.subplot(331)
    plt.bar(L_list,RCNN_time_pd['RCNN_1000_4'],color='r',width=0.4,label='RCNN(BA_1000_4)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_1000_4'],color='b',width=0.4,label='MRCNN(BA_1000_4)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.ylabel('Time(s)',fontsize=24,fontweight='bold')
    plt.text(5.5,3,'(a)', fontsize=24)
    plt.legend(loc='best',fontsize=16)
    #plt.legend(loc=0,fontsize=16)

    plt.subplot(332)
    plt.bar(L_list,RCNN_time_pd['RCNN_1000_10'],color='r',width=0.4,label='RCNN(BA_1000_10)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_1000_10'],color='b',width=0.4,label='MRCNN(BA_1000_10)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,4.5,'(b)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(333)
    plt.bar(L_list,RCNN_time_pd['RCNN_1000_20'],color='r',width=0.4,label='RCNN(BA_1000_20)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_1000_20'],color='b',width=0.4,label='MRCNN(BA_1000_20)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,6.95,'(c)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(334)
    plt.bar(L_list,RCNN_time_pd['RCNN_2000_4'],color='r',width=0.4,label='RCNN(BA_2000_4)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_2000_4'],color='b',width=0.4,label='MRCNN(BA_2000_4)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.ylabel('Time(s)',fontsize=24,fontweight='bold')
    plt.text(5.5,8.5,'(d)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(335)
    plt.bar(L_list,RCNN_time_pd['RCNN_2000_10'],color='r',width=0.4,label='RCNN(BA_2000_10)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_2000_10'],color='b',width=0.4,label='MRCNN(BA_2000_10)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,10.05,'(e)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(336)
    plt.bar(L_list,RCNN_time_pd['RCNN_2000_20'],color='r',width=0.4,label='RCNN(BA_2000_20)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_2000_20'],color='b',width=0.4,label='MRCNN(BA_2000_20)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,17.05,'(f)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(337)
    plt.bar(L_list,RCNN_time_pd['RCNN_3000_4'],color='r',width=0.4,label='RCNN(BA_3000_4)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_3000_4'],color='b',width=0.4,label='MRCNN(BA_3000_4)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.xlabel(r'$L$',fontsize=24,fontweight='bold')
    plt.ylabel('Time(s)',fontsize=24,fontweight='bold')
    plt.text(5.5,10.35,'(g)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(338)
    plt.bar(L_list,RCNN_time_pd['RCNN_3000_10'],color='r',width=0.4,label='RCNN(BA_3000_10)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_3000_10'],color='b',width=0.4,label='MRCNN(BA_3000_10)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.xlabel(r'$L$',fontsize=24,fontweight='bold')
    plt.text(5.7,14.9,'(h)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(339)
    plt.bar(L_list,RCNN_time_pd['RCNN_3000_20'],color='r',width=0.4,label='RCNN(BA_3000_20)')
    plt.bar(L_list,MRCNN_time_pd['MRCNN_3000_20'],color='b',width=0.4,label='MRCNN(BA_3000_20)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.xlabel(r'$L$',fontsize=24,fontweight='bold')
    plt.text(5.7,29.0,'(i)', fontsize=24)
    plt.legend(loc='best',fontsize=16)
    plt.tight_layout()
    plt.show()

    # time needed (input+training)
    plt.figure(figsize=(20,16),dpi=200)
    plt.subplot(331)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_1000_4'],color='r',width=0.4,label='RCNN(BA_1000_4)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_1000_4'],color='b',width=0.4,label='MRCNN(BA_1000_4)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.ylabel('Time(s)',fontsize=24,fontweight='bold')
    plt.text(5.5,3,'(a)', fontsize=24)
    plt.legend(loc='best',fontsize=16)
    #plt.legend(loc=0,fontsize=16)

    plt.subplot(332)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_1000_10'],color='r',width=0.4,label='RCNN(BA_1000_10)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_1000_10'],color='b',width=0.4,label='MRCNN(BA_1000_10)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,4.5,'(b)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(333)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_1000_20'],color='r',width=0.4,label='RCNN(BA_1000_20)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_1000_20'],color='b',width=0.4,label='MRCNN(BA_1000_20)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,6.95,'(c)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(334)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_2000_4'],color='r',width=0.4,label='RCNN(BA_2000_4)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_2000_4'],color='b',width=0.4,label='MRCNN(BA_2000_4)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.ylabel('Time(s)',fontsize=24,fontweight='bold')
    plt.text(5.5,8.5,'(d)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(335)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_2000_10'],color='r',width=0.4,label='RCNN(BA_2000_10)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_2000_10'],color='b',width=0.4,label='MRCNN(BA_2000_10)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,10.05,'(e)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(336)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_2000_20'],color='r',width=0.4,label='RCNN(BA_2000_20)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_2000_20'],color='b',width=0.4,label='MRCNN(BA_2000_20)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.text(5.7,17.05,'(f)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(337)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_3000_4'],color='r',width=0.4,label='RCNN(BA_3000_4)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_3000_4'],color='b',width=0.4,label='MRCNN(BA_3000_4)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.xlabel(r'$L$',fontsize=24,fontweight='bold')
    plt.ylabel('Time(s)',fontsize=24,fontweight='bold')
    plt.text(5.5,10.35,'(g)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(338)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_3000_10'],color='r',width=0.4,label='RCNN(BA_3000_10)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_3000_10'],color='b',width=0.4,label='MRCNN(BA_3000_10)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.xlabel(r'$L$',fontsize=24,fontweight='bold')
    plt.text(5.7,14.9,'(h)', fontsize=24)
    plt.legend(loc='best',fontsize=16)

    plt.subplot(339)
    plt.bar(L_list,RCNN_time_train_pd['RCNN_3000_20'],color='r',width=0.4,label='RCNN(BA_3000_20)')
    plt.bar(L_list,MRCNN_time_train_pd['MRCNN_3000_20'],color='b',width=0.4,label='MRCNN(BA_3000_20)')
    plt.xticks(l_list,[str(i) for i in L_list],fontsize=20)
    plt.yticks(fontsize=20)
    plt.xlabel(r'$L$',fontsize=24,fontweight='bold')
    plt.text(5.7,29.0,'(i)', fontsize=24)
    plt.legend(loc='best',fontsize=16)
    plt.tight_layout()
    plt.show()


# pylint: disable=C0103, too-few-public-methods, locally-disabled, no-self-use, unused-argument
'''Copies files with defined tags to
a specified subfolder where the image has valid regions
'''
import argparse
import os.path as path
from shutil import copyfile

import opencvlib.imgpipes.vgg as vgg
import opencvlib.imgpipes.digikamlib as dkl
from funclib.iolib import get_file_parts2
from funclib.iolib import create_folder
from funclib.iolib import print_progress
from funclib.baselib import DictList

def main():
    '''
    Copies files matching the tags kwargs to
    the subfolder where the image has no regions set.

    The -r flag will only copy images without any ROIs defined in the VGG JSON file.

    Example:
    subjectless.py -t OR "C:/Users/Graham Monkman/OneDrive/Documents/PHD/images/bass/angler/bass-angler.json" "C:/Users/Graham Monkman/OneDrive/Documents/PHD/images/digikam4.db" is_train=head is_train=whole
    '''

    cmdline = argparse.ArgumentParser(description='Copies image files to a specified subfolder which have'
                                      ' the specified tags in digikam\n\n'
                                      'Only images in the root of the VGG file folder are checked.\n\n'
                                      'Example:\n'
                                      'subjectless.py -t OR "C:/Users/Graham Monkman/OneDrive/Documents/PHD/images/bass/angler/bass-angler.json" "C:/Users/Graham Monkman/OneDrive/Documents/PHD/images/digikam4.db" is_train=head is_train=whole'
                                      )

    cmdline.add_argument(
        '-f', '--subfolder', help='The subfolder to copy the files to. If optional uses the tags to create the folder.', default='')
    cmdline.add_argument(
        '-r', '--regionless', help='The default. Only image files without any regions are copied.', default='True')
    cmdline.add_argument(
        '-t', '--bool_type', help='Use AND or OR or ANDOR for key-value WHERE. Default:AND', default='ANDOR')
    cmdline.add_argument('vggfile', help='VGG JSON file to manipulate')
    cmdline.add_argument('digikamfile', help='Digikam file (sqlitedb) to use')
    cmdline.add_argument(
        'key_values', help='Provide tag key value pairs, e.g. species=bass MV=is_train', nargs='+')
    args = cmdline.parse_args()

    vgg.SILENT = True

    vggfile = path.normpath(args.vggfile)
    if not path.isfile(vggfile):
        print('\n%s is not a file.' % vggfile)
        return

    try:
        vgg.load_json(vggfile)
    except Exception as e:
        s = ('Failed to initialise VGG JSON file %s.\n\n' /
             'The error was %s\n\n' /
             'Check it is a valid JSON file.' % (vggfile, str(e)))
        print(s)
        return

    print("Loaded JSON VGG file %s...." % vggfile)

    digikamfile = path.normpath(args.digikamfile)
    if not path.isfile(digikamfile):
        print('\n%s is not a digikam file.' % digikamfile)
        return

    try:
        digi = dkl.ImagePaths(digikamfile)
    except Exception as e:
        s = ('Failed to initialise the digikam database %s.\n\n' /
             'The error was %s\n\n' /
             'Check it is not in use and is a valid sqlite database.' % (digikamfile, str(e)))
        print(s)
        return

    if not args.key_values:
        print('No key-value pairs specified.')
        return

    # Build kw args
    # allow multiple values in our key value pairs, eg is_train=head
    # is_train=whole will be {'is_train':['head','whole']}
    kwords = DictList()
    for kv in args.key_values:
        kv = str(kv)
        a, b = kv.split(sep='=')
        kwords[a] = b

    # return list of all matching images, irrespective of path
    if not args.bool_type in ['AND', 'OR', 'ANDOR']:
        print('Unknown argument %s for -t (the boolean search type). Defaulting to AND' %
              args.bool_type)

    if args.bool_type == 'AND':
        images = digi.images_by_tags_and(**kwords)
    elif args.bool_type == 'OR':
        images = digi.images_by_tags_or(**kwords)
    elif args.bool_type == 'ANDOR':
        images = digi.images_by_tags_outerAnd_innerOr(**kwords)

    print('%s images matched digikam tag criteria' % len(images))
    # create the new folder
    if args.subfolder == '':
        subfolder = " ".join(args.key_values)
    else:
        subfolder = args.subfolder

    new_fld = path.normpath(get_file_parts2(vggfile)[0] + '/' + subfolder)
    create_folder(new_fld)
    print("\nCreated folder %s" % new_fld)

    vgg_folder = get_file_parts2(vggfile)[0]
    cnt = 1
    copy_cnt = 0
    for img in images:
        imgfld = get_file_parts2(img)[0]
        if vgg_folder == imgfld:
            do_copy = True

            if args.regionless:
                vgg_image = vgg.Image(img)
                do_copy = bool(vgg_image.shape_count == 0)

            if do_copy:
                dest = path.join(new_fld, get_file_parts2(img)[1])
                copyfile(img, dest)
                copy_cnt += 1

            s = '%s of %s' % (cnt, len(images))
            print_progress(cnt, len(images), s, bar_length=30)
            cnt += 1

    print('Done. Copied %s files to %s' % (copy_cnt, new_fld))

if __name__ == "__main__":
    main()
    #sys.exit(int(main() or 0))


# Django imports
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.mail import send_mail
from django.db import IntegrityError
from django.db import models
from django.urls import reverse
from django.utils.crypto import get_random_string
from django.utils.crypto import hashlib

# App imports
from realestate.apps.core.models import BaseModel
from realestate.apps.core.models import Couple
from realestate.apps.core.models import Homebuyer

# Function to generate a registration token
def _generate_registration_token():
    while True:
        token = hashlib.sha256(get_random_string(length=64).encode()).hexdigest()
        if not PendingHomebuyer.objects.filter(registration_token=token):
            return token

# PendingCouple model
class PendingCouple(BaseModel):
    # Create a foreign key to the Realtor model
    realtor = models.ForeignKey(
        "core.Realtor", verbose_name="Realtor", on_delete=models.CASCADE
    )

    # String representation
    def __str__(self):
        pending_homebuyers = self.pendinghomebuyer_set.all()

        if pending_homebuyers:
            return ", ".join(map(str, pending_homebuyers))
        return "No homebuyers specified"

    # Method to get the couple
    @property
    def couple(self):
        # Get the emails of the pending homebuyers
        emails = self.pendinghomebuyer_set.values_list("email", flat=True)

        # Get the homebuyers and couples
        homebuyers = Homebuyer.objects.filter(user__email__in=emails)
        couples = Couple.objects.filter(homebuyer__in=homebuyers)

        # If the couple exists, return it
        if couples.exists():
            return couples.first()

        # Otherwise, return None
        return None

    # Method to check if the couple is registered
    @property
    def registered(self):
        # Get the pending homebuyers
        pending_homebuyers = self.pendinghomebuyer_set.all()

        # Check if the homebuyers are registered
        return pending_homebuyers.count() == 2 and all(
            map(lambda hb: hb.registered, pending_homebuyers)
        )

    # Meta class
    class Meta:
        # Set field to be used for ordering
        ordering = ["realtor"]

        # Set the verbose names
        verbose_name = "Pending Couple"
        verbose_name_plural = "Pending Couples"

# PendingHomebuyer model
class PendingHomebuyer(BaseModel):
    # Set a constant for the email invite message
    _HOMEBUYER_INVITE_MESSAGE = """
        Hello {name},

        You have been invited to the Real Estate app.
        Register at the following link:
            {signup_link}
    """

    # Add the fields to the model
    email = models.EmailField(
        unique=True,
        verbose_name="Email Address",
        error_messages={"unique": ("A user with this email already exists.")},
    )
    first_name = models.CharField(max_length=30, verbose_name="First Name")
    last_name = models.CharField(max_length=30, verbose_name="Last Name")
    registration_token = models.CharField(
        max_length=64,
        default=_generate_registration_token,
        editable=False,
        unique=True,
        verbose_name="Registration Token",
    )

    # Create a foreign key to the PendingCouple model
    pending_couple = models.ForeignKey(
        "pending.PendingCouple", verbose_name="Pending Couple", on_delete=models.CASCADE
    )

    # String representation
    def __str__(self):
        return f"{self.email} ({self.registration_status})"

    # Method to get the signup link
    def _signup_link(self, host):
        url = reverse(
            "homebuyer-signup", kwargs={"registration_token": self.registration_token}
        )
        return host + url

    # Method to clean the model
    def clean(self):
        # Get the pending homebuyers
        pending_homebuyers = set(
            self.pending_couple.pendinghomebuyer_set.values_list(
                "id", flat=True
            ).distinct()
        )

        # Add the current pending homebuyer
        pending_homebuyers.add(self.id)

        # If the couple pending homebuyers is greater than 2
        if len(pending_homebuyers) > 2:
            # Raise the validation error
            raise ValidationError("PendingCouple already has 2 Homebuyers.")

        # Call the parent clean method
        return super(PendingHomebuyer, self).clean()

    # Method to get the couple
    @property
    def couple(self):
        return self.pending_couple.couple

    # Method to get the partner
    @property
    def partner(self):
        # Get the pending homebuyers
        pending_homebuyers = self.pending_couple.pendinghomebuyer_set.exclude(
            id=self.id
        )

        # If the pending homebuyers is greater than 1
        if pending_homebuyers.count() > 1:
            # Raise the integrity error
            raise IntegrityError(
                f"PendingCouple has too many related PendingHomebuyer and should be resolved immediately. (PendingCouple ID: {self.pending_couple.id})"
            )

        # Else return the first member of the pending homebuyers
        return pending_homebuyers.first()

    # Method to check if the homebuyer is registered
    @property
    def registered(self):
        if Homebuyer.objects.filter(user__email=self.email).exists():
            return True

    # Method to get the registration status
    @property
    def registration_status(self):
        return "Registered" if self.registered else "Unregistered"

    # Method to send the email invite
    def send_email_invite(self, request):
        # If the homebuyer is registered, return None
        if self.registered:
            return None

        # Get the message text
        message = self._HOMEBUYER_INVITE_MESSAGE.format(
            name=self.first_name, signup_link=self._signup_link(request.get_host())
        )

        # Send the email
        return send_mail(
            "Real Estate Invite",
            message,
            settings.EMAIL_HOST_USER,
            [self.email],
            fail_silently=False,
        )

    # Meta class
    class Meta:
        # Set the fields to be used for ordering
        ordering = ["email"]

        # Set the verbose names
        verbose_name = "Pending Homebuyer"
        verbose_name_plural = "Pending Homebuyers"


#install pycirclize
import matplotlib.pyplot as plt
from pycirclize import Circos
from pycirclize.parser import Gff

# Load GFF file
gff_file = ("enterobacteria.gff")
gff = Gff(gff_file)

circos = Circos(sectors={gff.name: gff.range_size})
circos.text("Enterobacteria phage\n(NC_000902)", size=15)

sector = circos.sectors[0]
cds_track = sector.add_track((90, 100))
cds_track.axis(fc="#EEEEEE", ec="none")
# Plot forward CDS
cds_track.genomic_features(
    gff.extract_features("CDS", target_strand=1),
    plotstyle="arrow",
    r_lim=(95, 100),
    fc="salmon",
)
# Plot reverse CDS
cds_track.genomic_features(
    gff.extract_features("CDS", target_strand=-1),
    plotstyle="arrow",
    r_lim=(90, 95),
    fc="skyblue",
)
# Extract CDS product labels
pos_list, labels = [], []
for f in gff.extract_features("CDS"):
    start, end = int(str(f.location.end)), int(str(f.location.start))
    pos = (start + end) / 2
    label = f.qualifiers.get("product", [""])[0]
    if label == "" or label.startswith("hypothetical"):
        continue
    if len(label) > 20:
        label = label[:20] + "..."
    pos_list.append(pos)
    labels.append(label)
# Plot CDS product labels on outer position
cds_track.xticks(
    pos_list,
    labels,
    label_orientation="vertical",
    show_bottom_line=True,
    label_size=6,
    line_kws=dict(ec="grey"),
)
# Plot xticks & intervals on inner position
cds_track.xticks_by_interval(
    interval=5000,
    outer=False,
    show_bottom_line=True,
    label_formatter=lambda v: f"{v/ 1000:.1f} Kb",
    label_orientation="vertical",
    line_kws=dict(ec="grey"),
)

fig = circos.plotfig()

plt.show()


import sys;
import pygame;
from time import sleep;

from bullet import Bullet;
from alien import Alien;

def check_keydown_events(event,ai_setting,screen,ship,bullets):
	"""响应按键"""
	if event.key == pygame.K_RIGHT:
	#向右移动飞船
		ship.moving_right = True;
	elif event.key == pygame.K_LEFT:
		#向左移动飞船
		ship.moving_left = True;
	elif event.key == pygame.K_SPACE:
		#发射子弹
		fire_bullet(ai_setting,screen,ship,bullets);
	elif event.key == pygame.K_q:
		sys.exit();

def check_keyup_events(event,ship):
	"""响应松开按键"""
	if event.key == pygame.K_RIGHT:
		#停止向右移动飞船
		ship.moving_right = False;
	elif event.key == pygame.K_LEFT:
		#停止向左移动飞船
		ship.moving_left = False;

def check_events(ai_setting,screen,status,sb,play_button,ship,aliens,bullets):
	#监视键盘和鼠标事件
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			sys.exit();
		elif event.type == pygame.KEYDOWN:
			check_keydown_events(event,ai_setting,screen,ship,bullets);
		elif event.type == pygame.KEYUP:
			check_keyup_events(event,ship);
		elif event.type == pygame.MOUSEBUTTONDOWN:
			mouse_x,mouse_y = pygame.mouse.get_pos();
			check_play_button(ai_setting,screen,status,sb,ship,aliens,bullets,play_button,mouse_x,mouse_y);

def check_play_button(ai_setting,screen,status,sb,ship,aliens,bullets,play_button,mouse_x,mouse_y):
	"""在玩家点击play按钮后游戏开始"""
	button_click = play_button.rect.collidepoint(mouse_x,mouse_y);
	if button_click and not status.game_active:
		#重置游戏设置
		ai_setting.initialize_dynamic_settings();

		#隐藏光标
		pygame.mouse.set_visible(False);

		#重置游戏统计信息
		status.rest_status();
		status.game_active = True;

		#清空外星人列表和子弹列表
		aliens.empty();
		bullets.empty();

		#重置记分牌图像
		sb.prep_score();
		sb.prep_high_score();
		sb.prep_level();
		sb.prep_ship();

		#创建一群新的外星人，并把飞船放到屏幕底端中央
		create_fleet(ai_setting,screen,ship,aliens);
		ship.center_ship();

def update_screen(ai_setting,screen,status,sb,ship,aliens,bullets,play_button):
	"""更新屏幕上的图像，并切换到新屏幕"""
	#每次循环都重绘屏幕
	screen.fill(ai_setting.bg_color);

	#在飞船和外星人后面绘制所有子弹
	for bullet in bullets.sprites():
		bullet.draw_bullet();

	#绘制飞船
	ship.blitme();

	#绘制外星人
	#alien.blitme();
	aliens.draw(screen);

	#显示得分
	sb.show_score();

	#如果游戏没有运行，则绘制Play按钮
	if not status.game_active:
		play_button.draw_button();

	#让屏幕可见
	pygame.display.flip();

def update_bullets(ai_setting,screen,status,sb,ship,aliens,bullets):
	"""更新子弹位置并删除消失的子弹"""
	bullets.update();

	#删除已经消失的子弹
	for bullet in bullets.copy():
		if bullet.rect.bottom <= 0:
			bullets.remove(bullet);
	check_bullet_alien_collision(ai_setting,screen,status,sb,ship,aliens,bullets);

def check_bullet_alien_collision(ai_setting,screen,status,sb,ship,aliens,bullets):
	#检查是否有子弹击中了外星人，如果有则删除相应的子弹和外星人
	collisions = pygame.sprite.groupcollide(aliens,bullets,True,True);
	print(len(bullets));
	print("外星人的数量：" + str(len(aliens)));
	if collisions:
		#针对一颗子弹射中多个外星人
		for alienss in collisions.values():
			status.score += ai_setting.alien_points * len(alienss);
			sb.prep_score();
		check_high_score(status,sb);

	if len(aliens) == 0 :
		#删除现有的子弹，并新建外星人
		bullets.empty();
		ai_setting.increase_speed();
		create_fleet(ai_setting,screen,ship,aliens);
		#提高等级
		status.level += 1;
		sb.prep_level();

def fire_bullet(ai_setting,screen,ship,bullets):
	"""如果没有到达限制则发射子弹"""
	#判断屏幕上的子弹是否小于指定的数量
	if len(bullets) < ai_setting.bullet_allowed :
		#创建一颗子弹将其加入到bullets中
		new_bullet = Bullet(ai_setting,screen,ship);
		bullets.add(new_bullet);

def get_number_aliens_x(ai_setting,alien_width):
	'''计算一行可以容纳多少个外星人'''
	available_space_x = ai_setting.screen_width - 2*alien_width;
	numbers_alien_x = int(available_space_x/(2*alien_width));
	return numbers_alien_x;

def get_number_rows(ai_setting,ship_height,alien_height):
	'''计算屏幕可以容纳多少行外星人'''
	availiable_space_y = ai_setting.screen_height - (3*alien_height) - ship_height;
	number_rows = int(availiable_space_y/(2*alien_height));
	return number_rows;

def create_alien(ai_setting,screen,ship,aliens,alien_number,row_number):
	'''建一个外星人并把其加入当前行'''
	alien = Alien(ai_setting,screen);
	alien_width = alien.rect.width;
	alien.x = alien_width + 2*alien_width * alien_number;
	alien.rect.x = alien.x;
	alien.rect.y = ship.rect.height + 5 + alien.rect.height + 2*alien.rect.height*row_number;
	aliens.add(alien);

def create_fleet(ai_setting,screen,ship,aliens):
	"""创建外星人群"""
	#创建一个外星人，并计算一行可以容纳多少个外星人
	#外星人间距为外星人宽度
	alien = Alien(ai_setting,screen);
	numbers_alien_x = get_number_aliens_x(ai_setting,alien.rect.width);

	number_rows = get_number_rows(ai_setting,ship.rect.height,alien.rect.height);

	for number_row in range(number_rows):
		#创建第一行外星人
		for alien_number in range(numbers_alien_x + 1):
			#创建一个外星人并把其加入当前行
			create_alien(ai_setting,screen,ship,aliens,alien_number,number_row);

def update_aliens(ai_setting,status,sb,screen,ship,aliens,bullets):
	'''更新外星人人群中所有外星人的位置'''
	check_fleet_edges(ai_setting,aliens);
	aliens.update();

	#检查外星人和飞船之间的碰撞
	if pygame.sprite.spritecollideany(ship,aliens):
		ship_hit(ai_setting,status,sb,screen,ship,aliens,bullets);

	#检查是否有外星人到底底部
	check_aliens_bottom(ai_setting,status,sb,screen,ship,aliens,bullets);

def check_fleet_edges(ai_setting,aliens):
	'''有外星人到达边缘时采取相应措施'''
	for alien in aliens.sprites():
		if alien.check_edges():
			change_fleet_direction(ai_setting,aliens);
			break;

def change_fleet_direction(ai_setting,aliens):
	'''将整个外星人人群下移并改变方向'''
	for alien in aliens.sprites():
		alien.rect.y += ai_setting.fleet_drop_speed;
	ai_setting.fleet_direction *= -1;

def ship_hit(ai_setting,status,sb,screen,ship,aliens,bullets):
	"""响应被外星人撞到飞船"""
	if status.ship_left > 0:
		#将ship_left减1
		status.ship_left -= 1;

		#更新记分牌
		sb.prep_score();
		sb.prep_ship();

		#清空外星人列表和子弹列表
		aliens.empty();
		bullets.empty();

		#创建一群新的外星人，并把飞船放到屏幕底端中央
		create_fleet(ai_setting,screen,ship,aliens);
		ship.center_ship();

		#暂停
		sleep(0.5);
	else:
		status.game_active = False;
		#让光标可见
		pygame.mouse.set_visible(True);

def check_aliens_bottom(ai_setting,status,sb,screen,ship,aliens,bullets):
	"""检查是否有外星人到达屏幕底端"""
	screen_rect = screen.get_rect();
	for alien in aliens.sprites():
		if alien.rect.bottom >= screen_rect.bottom:
			#外星人撞到屏幕底部，飞船也销毁
			ship_hit(ai_setting,status,sb,screen,ship,aliens,bullets);
			break;

def check_high_score(status,sb):
	"""检查是否产生了新的最高分"""
	if status.score > status.high_score:
		status.high_score = status.score;
		sb.prep_high_score();


# coding: utf8

import sys
import collections
import itertools
import operator

def new_pos_at_direction(pos, direction):
    return tuple(itertools.starmap(operator.add, zip(pos, direction)))

def dist_to_center(center, pos):
    # assuming the playground is nested squares (than arbitrary rectangles)
    return max(abs(center[x] - pos[x]) for x in range(2))

def main():
    grids = {
        (i, j): grid
        for i, row in enumerate(sys.stdin.read().splitlines())
        for j, grid in enumerate(row)
    }
    directions = (
        (-1, 0),
        (0, -1),
        (0, 1),
        (1, 0),
    )
    labels = {}
    for pos, grid in grids.items():
        if grid != '.':
            continue
        for direction in directions:
            new_pos = new_pos_at_direction(pos, direction)
            if 'A' <= grids[new_pos] <= 'Z':
                label = [grids[x] for x in (new_pos, new_pos_at_direction(new_pos, direction))]
                if direction in ((-1, 0), (0, -1)):
                    label = label[::-1]
                labels.setdefault(''.join(label), []).append(pos)
                break
    center = tuple(max(pos[x] for pos in grids) // 2 for x in range(2))
    portals = {}
    for label, pos in labels.items():
        if label in ('AA', 'ZZ'):
            continue
        if dist_to_center(center, pos[0]) > dist_to_center(center, pos[1]):
            # ensure pos[0] is the inner one
            pos = pos[::-1]
        portals[pos[0]] = (pos[1], 1)
        portals[pos[1]] = (pos[0], -1)
    min_dist = collections.defaultdict(lambda: float('inf'))
    pending = collections.deque([(labels['AA'][0], 0)])
    min_dist[pending[0]] = 0
    target_found = False
    while pending and not target_found:
        pos, level = pending.popleft()
        check_positions = [
            (new_pos_at_direction(pos, direction), level)
            for direction in directions
        ]
        if pos in portals:
            new_level = level + portals[pos][1]
            if new_level >= 0:
                check_positions.append((portals[pos][0], new_level))
        for new_pos_level in check_positions:
            if grids[new_pos_level[0]] == '.':
                dist = min_dist[(pos, level)] + 1
                if dist < min_dist[new_pos_level]:
                    min_dist[new_pos_level] = dist
                    pending.append(new_pos_level)
                    if new_pos_level == (labels['ZZ'][0], 0):
                        target_found = True
    print(min_dist[(labels['ZZ'][0], 0)])

if __name__ == '__main__':
    main()


"""

Haven't Done...

"""

import os
import sys
sys.path.insert(0, os.getcwd())

import torch
from torchvision import transforms, datasets

from comvex.vit import ViT
from comvex.transunet import TransUNet

EPOCH = 10
BATCH_SIZE = 32
LR_RATE = 1e-4

if __name__ == "__main__":

    vit = ViT(
        image_size=28,
        image_channel=1,
        patch_size=4,
        num_classes=6,
        dim=64,
        num_heads=8,
        num_layers=12,
    )

    train_dataset = datasets.MNIST(
        'datasets',
        train=True,
        download=True,
        transform=transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.1307,), (0.3081,)),
        ])
    )

    test_dataset = datasets.MNIST(
        'datasets',
        train=False,
        download=True,
        transform=transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.1307,), (0.3081,))
        ])
    )

    train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
    test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)

    for epoch in range(EPOCH):
        for batch_id, (data, y) in enumerate(train_loader):
            print(data.shape)
            print(y.shape)

            assert False


import cv2
import numpy as np
from model import model_b as de
cap = cv2.VideoCapture(0)
cond=True
while cond:
    success, img = cap.read()
    de.detection(img)
    cv2.imshow('Image', img)
    k=cv2.waitKey(33)
    if k==27:
        cond=False


from keras.models import Sequential
from keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Reshape, Flatten

def build_model(is_train):
    inputshape = (1200,)
    imgshape   = (20, 20, 3)
    kernel     = (3, 3)
    pooling    = (2, 2)

    model = Sequential()
    # our input vector is flat, but Conv2D wants a 3d
    # shaped tensor (width, height, depth), reshape it.
    model.add( Reshape(imgshape, input_shape=inputshape) )
    # add some convolutional filters
    model.add( Conv2D(32, kernel_size=kernel, activation='relu') )
    model.add( Conv2D(64, kernel, activation='relu') )
    # downsample from the convolutional filters
    model.add( MaxPooling2D(pool_size=pooling) )
    # add some dropout to avoid overfitting
    model.add( Dropout(0.25) )
    # flatten results for the next dense layer
    model.add( Flatten() )
    # this layer is gonna learn how to classify planes
    # according to the inputs that the convolutional
    # and dropout layers activate.
    model.add( Dense(128, activation='relu') )
    # avoid overfitting
    model.add( Dropout(0.5) )
    # the output layer
    model.add( Dense(2, activation='softmax') )

    return model


"""Members can be updated

Revision ID: 28174fb4a2c6
Revises: 102ddd686fcf
Create Date: 2017-10-11 13:35:25.574287

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '28174fb4a2c6'
down_revision = '102ddd686fcf'
branch_labels = None
depends_on = None

def upgrade():
    with op.batch_alter_table('member', schema=None) as batch_op:
        mrc = batch_op.add_column(sa.Column('most_recent', sa.Boolean(), nullable=False, default = 1))

        batch_op.drop_constraint('uq_member_address', type_='unique')
        batch_op.drop_constraint('uq_member_name', type_='unique')

    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('member', schema=None) as batch_op:
        batch_op.create_unique_constraint('uq_member_name', ['name'])
        batch_op.create_unique_constraint('uq_member_address', ['address'])
        batch_op.drop_column('most_recent')

    # ### end Alembic commands ###


import os
from celery import Celery

# Set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'goodreads.settings')

# Create a new Celery application instance.
app = Celery('goodreads')

# Load the celery configuration from the Django settings.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Discover and register task modules from all registered Django apps.
app.autodiscover_tasks()

# Define a debug task.
@app.task(bind=True)
def debug_task(self):
    print(f'Request: {self.request!r}')


import pandas as pd

from statistical_transformations.utils import get_common_reaches
from statistical_transformations.fdc_utils import convert_parameter_based_to_discrete

import matplotlib.pyplot as plt
import xarray as xr
import numpy as np

import argparse
import os

def plot_all_reaches(input_ds: xr.Dataset, characteristics_df: pd.DataFrame,
                            distribution: str, output_dir: str = "."):
    """
    Plottign utility that will plot both the original discretized FDC and the values out of the parameter-based
    FDC

    Parameters
    ----------
    input_ds: xr.Dataset
        Input dataset, which should contian the variables Obs_FDC and Obs_FDC_<distribution>
    characteristics_df: pd.DataFrame
        Dataframe indexed by reach id and containing at least upstream (ie., upstream area)
    distribution: str
        A valid distribution. The parameter-based FDC were calculated for lognorm and genextreme
    output_dir: str
        Where to put all the plots.

    Returns
    -------
    None

    """
    common_reaches = get_common_reaches(input_ds)
    station_rchid = input_ds.station_rchid.values

    exceedance_values = input_ds.percentile.values

    for reach in common_reaches:
        idx_station_rchid = np.where(station_rchid == reach)[0][0]

        obs_fdc = input_ds.Obs_FDC[idx_station_rchid, :].values
        parameters_fdc = input_ds.variables["Obs_FDC_{}".format(distribution)][idx_station_rchid, :].values
        parameter_obs_fdc = convert_parameter_based_to_discrete(distribution, parameters_fdc, exceedance_values)
        upstream_area = characteristics_df.loc[reach, "uparea"]
        # Rescale to m3/s
        parameter_obs_fdc = upstream_area * 10. ** parameter_obs_fdc
        print(parameter_obs_fdc, obs_fdc)
        plt.figure(figsize=(12, 9))
        ax = plt.subplot(111)
        ax.spines["top"].set_visible(False)
        ax.spines["right"].set_visible(False)

        plt.semilogy(exceedance_values, obs_fdc, label="Discrete FDC")
        plt.semilogy(exceedance_values, parameter_obs_fdc, label="Discretized FDC from parameter-based distribution")
        plt.legend()
        plt.title("Reach: {}".format(reach))

        plt.savefig("{}/comparison_discrete_parameter_FDC_{}.png".format(output_dir, reach))
        plt.close()

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("input_fdc_nc")
    parser.add_argument("properties_csv")
    parser.add_argument("distribution", choices=["lognorm", "genextreme"])
    parser.add_argument("-output_dir", help="Directory that will contain the results", default=".")
    return parser.parse_args()

def main():
    args = parse_args()
    input_fdc_nc = args.input_fdc_nc
    properties_csv = args.properties_csv
    output_dir = args.output_dir
    distribution = args.distribution

    if not os.path.isdir(output_dir):
        os.mkdir(output_dir)

    fdc_ds = xr.open_dataset(input_fdc_nc)
    characteristics_df = pd.read_csv(properties_csv, index_col="rchid")

    plot_all_reaches(fdc_ds, characteristics_df, distribution, output_dir=output_dir)

if __name__ == "__main__":
    main()


# Import libraries
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split

# Load the dataset
df = pd.read_csv("exams.csv")

# Encode the categorical features
le1 = LabelEncoder()
le2 = LabelEncoder()
le3 = LabelEncoder()
le4 = LabelEncoder()
le5 = LabelEncoder()

df["gender"] = le1.fit_transform(df["gender"])
df["race/ethnicity"] = le2.fit_transform(df["race/ethnicity"])
df["parental level of education"] = le3.fit_transform(df["parental level of education"])
df["lunch"] = le4.fit_transform(df["lunch"])
df["test preparation course"] = le5.fit_transform(df["test preparation course"])

# Split the dataset into features and targets
X = df.drop(["math score", "reading score", "writing score"], axis=1).values
y = df[["math score", "reading score", "writing score"]].values

# Split the dataset into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Convert the data to tensors
X_train = torch.from_numpy(X_train).float()
X_test = torch.from_numpy(X_test).float()
y_train = torch.from_numpy(y_train).float()
y_test = torch.from_numpy(y_test).float()

# Define the ANN model
class ANN(nn.Module):
  def __init__(self):
    super(ANN, self).__init__()
    # Define the layers and activation functions
    self.fc1 = nn.Linear(5, 20) # Input layer with 5 features and output layer with 10 neurons
    self.relu1 = nn.ReLU() # ReLU activation function for the first hidden layer
    self.fc2 = nn.Linear(20, 20) # Second hidden layer with 10 neurons and output layer with 10 neurons
    self.relu2 = nn.ReLU() # ReLU activation function for the second hidden layer
    self.fc3 = nn.Linear(20, 3) # Output layer with 10 neurons and output layer with 3 neurons (one for each score)

  def forward(self, x):
    # Define the forward pass
    out = self.fc1(x) # Pass the input through the first layer
    out = self.relu1(out) # Apply the ReLU activation function
    out = self.fc2(out) # Pass the output of the first layer through the second layer
    out = self.relu2(out) # Apply the ReLU activation function
    out = self.fc3(out) # Pass the output of the second layer through the output layer
    return out
'''
# Create an instance of the model
model = ANN()
# Define the loss function and optimizer
criterion = nn.MSELoss() # Mean squared error loss function for regression
optimizer = optim.Adam(model.parameters(), lr=0.01) # Adam optimizer with learning rate of 0.01

# Define the number of epochs for training
epochs = 100

# Train the model
for epoch in range(epochs):
  # Zero the parameter gradients
  optimizer.zero_grad()
  # Forward pass
  outputs = model(X_train)
  # Calculate the loss
  loss = criterion(outputs, y_train)
  # Backward pass and optimize
  loss.backward()
  optimizer.step()
  # Print the loss every 10 epochs
  if (epoch+1) % 10 == 0:
    print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")

# Test the model on unseen data
with torch.no_grad():
  predictions = model(X_test)
  test_loss = criterion(predictions, y_test)
  print(f"Test Loss: {test_loss.item():.4f}")

torch.save(model, 'model.pth')
torch.save(le1, 'encoder1.pkl')
torch.save(le2, 'encoder2.pkl')
torch.save(le3, 'encoder3.pkl')
torch.save(le4, 'encoder4.pkl')
torch.save(le5, 'encoder5.pkl')'''


import requests

# Пример запроса на запуск получения изображений
number = 5
response = requests.post('http://localhost:5000/start/{}'.format(number), headers={'Authorization': 'admin'})
if response.status_code == 200:
    image_data = response.json()
    # Обработка полученных данных
    print(image_data)
else:
    print('Ошибка при запросе:', response.text)

# Пример запроса на получение текущей конфигурации
response = requests.get('http://localhost:5000/get_config', headers={'Authorization': 'admin'})
if response.status_code == 200:
    config_data = response.json()
    # Обработка полученных данных
    print(config_data)
else:
    print('Ошибка при запросе:', response.text)

# Пример запроса на изменение конфигурации
new_config = {
    'train_fit_bool': True,
    'val_fit_bool': False,
    'n_epochs': 10,
    'output_images_bool': True
}
response = requests.post('http://localhost:5000/set_config', json=new_config, headers={'Authorization': 'admin'})
if response.status_code == 200:
    print('Конфигурация успешно изменена')
else:
    print('Ошибка при запросе:', response.text)

# Пример запроса на получение начальной фразы
response = requests.get('http://localhost:5000/set_initial_phrase', headers={'Authorization': 'admin'})
if response.status_code == 200:
    initial_phrase = response.json()['initial_phrase']
    # Обработка полученной фразы
    print(initial_phrase)
else:
    print('Ошибка при запросе:', response.text)