{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Author: Elisabetta Ghisu\n",
    "\n",
    "\"\"\"\n",
    "- Script containing functions for computing the shortest path kernel\n",
    "- The Floyd Warshall algorithm is first implemented\n",
    "- Then the SP is calculated\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "#######################\n",
    "# - IMPORT PACKAGES - #\n",
    "#######################\n",
    "\n",
    "\n",
    "\n",
    "import numpy.matlib as matlib\n",
    "import numpy as np\n",
    "\n",
    "\"\"\"\n",
    "### FLOYD WARSHALL ALGORITHM\n",
    "Input:\n",
    "- Adjancency matrix A\n",
    "Output:\n",
    "- Shortest path matrix S\n",
    "\"\"\"\n",
    "\n",
    "def floyd_warshall(A):\n",
    "\n",
    "\t# nuber of nodes\n",
    "\tn = A.shape[0]\n",
    "\n",
    "\t# initialize shortes path matrix\n",
    "\tS = np.zeros(shape = (n,n))\n",
    "\n",
    "\tfor i in range(n):\n",
    "\t\tfor j in range(n):\n",
    "\t\t\tif A[i,j] == 0 and i!=j:\n",
    "\t\t\t\tS[i,j] = float(\"inf\")\n",
    "\t\t\telse:\n",
    "\t\t\t\tS[i,j] = A[i,j]\n",
    "\n",
    "\t# Compute the shortest path matrix\n",
    "\tfor k in range(n):\n",
    "\t\tfor i in range(n):\n",
    "\t\t\tfor j in range(n):\n",
    "\t\t\t\tif S[i,j] > S[i,k] + S[k,j]:\n",
    "\t\t\t\t\tS[i,j] = S[i,k] + S[k,j]\n",
    "\n",
    "\treturn S\t\t\t\t\t\t\t\t\n",
    "\n",
    "\n",
    "\n",
    "\"\"\"\n",
    "SHORTEST PATH KERNEL: This is a fast implementation of the shortest path\n",
    "kernel algorithm\n",
    "Inputs\n",
    "- Adjancency matrix\n",
    "- List of list of node labels for each graph\n",
    "- Total number of node labels \n",
    "Outputs\n",
    "- Kernel matrix\n",
    "- Feature matrix\n",
    "\"\"\"\n",
    "\n",
    "def sp_kernel_fast(adj_mat, labels, L):\n",
    "\n",
    "\t# Number of graphs\n",
    "\tn = len(adj_mat)\n",
    "\tL = int(L)\n",
    "\tS = []\n",
    "\n",
    "\t# shortest path matrices\n",
    "\tfor i in xrange(n):\n",
    "\t\tif i%1000 == 0 and i !=0:\n",
    " \t\t\tprint('haha') #( \"%d\" % i)\n",
    "\t\tS.append(floyd_warshall(adj_mat[i]))\n",
    "\t\n",
    "\t# maximum length of shortest paths in the dataset\n",
    "\tmax_path = 0\n",
    "\n",
    "\t# for each graph in dataset\n",
    "\tfor i in xrange(n):\n",
    "\n",
    "\t\tS_cur = np.copy(S[i])\n",
    "\t\tS_cur[S_cur == np.inf] = 0\n",
    "\t\tnew_max = np.max(S_cur)\n",
    "\t\t\n",
    "\t\tif new_max > max_path:\n",
    "\t\t\tmax_path = new_max # get max short path in all Ss\n",
    "\n",
    "\t# maximum length of shortest paths\n",
    "\tmax_path = int(max_path)\n",
    "\n",
    "\t# initialize feature matrix\n",
    "\tsp = np.zeros(((max_path + 1) * L * (L+1) /2,n))\n",
    "\n",
    "\t# compute feature map for shortest path\n",
    "\tfor i in xrange(n):\n",
    "\n",
    "\t\tif i % 1000 == 0:\n",
    "\t\t\tprint('haha') #\"Processed %d graphs\" %i\n",
    "\n",
    "\t\tS_graph = S[i]\n",
    "\t\tlabels_graph = np.asarray(labels[i].reshape((len(labels[i]),1)))\n",
    "\t\tlabels_graph = labels_graph + 1\n",
    "\t\t\n",
    "\t\tlabels_aux = matlib.repmat(labels_graph, 1, len(labels_graph))\n",
    "\t\t\n",
    "\t\tmin_lab = np.minimum(labels_aux, labels_aux.T)\n",
    "\t\t\n",
    "\t\tmax_lab = np.maximum(labels_aux, labels_aux.T)\n",
    "\t\tsub_path = np.triu(~(np.isinf(S_graph))).T\n",
    "\n",
    "\t\tmin_lab = min_lab[sub_path]\n",
    "\t\tmax_lab = max_lab[sub_path]\n",
    "\n",
    "\n",
    "\t\tind = S_graph[sub_path] * L * (L + 1) / 2 + (min_lab - 1) * (2*L + 2 - min_lab) / 2 + max_lab - min_lab\n",
    "\t\tind = ind.astype(int)\n",
    "\t\taccum = np.zeros((max_path + 1) * L * (L + 1) /2)\n",
    "\t\taccum[:ind.max() + 1] += np.bincount(ind.astype(int))\n",
    "\t\tsp[ind,i] = accum[ind]\n",
    "\t\n",
    "\tsum_cols = np.sum(sp, axis = 1)\n",
    "\tind_true = sum_cols != 0\n",
    "\tsp = sp[ind_true,:]\n",
    "\t\n",
    "\t# compute kernel matrix\n",
    "\tK = np.dot(sp.T,sp)\n",
    "    \n",
    "\treturn K, sp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'igraph'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-3-86bbbfdc06dd>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     15\u001b[0m \u001b[0;31m# iGraph imports to handle graphs and for graph I/O\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0migraph\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mGraph\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     17\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'igraph'"
     ]
    }
   ],
   "source": [
    "#Authors: Elisabetta Ghisu, Felipe Llinares Lopez\n",
    "\n",
    "\"\"\"\n",
    "- This script includes a list of functions for analyzing \n",
    "parsing and formatting graphs\n",
    "- The graphs are given in graphml format\n",
    "- It also contains functions for loading, processing the graphs\n",
    "and extract graph statistics\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "import numpy as np\n",
    "from numpy import genfromtxt\n",
    "\n",
    "# iGraph imports to handle graphs and for graph I/O\n",
    "from igraph import Graph\n",
    "\n",
    "\n",
    "# ---------------------------------GRAPHML I/O FUNCTIONS------------------------------------ #\n",
    "\n",
    "# INPUT:\n",
    "# filenames_graphs: list of GraphML files, where each file contains one graph in the dataset\n",
    "# filename_labels: text file with labels corresponding to each graph in the dataset, in the same order as they are in\n",
    "#                  filename_graphs\n",
    "# OUTPUT:\n",
    "# G: A list containing one iGraph object for each graph in the dataset\n",
    "# Y: A Numpy array containing the labels corresponding to each graph, in the same order as G\n",
    "def load_graphml(filenames_graphs, filename_labels):\n",
    "    G = []\n",
    "    for fname in filenames_graphs:\n",
    "        G.append(Graph.Read_GraphML(fname))\n",
    "    Y = genfromtxt(filename_labels)\n",
    "    return (G, Y)\n",
    "\n",
    "\n",
    "# Loads a list of paths to GraphML files from filename_list\n",
    "def load_file_list(filename_flist):\n",
    "    f = open(filename_flist, 'r')\n",
    "    f_graphs = []\n",
    "    for line in f:\n",
    "        f_graphs.append(line.strip())\n",
    "    f.close()\n",
    "    return f_graphs\n",
    "\n",
    "\n",
    "# --------------------------------COMPUTE STATISTICS---------------------------------------- #\n",
    "\n",
    "\n",
    "# Retrieve labels of all vertices belonging to any graph in the list of iGraph objects G and\n",
    "# returns the entire list, and a list with the alphabet of the vertex labels\n",
    "def get_all_vertex_labels(G, att_name='label'):\n",
    "    v_l = []\n",
    "    for g in G:\n",
    "        v_l += g.vs[att_name]\n",
    "    return (v_l, np.unique(v_l))\n",
    "\n",
    "\n",
    "# Retrieve labels of all edges belonging to any graph in the list of iGraph objects G and\n",
    "# returns the entire list, and a list with the alphabet of the edge labels\n",
    "def get_all_edge_labels(G, att_name='label'):\n",
    "    e_l = []\n",
    "    for g in G:\n",
    "        e_l += g.es[att_name]\n",
    "    return (e_l, np.unique(e_l))\n",
    "\n",
    "\n",
    "# Returns a list where each element is itself the adjacency list of the corresponding graph\n",
    "# The adjacency lit of a graph has the following format:\n",
    "# it is a list where each element is a list containing the id of adjacent nodes\n",
    "def get_adj_list(G):\n",
    "    ad_l = []\n",
    "    for g in G:\n",
    "        ad_l.append(g.get_adjlist())\n",
    "    return ad_l\n",
    "\n",
    "# Returns a list where each element is the adjacency matrix of the graph \n",
    "# The adjancency matrix is in iGraph format\n",
    "def get_adj_mat(G):\n",
    "    ad_m = []\n",
    "    for g in G:\n",
    "        ad_m.append(g.get_adjacency())\n",
    "    return ad_m\n",
    "\n",
    "# Returns a list where each element contains the nodes label for a graph\n",
    "def get_node_labels(G, att_name = 'label'):\n",
    "    node_l = []\n",
    "    for g in G:\n",
    "        node_l.append(g.vs[att_name])\n",
    "    return node_l\n",
    "\n",
    "\n",
    "\n",
    "# ----------------- LOAD AND PROCESS THE GRAPHS --------------- #\n",
    "\n",
    "\n",
    "\"\"\"\n",
    "Inputs:\n",
    "- list of graphs file\n",
    "- labels file\n",
    "- path to the data folder\n",
    "Outputs:\n",
    "- List of node labels\n",
    "- List of adjancency lists\n",
    "- List of graphs in graphml format\n",
    "- Targets\n",
    "- number of classes\n",
    "- sample size\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "def load_and_process(filenames_graphs, filename_labels, path_to_dataset):\n",
    "\n",
    "    # load a list of names to graphml files\n",
    "    f_graphs = load_file_list(filenames_graphs)\n",
    "    # sample size\n",
    "    n = len(f_graphs)\n",
    "\n",
    "    # create a list of paths to the files\n",
    "    f_graphs_path =[]\n",
    "\n",
    "    # for each graph in dataset\n",
    "    for i in range(n):\n",
    "\n",
    "        # index the graph\n",
    "        graph_name = f_graphs[i]\n",
    "\n",
    "        # path to the data folder\n",
    "        path = \"%s/%s\" % (path_to_dataset, graph_name)\n",
    "        f_graphs_path.append(path)\n",
    "\n",
    "    # If the data is DD have to delete an element (corrupted file)\n",
    "    if graph_name == \"DD\":\n",
    "        del f_graphs_path[148]\n",
    "        n = n-1\n",
    "\n",
    "    # Load the graphs in graphml format\n",
    "    # G is a llist of graphml graph\n",
    "    # Y is an array of targets\n",
    "    G,Y = load_graphml(f_graphs_path, filename_labels)\n",
    "\n",
    "    # Delete corrupted file in DD\n",
    "    if graph_name == \"DD\": \n",
    "        Y = np.delete(Y, 148)\n",
    "\n",
    "    # get adjacency list and matrix for all the graphs in G\n",
    "    ad_list = get_adj_list(G)\n",
    "    ad_mat = get_adj_mat(G)\n",
    "\n",
    "    # get a list containing lists of node labels\n",
    "    node_label = get_node_labels(G)\n",
    "\n",
    "    return node_label, ad_list, G, Y\n",
    "\n",
    "\n",
    "\n",
    "\"\"\"\n",
    "RENAME NODES: function to rename nodes from 0,...,num_nodes\n",
    "Input\n",
    "- list of list of node labels in each graph\n",
    "Output\n",
    "- L: total number of different labels in the dataset\n",
    "- node_label: new renamed labels\n",
    "\"\"\"\n",
    "\n",
    "def rename_nodes(node_label): \n",
    "    \n",
    "    # number of graphs in the dataset\n",
    "    n = len(node_label)\n",
    "\n",
    "    # labels will store the new labels\n",
    "    labels = [0] * n\n",
    "\n",
    "    # disctionary containing the map from the old to the new labels\n",
    "    label_lookup = {}\n",
    "\n",
    "    # counter of unique labels\n",
    "    label_counter = 0\n",
    "\n",
    "    # for each graph in dataset\n",
    "    for i in range(n):\n",
    "\n",
    "\n",
    "        # number of nodes in graph[i]\n",
    "        num_nodes = len(node_label[i]) \n",
    "\n",
    "        # will be used to store the new labels\n",
    "        labels[i] = np.zeros(num_nodes, dtype = np.uint64) # positive integers\n",
    "\n",
    "        # for each node in the graph\n",
    "        for j in range(num_nodes):\n",
    "\n",
    "            # the node label to a string\n",
    "            l_node_str = str(np.copy(node_label[i][j]))\n",
    "            \n",
    "            # if the string has not been observed yet\n",
    "            # the corresponding node is assigned a new label\n",
    "            # otherwise it will be named with the same label\n",
    "            # already assigned to an identical string\n",
    "\n",
    "            if not label_lookup.has_key(l_node_str):\n",
    "                label_lookup[l_node_str] = label_counter\n",
    "                labels[i][j] = label_counter                                                              \n",
    "                label_counter += 1\n",
    "            else:\n",
    "                labels[i][j] = label_lookup[l_node_str]\n",
    "\n",
    "    # total number of labels in the dataset\n",
    "    L = label_counter\n",
    "    print('haha') #'Number of original labels %d' % L \n",
    "\n",
    "    return L, labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "usage: ipykernel_launcher.py [-h] --dataset DATASET\n",
      "ipykernel_launcher.py: error: the following arguments are required: --dataset\n"
     ]
    },
    {
     "ename": "SystemExit",
     "evalue": "2",
     "output_type": "error",
     "traceback": [
      "An exception has occurred, use %tb to see the full traceback.\n",
      "\u001b[0;31mSystemExit\u001b[0m\u001b[0;31m:\u001b[0m 2\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/dist-packages/IPython/core/interactiveshell.py:3273: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n",
      "  warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n"
     ]
    }
   ],
   "source": [
    "# Author: Elisabetta Ghisu\n",
    "\n",
    "\"\"\"\n",
    "- Script for computing the kernel matrix and features map \n",
    "using shortest path kernel\n",
    "\"\"\"\n",
    "\n",
    "###########################\n",
    "# --- IMPORT PACKAGES --- #\n",
    "###########################\n",
    "\n",
    "import numpy as np\n",
    "import argparse\n",
    "import os\n",
    "import pickle\n",
    "\n",
    "from numpy import genfromtxt\n",
    "\n",
    "# from sp_functions import *\n",
    "# from parse_graphs import *\n",
    "\n",
    "\n",
    "\n",
    "##############################\n",
    "### Command Line Arguments ###\n",
    "##############################\n",
    "\n",
    "parser = argparse.ArgumentParser(description = \"Compute kernel and features matrices via shortest path kernel\")\n",
    "parser.add_argument(\"--dataset\", required = True, help = \"Name of the dataset\")\n",
    "args = parser.parse_args()\n",
    "\n",
    "\n",
    "#####################\n",
    "### LOAD THE DATA ###\n",
    "#####################\n",
    "\n",
    "\"\"\"\n",
    "- Here we load the data input and targets\n",
    "- The data are assumed to be in graph formats\n",
    "- They should be in graphml format \n",
    "\"\"\"\n",
    "\n",
    "# path to the list of graphs and dataset\n",
    "filenames_graphs = \"data/%s.list\" % (args.dataset)\n",
    "path_to_dataset = \"data/%s\" % (args.dataset) \n",
    "\n",
    "# Load the targets\n",
    "filename_labels = \"data/%s_label.txt\" % (args.dataset)\n",
    "\n",
    "# load and process graphs\n",
    "node_label, ad_list, G, Y = load_and_process(filenames_graphs, filename_labels, path_to_dataset)\n",
    "\n",
    "# output directory\n",
    "out_path = \"kernel_matrices/%s/sp\" % args.dataset\n",
    "\n",
    "# If the output directory does not exist, then create it\n",
    "if not os.path.exists(out_path):\n",
    "    os.makedirs(out_path)\n",
    "\n",
    "\n",
    "#########################\n",
    "# --- SHORTEST PATH --- #\n",
    "#########################\n",
    "\n",
    "\n",
    "# assign labels starting from zero to the nodes\n",
    "L, labels = rename_nodes(node_label)\n",
    "\n",
    "\n",
    "# Compute adjancency matrix \n",
    "adj_mat = get_adj_mat(G)\n",
    "\n",
    "# Compute kernel and feature maps using shortest path\n",
    "K, phi = sp_kernel_fast(adj_mat, labels, L)\n",
    "\n",
    "# save kernel matrix\n",
    "file_name = \"%s/%s_ker_mat\" % (out_path, args.dataset)\n",
    "np.save(file_name, K)\n",
    "\n",
    "# save feature map\n",
    "file_name = \"%s/%s_phi_map\" % (out_path, args.dataset)\n",
    "np.save(file_name, phi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import networkx as nx\n",
    "   \n",
    "def loadCT(filename):\n",
    "    \"\"\"load data from .ct file.\n",
    "    \n",
    "    Notes\n",
    "    ------ \n",
    "    a typical example of data in .ct is like this:\n",
    "    \n",
    "     3 2  <- number of nodes and edges\n",
    "        0.0000    0.0000    0.0000 C <- each line describes a node, the last parameter in which is the label of the node, representing a chemical element @Q what are the first 3 numbers?\n",
    "        0.0000    0.0000    0.0000 C\n",
    "        0.0000    0.0000    0.0000 O\n",
    "      1  3  1  1 <- each line describes an edge, the first two numbers represent two nodes of the edge, the last number represents the label. @Q what are the 3th numbers?\n",
    "      2  3  1  1\n",
    "    \"\"\"\n",
    "    content = open(filename).read().splitlines()\n",
    "    G = nx.Graph(name=str(content[0])) # set name of the graph\n",
    "    tmp = content[1].split(\" \")\n",
    "    if tmp[0] == '':\n",
    "        nb_nodes = int(tmp[1]) # number of the nodes\n",
    "        nb_edges = int(tmp[2]) # number of the edges\n",
    "    else:\n",
    "        nb_nodes = int(tmp[0])\n",
    "        nb_edges = int(tmp[1])\n",
    "\n",
    "    for i in range(0, nb_nodes):\n",
    "        tmp = content[i + 2].split(\" \")\n",
    "        tmp = [x for x in tmp if x != '']\n",
    "        G.add_node(i, label=tmp[3])\n",
    "\n",
    "    for i in range(0, nb_edges):\n",
    "        tmp = content[i + G.number_of_nodes() + 2].split(\" \")\n",
    "        tmp = [x for x in tmp if x != '']\n",
    "        G.add_edge(int(tmp[0]) - 1, int(tmp[1]) - 1, label=int(tmp[3]))\n",
    "    return G\n",
    "\n",
    "\n",
    "def loadGXL(filename):\n",
    "    import networkx as nx\n",
    "    import xml.etree.ElementTree as ET\n",
    "\n",
    "    tree = ET.parse(filename)\n",
    "    root = tree.getroot()\n",
    "    index = 0\n",
    "    G = nx.Graph()\n",
    "    dic={}\n",
    "    for node in root.iter('node'):\n",
    "        label = node.find('attr')[0].text\n",
    "        dic[node.attrib['id']] = index\n",
    "        G.add_node(index, id=node.attrib['id'], label=label)\n",
    "        index += 1\n",
    "        \n",
    "    for edge in root.iter('edge'):\n",
    "        label = edge.find('attr')[0].text\n",
    "        G.add_edge(dic[edge.attrib['from']], dic[edge.attrib['to']], label=label)\n",
    "    return G\n",
    " \n",
    "def loadDataset(filename):\n",
    "    \"\"\"load file list of the dataset.\n",
    "    \"\"\"\n",
    "    from os.path import dirname, splitext\n",
    "\n",
    "    dirname_dataset = dirname(filename)\n",
    "    extension = splitext(filename)[1][1:]\n",
    "    data = []\n",
    "    y = []\n",
    "    if(extension == \"ds\"):\n",
    "        content = open(filename).read().splitlines()\n",
    "        for i in range(0, len(content)):\n",
    "            tmp = content[i].split(' ')\n",
    "            data.append(loadCT(dirname_dataset + '/' + tmp[0].replace('#', '', 1))) # remove the '#'s in file names\n",
    "            y.append(float(tmp[1]))\n",
    "    elif(extension == \"cxl\"):\n",
    "        import xml.etree.ElementTree as ET\n",
    "\n",
    "        tree = ET.parse(filename)\n",
    "        root = tree.getroot()\n",
    "        data = []\n",
    "        y = []\n",
    "        for graph in root.iter('print'):\n",
    "            mol_filename = graph.attrib['file']\n",
    "            mol_class = graph.attrib['class']\n",
    "            data.append(loadGXL(dirname_dataset + '/' + mol_filename))\n",
    "            y.append(mol_class)\n",
    "\n",
    "    return data, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "import pathlib\n",
    "sys.path.insert(0, \"../../\")\n",
    "\n",
    "\n",
    "import networkx as nx\n",
    "import numpy as np\n",
    "import time\n",
    "\n",
    "from pygraph.utils.utils import getSPGraph\n",
    "\n",
    "\n",
    "def spkernel(Gn):\n",
    "    \"\"\"Transform graph G to its corresponding shortest-paths graph using Floyd-transformation.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    G : NetworkX graph\n",
    "        The graph to be tramsformed.\n",
    "        \n",
    "    Return\n",
    "    ------\n",
    "    S : NetworkX graph\n",
    "        The shortest-paths graph corresponding to G.\n",
    "        \n",
    "    References\n",
    "    ----------\n",
    "    [1] Borgwardt KM, Kriegel HP. Shortest-path kernels on graphs. InData Mining, Fifth IEEE International Conference on 2005 Nov 27 (pp. 8-pp). IEEE.\n",
    "    \"\"\"\n",
    "    Kmatrix = np.zeros((len(Gn), len(Gn)))\n",
    "    \n",
    "    Sn = [] # get shortest path graphs of Gn\n",
    "    for i in range(0, len(Gn)):\n",
    "        Sn.append(getSPGraph(Gn[i]))\n",
    "    \n",
    "#     print(S1.nodes(data = True))\n",
    "#     print(S2.nodes(data = True))\n",
    "#     print(S1.edges(data = True))\n",
    "#     print(S2.edges(data = True))\n",
    "    \n",
    "    start_time = time.time()\n",
    "    for i in range(0, len(Gn)):\n",
    "        for j in range(i, len(Gn)):\n",
    "            for e1 in Sn[i].edges(data = True):\n",
    "                for e2 in Sn[j].edges(data = True):          \n",
    "                    if e1[2]['cost'] != 0 and e1[2]['cost'] == e2[2]['cost'] and ((e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])):\n",
    "                        Kmatrix[i][j] += 1\n",
    "                        Kmatrix[j][i] += (0 if i == j else 1)\n",
    "    \n",
    "    print(\"--- %s seconds ---\" % (time.time() - start_time))\n",
    "    \n",
    "    return Kmatrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 2. 3. 1. 2.]]\n",
      "{0: {0: [0], 3: [0, 3], 1: [0, 3, 1], 4: [0, 3, 4], 2: [0, 3, 4, 2]}, 1: {1: [1], 3: [1, 3], 0: [1, 3, 0], 4: [1, 3, 4], 2: [1, 3, 4, 2]}, 2: {2: [2], 4: [2, 4], 3: [2, 4, 3], 0: [2, 4, 3, 0], 1: [2, 4, 3, 1]}, 3: {3: [3], 0: [3, 0], 1: [3, 1], 4: [3, 4], 2: [3, 4, 2]}, 4: {4: [4], 2: [4, 2], 3: [4, 3], 0: [4, 3, 0], 1: [4, 3, 1]}}\n",
      "[[0. 2. 3. 1. 2.]\n",
      " [2. 0. 3. 1. 2.]\n",
      " [3. 3. 0. 2. 1.]\n",
      " [1. 1. 2. 0. 1.]\n",
      " [2. 2. 1. 1. 0.]]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 11436 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{(0, 1): 2.0, (0, 2): 3.0, (0, 3): 1.0, (0, 4): 2.0, (1, 2): 3.0, (1, 3): 1.0, (1, 4): 2.0, (2, 3): 2.0, (2, 4): 1.0, (3, 4): 1.0}\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 35176 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "dataset, y = loadDataset(\"../../datasets/acyclic/dataset_bps.ds\")\n",
    "G1 = dataset[12]\n",
    "\n",
    "nx.draw_networkx(G1)\n",
    "# print(list(dataset[12][4]))\n",
    "\n",
    "l = nx.shortest_path(G1)\n",
    "\n",
    "l2 = nx.floyd_warshall_numpy(G1)\n",
    "print(np.array(l2[0]))\n",
    "print(l)\n",
    "print(l2)\n",
    "from matplotlib import pyplot as plt\n",
    "plt.show()\n",
    "\n",
    "S = getSPGraph(G1)\n",
    "nx.draw_networkx(S)\n",
    "pos = nx.spring_layout(S)\n",
    "edge_labels = nx.get_edge_attributes(S,'cost')\n",
    "print(edge_labels)\n",
    "nx.draw_networkx_edge_labels(S, pos, edge_labels = edge_labels)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- 8.196406841278076 seconds ---\n",
      "[[ 3.  1.  3. ...  1.  1.  1.]\n",
      " [ 1.  6.  1. ...  0.  0.  3.]\n",
      " [ 3.  1.  3. ...  1.  1.  1.]\n",
      " ...\n",
      " [ 1.  0.  1. ... 55. 21.  7.]\n",
      " [ 1.  0.  1. ... 21. 55.  7.]\n",
      " [ 1.  3.  1. ...  7.  7. 55.]]\n"
     ]
    }
   ],
   "source": [
    "dataset, y = loadDataset(\"../../datasets/acyclic/dataset_bps.ds\")\n",
    "G1 = dataset[12]\n",
    "G2 = dataset[20]\n",
    "Kmatrix = spkernel(dataset)\n",
    "\n",
    "print(Kmatrix)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
