#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jun 18 15:52:35 2020
@author: ljia
"""
import numpy as np
import time
import networkx as nx
class GEDMethod(object):
def __init__(self, ged_data):
self._initialized = False
self._ged_data = ged_data
self._options = None
self._lower_bound = 0
self._upper_bound = np.inf
self._node_map = [0, 0] # @todo
self._runtime = None
self._init_time = None
def init(self):
"""Initializes the method with options specified by set_options().
"""
start = time.time()
self._ged_init()
end = time.time()
self._init_time = end - start
self._initialized = True
def set_options(self, options):
"""
/*!
* @brief Sets the options of the method.
* @param[in] options String of the form [--@, where @p option contains neither spaces nor single quotes,
* and @p arg contains neither spaces nor single quotes or is of the form '[--@ @] [...]',
* where both @p sub-option and @p sub-arg contain neither spaces nor single quotes.
*/
"""
self._ged_set_default_options()
for key, val in options.items():
if not self._ged_parse_option(key, val):
raise Exception('Invalid option "', key, '". Usage: options = "' + self._ged_valid_options_string() + '".') # @todo: not implemented.
self._initialized = False
def run(self, g_id, h_id):
"""
/*!
* @brief Runs the method with options specified by set_options().
* @param[in] g_id ID of input graph.
* @param[in] h_id ID of input graph.
*/
"""
start = time.time()
result = self.run_as_util(self._ged_data._graphs[g_id], self._ged_data._graphs[h_id])
end = time.time()
self._lower_bound = result['lower_bound']
self._upper_bound = result['upper_bound']
if len(result['node_maps']) > 0:
self._node_map = result['node_maps'][0]
self._runtime = end - start
def run_as_util(self, g, h):
"""
/*!
* @brief Runs the method with options specified by set_options().
* @param[in] g Input graph.
* @param[in] h Input graph.
* @param[out] result Result variable.
*/
"""
# Compute optimal solution and return if at least one of the two graphs is empty.
if nx.number_of_nodes(g) == 0 or nx.number_of_nodes(h) == 0:
print('This is not implemented.')
pass # @todo:
# Run the method.
return self._ged_run(g, h)
def get_upper_bound(self):
"""
/*!
* @brief Returns an upper bound.
* @return Upper bound for graph edit distance provided by last call to run() or -1 if the method does not yield an upper bound.
*/
"""
return self._upper_bound
def get_lower_bound(self):
"""
/*!
* @brief Returns a lower bound.
* @return Lower bound for graph edit distance provided by last call to run() or -1 if the method does not yield a lower bound.
*/
"""
return self._lower_bound
def get_runtime(self):
"""
/*!
* @brief Returns the runtime.
* @return Runtime of last call to run() in seconds.
*/
"""
return self._runtime
def get_init_time(self):
"""
/*!
* @brief Returns the initialization time.
* @return Runtime of last call to init() in seconds.
*/
"""
return self._init_time
def get_node_map(self):
"""
/*!
* @brief Returns a graph matching.
* @return Constant reference to graph matching provided by last call to run() or to an empty matching if the method does not yield a matching.
*/
"""
return self._node_map
def _ged_init(self):
"""
/*!
* @brief Initializes the method.
* @note Must be overridden by derived classes that require initialization.
*/
"""
pass
def _ged_parse_option(self, option, arg):
"""
/*!
* @brief Parses one option.
* @param[in] option The name of the option.
* @param[in] arg The argument of the option.
* @return Boolean @p true if @p option is a valid option name for the method and @p false otherwise.
* @note Must be overridden by derived classes that have options.
*/
"""
return False
def _ged_run(self, g, h):
"""
/*!
* @brief Runs the method with options specified by set_options().
* @param[in] g Input graph.
* @param[in] h Input graph.
* @param[out] result Result variable.
* @note Must be overridden by derived classes.
*/
"""
return {}
def _ged_valid_options_string(self):
"""
/*!
* @brief Returns string of all valid options.
* @return String of the form [--@.
* @note Must be overridden by derived classes that have options.
*/
"""
return ''
def _ged_set_default_options(self):
"""
/*!
* @brief Sets all options to default values.
* @note Must be overridden by derived classes that have options.
*/
"""
pass