Browse Source

Update optimizing part in MedianPreimageGeneratorCML.

v0.2.x
jajupmochi 5 years ago
parent
commit
d64cf4d0ac
4 changed files with 365 additions and 599 deletions
  1. +9
    -0
      gklearn/ged/learning/__init__.py
  2. +148
    -0
      gklearn/ged/learning/cost_matrices_learner.py
  3. +175
    -0
      gklearn/ged/learning/costs_learner.py
  4. +33
    -599
      gklearn/preimage/median_preimage_generator_cml.py

+ 9
- 0
gklearn/ged/learning/__init__.py View File

@@ -0,0 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 7 16:07:25 2020

@author: ljia
"""

from gklearn.ged.learning.cost_matrices_learner import CostMatricesLearner

+ 148
- 0
gklearn/ged/learning/cost_matrices_learner.py View File

@@ -0,0 +1,148 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 7 11:42:48 2020

@author: ljia
"""
import numpy as np
import cvxpy as cp
import time
from gklearn.ged.learning.costs_learner import CostsLearner
from gklearn.ged.util import compute_geds_cml


class CostMatricesLearner(CostsLearner):
def __init__(self, edit_cost='CONSTANT', triangle_rule=False, allow_zeros=True, parallel=False, verbose=2):
super().__init__(parallel, verbose)
self._edit_cost = edit_cost
self._triangle_rule = triangle_rule
self._allow_zeros = allow_zeros
def fit(self, X, y):
if self._edit_cost == 'LETTER':
raise Exception('Cannot compute for cost "LETTER".')
elif self._edit_cost == 'LETTER2':
raise Exception('Cannot compute for cost "LETTER2".')
elif self._edit_cost == 'NON_SYMBOLIC':
raise Exception('Cannot compute for cost "NON_SYMBOLIC".')
elif self._edit_cost == 'CONSTANT': # @todo: node/edge may not labeled.
if not self._triangle_rule and self._allow_zeros:
w = cp.Variable(X.shape[1])
cost_fun = cp.sum_squares(X @ w - y)
constraints = [w >= [0.0 for i in range(X.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.execute_cvx(prob)
edit_costs_new = w.value
residual = np.sqrt(prob.value)
elif self._triangle_rule and self._allow_zeros: # @todo
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([1.0, 1.0, -1.0, 0.0, 0.0, 0.0]).T@x >= 0.0,
np.array([0.0, 0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif not self._triangle_rule and not self._allow_zeros: # @todo
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif self._triangle_rule and not self._allow_zeros: # @todo
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat.shape[1])],
np.array([1.0, 1.0, -1.0, 0.0, 0.0, 0.0]).T@x >= 0.0,
np.array([0.0, 0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
else:
raise Exception('The edit cost "', self._ged_options['edit_cost'], '" is not supported for update progress.')
self._cost_list.append(edit_costs_new)
def init_geds_and_nb_eo(self, y, graphs):
time0 = time.time()
self._cost_list.append(np.concatenate((self._ged_options['node_label_costs'],
self._ged_options['edge_label_costs'])))
ged_vec, self._nb_eo = self.compute_geds_and_nb_eo(graphs)
self._residual_list.append(np.sqrt(np.sum(np.square(np.array(ged_vec) - y))))
self._runtime_list.append(time.time() - time0)

if self._verbose >= 2:
print('Current node label costs:', self._cost_list[-1][0:len(self._ged_options['node_label_costs'])])
print('Current edge label costs:', self._cost_list[-1][len(self._ged_options['node_label_costs']):])
print('Residual list:', self._residual_list)
def update_geds_and_nb_eo(self, y, graphs, time0):
self._ged_options['node_label_costs'] = self._cost_list[-1][0:len(self._ged_options['node_label_costs'])]
self._ged_options['edge_label_costs'] = self._cost_list[-1][len(self._ged_options['node_label_costs']):]
ged_vec, self._nb_eo = self.compute_geds_and_nb_eo(graphs)
self._residual_list.append(np.sqrt(np.sum(np.square(np.array(ged_vec) - y))))
self._runtime_list.append(time.time() - time0)
def compute_geds_and_nb_eo(self, graphs):
ged_vec, ged_mat, n_edit_operations = compute_geds_cml(graphs, options=self._ged_options, parallel=self._parallel, verbose=(self._verbose > 1))
return ged_vec, np.array(n_edit_operations)
def check_convergency(self):
self._ec_changed = False
for i, cost in enumerate(self._cost_list[-1]):
if cost == 0:
if self._cost_list[-2][i] > self._epsilon_ec:
self._ec_changed = True
break
elif abs(cost - self._cost_list[-2][i]) / cost > self._epsilon_ec:
self._ec_changed = True
break
# if abs(cost - edit_cost_list[-2][i]) > self.__epsilon_ec:
# ec_changed = True
# break
self._residual_changed = False
if self._residual_list[-1] == 0:
if self._residual_list[-2] > self._epsilon_residual:
self._residual_changed = True
elif abs(self._residual_list[-1] - self._residual_list[-2]) / self._residual_list[-1] > self._epsilon_residual:
self._residual_changed = True
self._converged = not (self._ec_changed or self._residual_changed)
if self._converged:
self._itrs_without_update += 1
else:
self._itrs_without_update = 0
self._num_updates_ecs += 1
def print_current_states(self):
print()
print('-------------------------------------------------------------------------')
print('States of iteration', self._itrs + 1)
print('-------------------------------------------------------------------------')
# print('Time spend:', self.__runtime_optimize_ec)
print('Total number of iterations for optimizing:', self._itrs + 1)
print('Total number of updating edit costs:', self._num_updates_ecs)
print('Was optimization of edit costs converged:', self._converged)
print('Did edit costs change:', self._ec_changed)
print('Did residual change:', self._residual_changed)
print('Iterations without update:', self._itrs_without_update)
print('Current node label costs:', self._cost_list[-1][0:len(self._ged_options['node_label_costs'])])
print('Current edge label costs:', self._cost_list[-1][len(self._ged_options['node_label_costs']):])
print('Residual list:', self._residual_list)
print('-------------------------------------------------------------------------')

+ 175
- 0
gklearn/ged/learning/costs_learner.py View File

@@ -0,0 +1,175 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 7 11:30:31 2020

@author: ljia
"""
import numpy as np
import cvxpy as cp
import time
from gklearn.utils import Timer


class CostsLearner(object):
def __init__(self, parallel, verbose):
### To set.
self._parallel = parallel
self._verbose = verbose
# For update().
self._time_limit_in_sec = 0
self._max_itrs = 100
self._max_itrs_without_update = 3
self._epsilon_residual = 0.01
self._epsilon_ec = 0.1
### To compute.
self._residual_list = []
self._runtime_list = []
self._cost_list = []
self._nb_eo = None
# For update().
self._itrs = 0
self._converged = False
self._num_updates_ecs = 0
self._ec_changed = None
self._residual_changed = None
self._itrs_without_update = 0
### Both set and get.
self._ged_options = None


def fit(self, X, y):
pass
def preprocess(self):
pass # @todo: remove the zero numbers of edit costs.
def postprocess(self):
for i in range(len(self._cost_list[-1])):
if -1e-9 <= self._cost_list[-1][i] <= 1e-9:
self._cost_list[-1][i] = 0
if self._cost_list[-1][i] < 0:
raise ValueError('The edit cost is negative.')
def set_update_params(self, **kwargs):
self._time_limit_in_sec = kwargs.get('time_limit_in_sec', self._time_limit_in_sec)
self._max_itrs = kwargs.get('max_itrs', self._max_itrs)
self._max_itrs_without_update = kwargs.get('max_itrs_without_update', self._max_itrs_without_update)
self._epsilon_residual = kwargs.get('epsilon_residual', self._epsilon_residual)
self._epsilon_ec = kwargs.get('epsilon_ec', self._epsilon_ec)

def update(self, y, graphs, ged_options, **kwargs):
# Set parameters.
self._ged_options = ged_options
if kwargs != {}:
self.set_update_params(**kwargs)
# The initial iteration.
if self._verbose >= 2:
print('\ninitial:')
self.init_geds_and_nb_eo(y, graphs)

self._converged = False
self._itrs_without_update = 0
self._itrs = 0
self._num_updates_ecs = 0
timer = Timer(self._time_limit_in_sec)
# Run iterations from initial edit costs.
while not self.termination_criterion_met(self._converged, timer, self._itrs, self._itrs_without_update):
if self._verbose >= 2:
print('\niteration', self._itrs + 1)
time0 = time.time()
# Fit GED space to the target space.
self.preprocess()
self.fit(self._nb_eo, y)
self.postprocess()
# Compute new GEDs and numbers of edit operations.
self.update_geds_and_nb_eo(y, graphs, time0)
# Check convergency.
self.check_convergency()
# Print current states.
if self._verbose >= 2:
self.print_current_states()
self._itrs += 1
def init_geds_and_nb_eo(self, y, graphs):
pass
def update_geds_and_nb_eo(self, y, graphs, time0):
pass
def compute_geds_and_nb_eo(self, graphs):
pass
def check_convergency(self):
pass
def print_current_states(self):
pass


def termination_criterion_met(self, converged, timer, itr, itrs_without_update):
if timer.expired() or (itr >= self._max_itrs if self._max_itrs >= 0 else False):
# if self.__state == AlgorithmState.TERMINATED:
# self.__state = AlgorithmState.INITIALIZED
return True
return converged or (itrs_without_update > self._max_itrs_without_update if self._max_itrs_without_update >= 0 else False)
def execute_cvx(self, prob):
try:
prob.solve(verbose=(self._verbose>=2))
except MemoryError as error0:
if self._verbose >= 2:
print('\nUsing solver "OSQP" caused a memory error.')
print('the original error message is\n', error0)
print('solver status: ', prob.status)
print('trying solver "CVXOPT" instead...\n')
try:
prob.solve(solver=cp.CVXOPT, verbose=(self._verbose>=2))
except Exception as error1:
if self._verbose >= 2:
print('\nAn error occured when using solver "CVXOPT".')
print('the original error message is\n', error1)
print('solver status: ', prob.status)
print('trying solver "MOSEK" instead. Notice this solver is commercial and a lisence is required.\n')
prob.solve(solver=cp.MOSEK, verbose=(self._verbose>=2))
else:
if self._verbose >= 2:
print('solver status: ', prob.status)
else:
if self._verbose >= 2:
print('solver status: ', prob.status)
if self._verbose >= 2:
print()
def get_results(self):
results = {}
results['residual_list'] = self._residual_list
results['runtime_list'] = self._runtime_list
results['cost_list'] = self._cost_list
results['nb_eo'] = self._nb_eo
results['itrs'] = self._itrs
results['converged'] = self._converged
results['num_updates_ecs'] = self._num_updates_ecs
results['ec_changed'] = self._ec_changed
results['residual_changed'] = self._residual_changed
results['itrs_without_update'] = self._itrs_without_update
return results

+ 33
- 599
gklearn/preimage/median_preimage_generator_cml.py View File

@@ -10,15 +10,12 @@ import time
import random
import multiprocessing
import networkx as nx
import cvxpy as cp
import itertools
from gklearn.preimage import PreimageGenerator
from gklearn.preimage.utils import compute_k_dis
from gklearn.ged.util import compute_geds_cml
from gklearn.ged.env import GEDEnv
from gklearn.ged.learning import CostMatricesLearner
from gklearn.ged.median import MedianGraphEstimatorPy
from gklearn.ged.median import constant_node_costs, mge_options_to_string
from gklearn.utils import Timer, SpecialLabel
from gklearn.utils.utils import get_graph_kernel_by_name


@@ -28,7 +25,7 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
def __init__(self, dataset=None):
PreimageGenerator.__init__(self, dataset=dataset)
# arguments to set.
### arguments to set.
self.__mge = None
self.__ged_options = {}
self.__mge_options = {}
@@ -38,6 +35,7 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
self.__parallel = True
self.__n_jobs = multiprocessing.cpu_count()
self.__ds_name = None
# for cml.
self.__time_limit_in_sec = 0
self.__max_itrs = 100
self.__max_itrs_without_update = 3
@@ -45,7 +43,7 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
self.__epsilon_ec = 0.1
self.__allow_zeros = True
# self.__triangle_rule = True
# values to compute.
### values to compute.
self.__runtime_optimize_ec = None
self.__runtime_generate_preimage = None
self.__runtime_total = None
@@ -57,12 +55,13 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
self.__k_dis_set_median = None
self.__k_dis_gen_median = None
self.__k_dis_dataset = None
self.__itrs = 0
self.__converged = False
self.__num_updates_ecc = 0
self.__node_label_costs = None
self.__edge_label_costs = None
# values that can be set or to be computed.
# for cml.
self.__itrs = 0
self.__converged = False
self.__num_updates_ecs = 0
### values that can be set or to be computed.
self.__edit_cost_constants = []
self.__gram_matrix_unnorm = None
self.__runtime_precompute_gm = None
@@ -154,7 +153,7 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
print('================================================================================')
print('Finished generation of preimages.')
print('--------------------------------------------------------------------------------')
print('The optimized edit cost constants:', self.__edit_cost_constants)
print('The optimized edit costs:', self.__edit_cost_constants)
print('SOD of the set median:', self.__sod_set_median)
print('SOD of the generalized median:', self.__sod_gen_median)
print('Distance in kernel space for set median:', self.__k_dis_set_median)
@@ -165,7 +164,7 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
print('Time to generate pre-images:', self.__runtime_generate_preimage)
print('Total time:', self.__runtime_total)
print('Total number of iterations for optimizing:', self.__itrs)
print('Total number of updating edit costs:', self.__num_updates_ecc)
print('Total number of updating edit costs:', self.__num_updates_ecs)
print('Is optimization of edit costs converged:', self.__converged)
print('================================================================================')
print()
@@ -185,7 +184,7 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
results['k_dis_dataset'] = self.__k_dis_dataset
results['itrs'] = self.__itrs
results['converged'] = self.__converged
results['num_updates_ecc'] = self.__num_updates_ecc
results['num_updates_ecc'] = self.__num_updates_ecs
results['mge'] = {}
results['mge']['num_decrease_order'] = self.__mge.get_num_times_order_decreased()
results['mge']['num_increase_order'] = self.__mge.get_num_times_order_increased()
@@ -302,598 +301,33 @@ class MedianPreimageGeneratorCML(PreimageGenerator):
dis_k_vec.append(dis_k_mat[i, j])
dis_k_vec = np.array(dis_k_vec)
# init ged.
if self._verbose >= 2:
print('\ninitial:')
time0 = time.time()
graphs = [self.__clean_graph(g) for g in self._dataset.graphs]
self.__edit_cost_constants = self.__init_ecc
# Set GEDEnv options.
# graphs = [self.__clean_graph(g) for g in self._dataset.graphs]
# self.__edit_cost_constants = self.__init_ecc
options = self.__ged_options.copy()
options['edit_cost_constants'] = self.__edit_cost_constants # @todo
options['edit_cost_constants'] = self.__edit_cost_constants # @todo: not needed.
options['node_labels'] = self._dataset.node_labels
options['edge_labels'] = self._dataset.edge_labels
options['node_attrs'] = self._dataset.node_attrs
options['edge_attrs'] = self._dataset.edge_attrs
# options['node_attrs'] = self._dataset.node_attrs
# options['edge_attrs'] = self._dataset.edge_attrs
options['node_label_costs'] = self.__node_label_costs
options['edge_label_costs'] = self.__edge_label_costs
ged_vec_init, ged_mat, n_edit_operations = compute_geds_cml(graphs, options=options, parallel=self.__parallel, verbose=(self._verbose > 1))
residual_list = [np.sqrt(np.sum(np.square(np.array(ged_vec_init) - dis_k_vec)))]
time_list = [time.time() - time0]
edit_cost_list = [self.__init_ecc]
nb_cost_mat = np.array(n_edit_operations)
nb_cost_mat_list = [nb_cost_mat]
if self._verbose >= 2:
print('Current edit cost constants:', self.__edit_cost_constants)
print('Residual list:', residual_list)
# run iteration from initial edit costs.
self.__converged = False
itrs_without_update = 0
self.__itrs = 0
self.__num_updates_ecc = 0
timer = Timer(self.__time_limit_in_sec)
while not self.__termination_criterion_met(self.__converged, timer, self.__itrs, itrs_without_update):
if self._verbose >= 2:
print('\niteration', self.__itrs + 1)
time0 = time.time()
# "fit" geds to distances in feature space by tuning edit costs using theLeast Squares Method.
# np.savez('results/xp_fit_method/fit_data_debug' + str(self.__itrs) + '.gm',
# nb_cost_mat=nb_cost_mat, dis_k_vec=dis_k_vec,
# n_edit_operations=n_edit_operations, ged_vec_init=ged_vec_init,
# ged_mat=ged_mat)
self.__edit_cost_constants, _ = self.__update_ecc(nb_cost_mat, dis_k_vec)
for i in range(len(self.__edit_cost_constants)):
if -1e-9 <= self.__edit_cost_constants[i] <= 1e-9:
self.__edit_cost_constants[i] = 0
if self.__edit_cost_constants[i] < 0:
raise ValueError('The edit cost is negative.')
# for i in range(len(self.__edit_cost_constants)):
# if self.__edit_cost_constants[i] < 0:
# self.__edit_cost_constants[i] = 0
# compute new GEDs and numbers of edit operations.
options = self.__ged_options.copy() # np.array([self.__edit_cost_constants[0], self.__edit_cost_constants[1], 0.75])
options['edit_cost_constants'] = self.__edit_cost_constants # @todo
options['node_labels'] = self._dataset.node_labels
options['edge_labels'] = self._dataset.edge_labels
options['node_attrs'] = self._dataset.node_attrs
options['edge_attrs'] = self._dataset.edge_attrs
ged_vec, ged_mat, n_edit_operations = compute_geds_cml(graphs, options=options, parallel=self.__parallel, verbose=(self._verbose > 1))
residual_list.append(np.sqrt(np.sum(np.square(np.array(ged_vec) - dis_k_vec))))
time_list.append(time.time() - time0)
edit_cost_list.append(self.__edit_cost_constants)
nb_cost_mat = np.array(n_edit_operations)
nb_cost_mat_list.append(nb_cost_mat)
# check convergency.
ec_changed = False
for i, cost in enumerate(self.__edit_cost_constants):
if cost == 0:
if edit_cost_list[-2][i] > self.__epsilon_ec:
ec_changed = True
break
elif abs(cost - edit_cost_list[-2][i]) / cost > self.__epsilon_ec:
ec_changed = True
break
# if abs(cost - edit_cost_list[-2][i]) > self.__epsilon_ec:
# ec_changed = True
# break
residual_changed = False
if residual_list[-1] == 0:
if residual_list[-2] > self.__epsilon_residual:
residual_changed = True
elif abs(residual_list[-1] - residual_list[-2]) / residual_list[-1] > self.__epsilon_residual:
residual_changed = True
self.__converged = not (ec_changed or residual_changed)
if self.__converged:
itrs_without_update += 1
else:
itrs_without_update = 0
self.__num_updates_ecc += 1
# print current states.
if self._verbose >= 2:
print()
print('-------------------------------------------------------------------------')
print('States of iteration', self.__itrs + 1)
print('-------------------------------------------------------------------------')
# print('Time spend:', self.__runtime_optimize_ec)
print('Total number of iterations for optimizing:', self.__itrs + 1)
print('Total number of updating edit costs:', self.__num_updates_ecc)
print('Was optimization of edit costs converged:', self.__converged)
print('Did edit costs change:', ec_changed)
print('Did residual change:', residual_changed)
print('Iterations without update:', itrs_without_update)
print('Current edit cost constants:', self.__edit_cost_constants)
print('Residual list:', residual_list)
print('-------------------------------------------------------------------------')
self.__itrs += 1


def __termination_criterion_met(self, converged, timer, itr, itrs_without_update):
if timer.expired() or (itr >= self.__max_itrs if self.__max_itrs >= 0 else False):
# if self.__state == AlgorithmState.TERMINATED:
# self.__state = AlgorithmState.INITIALIZED
return True
return converged or (itrs_without_update > self.__max_itrs_without_update if self.__max_itrs_without_update >= 0 else False)


def __update_ecc(self, nb_cost_mat, dis_k_vec, rw_constraints='inequality'):
# if self.__ds_name == 'Letter-high':
if self.__ged_options['edit_cost'] == 'LETTER':
raise Exception('Cannot compute for cost "LETTER".')
pass
# # method 1: set alpha automatically, just tune c_vir and c_eir by
# # LMS using cvxpy.
# alpha = 0.5
# coeff = 100 # np.max(alpha * nb_cost_mat[:,4] / dis_k_vec)
## if np.count_nonzero(nb_cost_mat[:,4]) == 0:
## alpha = 0.75
## else:
## alpha = np.min([dis_k_vec / c_vs for c_vs in nb_cost_mat[:,4] if c_vs != 0])
## alpha = alpha * 0.99
# param_vir = alpha * (nb_cost_mat[:,0] + nb_cost_mat[:,1])
# param_eir = (1 - alpha) * (nb_cost_mat[:,4] + nb_cost_mat[:,5])
# nb_cost_mat_new = np.column_stack((param_vir, param_eir))
# dis_new = coeff * dis_k_vec - alpha * nb_cost_mat[:,3]
#
# x = cp.Variable(nb_cost_mat_new.shape[1])
# cost = cp.sum_squares(nb_cost_mat_new * x - dis_new)
# constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])]]
# prob = cp.Problem(cp.Minimize(cost), constraints)
# prob.solve()
# edit_costs_new = x.value
# edit_costs_new = np.array([edit_costs_new[0], edit_costs_new[1], alpha])
# residual = np.sqrt(prob.value)
# # method 2: tune c_vir, c_eir and alpha by nonlinear programming by
# # scipy.optimize.minimize.
# w0 = nb_cost_mat[:,0] + nb_cost_mat[:,1]
# w1 = nb_cost_mat[:,4] + nb_cost_mat[:,5]
# w2 = nb_cost_mat[:,3]
# w3 = dis_k_vec
# func_min = lambda x: np.sum((w0 * x[0] * x[3] + w1 * x[1] * (1 - x[2]) \
# + w2 * x[2] - w3 * x[3]) ** 2)
# bounds = ((0, None), (0., None), (0.5, 0.5), (0, None))
# res = minimize(func_min, [0.9, 1.7, 0.75, 10], bounds=bounds)
# edit_costs_new = res.x[0:3]
# residual = res.fun
# method 3: tune c_vir, c_eir and alpha by nonlinear programming using cvxpy.
# # method 4: tune c_vir, c_eir and alpha by QP function
# # scipy.optimize.least_squares. An initial guess is required.
# w0 = nb_cost_mat[:,0] + nb_cost_mat[:,1]
# w1 = nb_cost_mat[:,4] + nb_cost_mat[:,5]
# w2 = nb_cost_mat[:,3]
# w3 = dis_k_vec
# func = lambda x: (w0 * x[0] * x[3] + w1 * x[1] * (1 - x[2]) \
# + w2 * x[2] - w3 * x[3]) ** 2
# res = optimize.root(func, [0.9, 1.7, 0.75, 100])
# edit_costs_new = res.x
# residual = None
elif self.__ged_options['edit_cost'] == 'LETTER2':
# # 1. if c_vi != c_vr, c_ei != c_er.
# nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
# x = cp.Variable(nb_cost_mat_new.shape[1])
# cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
## # 1.1 no constraints.
## constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])]]
# # 1.2 c_vs <= c_vi + c_vr.
# constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
# np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0]
## # 2. if c_vi == c_vr, c_ei == c_er.
## nb_cost_mat_new = nb_cost_mat[:,[0,3,4]]
## nb_cost_mat_new[:,0] += nb_cost_mat[:,1]
## nb_cost_mat_new[:,2] += nb_cost_mat[:,5]
## x = cp.Variable(nb_cost_mat_new.shape[1])
## cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
## # 2.1 no constraints.
## constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])]]
### # 2.2 c_vs <= c_vi + c_vr.
### constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
### np.array([2.0, -1.0, 0.0]).T@x >= 0.0]
#
# prob = cp.Problem(cp.Minimize(cost_fun), constraints)
# prob.solve()
# edit_costs_new = [x.value[0], x.value[0], x.value[1], x.value[2], x.value[2]]
# edit_costs_new = np.array(edit_costs_new)
# residual = np.sqrt(prob.value)
if not self.__triangle_rule and self.__allow_zeros:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0]).T@x >= 0.01]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif self.__triangle_rule and self.__allow_zeros:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0]).T@x >= 0.01,
np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif not self.__triangle_rule and not self.__allow_zeros:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
prob.solve()
edit_costs_new = x.value
residual = np.sqrt(prob.value)
# elif method == 'inequality_modified':
# # c_vs <= c_vi + c_vr.
# nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
# x = cp.Variable(nb_cost_mat_new.shape[1])
# cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
# constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
# np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0]
# prob = cp.Problem(cp.Minimize(cost_fun), constraints)
# prob.solve()
# # use same costs for insertion and removal rather than the fitted costs.
# edit_costs_new = [x.value[0], x.value[0], x.value[1], x.value[2], x.value[2]]
# edit_costs_new = np.array(edit_costs_new)
# residual = np.sqrt(prob.value)
elif self.__triangle_rule and not self.__allow_zeros:
# c_vs <= c_vi + c_vr.
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif rw_constraints == '2constraints': # @todo: rearrange it later.
# c_vs <= c_vi + c_vr and c_vi == c_vr, c_ei == c_er.
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0,
np.array([1.0, -1.0, 0.0, 0.0, 0.0]).T@x == 0.0,
np.array([0.0, 0.0, 0.0, 1.0, -1.0]).T@x == 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
prob.solve()
edit_costs_new = x.value
residual = np.sqrt(prob.value)

elif self.__ged_options['edit_cost'] == 'NON_SYMBOLIC':
is_n_attr = np.count_nonzero(nb_cost_mat[:,2])
is_e_attr = np.count_nonzero(nb_cost_mat[:,5])
if self.__ds_name == 'SYNTHETICnew': # @todo: rearrenge this later.
# nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4]]
nb_cost_mat_new = nb_cost_mat[:,[2,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
# constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
# np.array([0.0, 0.0, 0.0, 1.0, -1.0]).T@x == 0.0]
# constraints = [x >= [0.0001 for i in range(nb_cost_mat_new.shape[1])]]
constraints = [x >= [0.0001 for i in range(nb_cost_mat_new.shape[1])],
np.array([0.0, 1.0, -1.0]).T@x == 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
prob.solve()
# print(x.value)
edit_costs_new = np.concatenate((np.array([0.0, 0.0]), x.value,
np.array([0.0])))
residual = np.sqrt(prob.value)
elif not self.__triangle_rule and self.__allow_zeros:
if is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif is_n_attr and not is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0]).T@x >= 0.01]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value, np.array([0.0])))
residual = np.sqrt(prob.value)
elif not is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 1.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]), x.value[2:]))
residual = np.sqrt(prob.value)
else:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]),
x.value[2:], np.array([0.0])))
residual = np.sqrt(prob.value)
elif self.__triangle_rule and self.__allow_zeros:
if is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([1.0, 1.0, -1.0, 0.0, 0.0, 0.0]).T@x >= 0.0,
np.array([0.0, 0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif is_n_attr and not is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0]).T@x >= 0.01,
np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value, np.array([0.0])))
residual = np.sqrt(prob.value)
elif not is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 1.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]), x.value[2:]))
residual = np.sqrt(prob.value)
else:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]),
x.value[2:], np.array([0.0])))
residual = np.sqrt(prob.value)
elif not self.__triangle_rule and not self.__allow_zeros:
if is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif is_n_attr and not is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value, np.array([0.0])))
residual = np.sqrt(prob.value)
elif not is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]), x.value[2:]))
residual = np.sqrt(prob.value)
else:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]),
x.value[2:], np.array([0.0])))
residual = np.sqrt(prob.value)
elif self.__triangle_rule and not self.__allow_zeros:
# c_vs <= c_vi + c_vr.
if is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 1.0, -1.0, 0.0, 0.0, 0.0]).T@x >= 0.0,
np.array([0.0, 0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif is_n_attr and not is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,2,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])],
np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value, np.array([0.0])))
residual = np.sqrt(prob.value)
elif not is_n_attr and is_e_attr:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4,5]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])],
np.array([0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]), x.value[2:]))
residual = np.sqrt(prob.value)
else:
nb_cost_mat_new = nb_cost_mat[:,[0,1,3,4]]
x = cp.Variable(nb_cost_mat_new.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat_new @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat_new.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = np.concatenate((x.value[0:2], np.array([0.0]),
x.value[2:], np.array([0.0])))
residual = np.sqrt(prob.value)

elif self.__ged_options['edit_cost'] == 'CONSTANT': # @todo: node/edge may not labeled.
if not self.__triangle_rule and self.__allow_zeros:
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif self.__triangle_rule and self.__allow_zeros:
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat.shape[1])],
np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 1.0, 0.0, 0.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 1.0, 0.0, 0.0]).T@x >= 0.01,
np.array([0.0, 0.0, 0.0, 0.0, 1.0, 0.0]).T@x >= 0.01,
np.array([1.0, 1.0, -1.0, 0.0, 0.0, 0.0]).T@x >= 0.0,
np.array([0.0, 0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif not self.__triangle_rule and not self.__allow_zeros:
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat.shape[1])]]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
elif self.__triangle_rule and not self.__allow_zeros:
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.01 for i in range(nb_cost_mat.shape[1])],
np.array([1.0, 1.0, -1.0, 0.0, 0.0, 0.0]).T@x >= 0.0,
np.array([0.0, 0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
else:
raise Exception('The edit cost "', self.__ged_options['edit_cost'], '" is not supported for update progress.')
# # method 1: simple least square method.
# edit_costs_new, residual, _, _ = np.linalg.lstsq(nb_cost_mat, dis_k_vec,
# rcond=None)
# # method 2: least square method with x_i >= 0.
# edit_costs_new, residual = optimize.nnls(nb_cost_mat, dis_k_vec)
# method 3: solve as a quadratic program with constraints.
# P = np.dot(nb_cost_mat.T, nb_cost_mat)
# q_T = -2 * np.dot(dis_k_vec.T, nb_cost_mat)
# G = -1 * np.identity(nb_cost_mat.shape[1])
# h = np.array([0 for i in range(nb_cost_mat.shape[1])])
# A = np.array([1 for i in range(nb_cost_mat.shape[1])])
# b = 1
# x = cp.Variable(nb_cost_mat.shape[1])
# prob = cp.Problem(cp.Minimize(cp.quad_form(x, P) + q_T@x),
# [G@x <= h])
# prob.solve()
# edit_costs_new = x.value
# residual = prob.value - np.dot(dis_k_vec.T, dis_k_vec)
# G = -1 * np.identity(nb_cost_mat.shape[1])
# h = np.array([0 for i in range(nb_cost_mat.shape[1])])
x = cp.Variable(nb_cost_mat.shape[1])
cost_fun = cp.sum_squares(nb_cost_mat @ x - dis_k_vec)
constraints = [x >= [0.0 for i in range(nb_cost_mat.shape[1])],
# np.array([1.0, 1.0, -1.0, 0.0, 0.0]).T@x >= 0.0]
np.array([1.0, 1.0, -1.0, 0.0, 0.0, 0.0]).T@x >= 0.0,
np.array([0.0, 0.0, 0.0, 1.0, 1.0, -1.0]).T@x >= 0.0]
prob = cp.Problem(cp.Minimize(cost_fun), constraints)
self.__execute_cvx(prob)
edit_costs_new = x.value
residual = np.sqrt(prob.value)
# method 4:
return edit_costs_new, residual
def __execute_cvx(self, prob):
try:
prob.solve(verbose=(self._verbose>=2))
except MemoryError as error0:
if self._verbose >= 2:
print('\nUsing solver "OSQP" caused a memory error.')
print('the original error message is\n', error0)
print('solver status: ', prob.status)
print('trying solver "CVXOPT" instead...\n')
try:
prob.solve(solver=cp.CVXOPT, verbose=(self._verbose>=2))
except Exception as error1:
if self._verbose >= 2:
print('\nAn error occured when using solver "CVXOPT".')
print('the original error message is\n', error1)
print('solver status: ', prob.status)
print('trying solver "MOSEK" instead. Notice this solver is commercial and a lisence is required.\n')
prob.solve(solver=cp.MOSEK, verbose=(self._verbose>=2))
else:
if self._verbose >= 2:
print('solver status: ', prob.status)
else:
if self._verbose >= 2:
print('solver status: ', prob.status)
if self._verbose >= 2:
print()
# Learner cost matrices.
# Initialize cost learner.
cml = CostMatricesLearner(edit_cost='CONSTANT', triangle_rule=False, allow_zeros=True, parallel=self.__parallel, verbose=self._verbose) # @todo
cml.set_update_params(time_limit_in_sec=self.__time_limit_in_sec, max_itrs=self.__max_itrs, max_itrs_without_update=self.__max_itrs_without_update, epsilon_residual=self.__epsilon_residual, epsilon_ec=self.__epsilon_ec)
# Run cost learner.
cml.update(dis_k_vec, self._dataset.graphs, options)
# Get results.
results = cml.get_results()
self.__converged = results['converged']
self.__itrs = results['itrs']
self.__num_updates_ecs = results['num_updates_ecs']
cost_list = results['cost_list']
self.__node_label_costs = cost_list[-1][0:len(self.__node_label_costs)]
self.__edge_label_costs = cost_list[-1][len(self.__node_label_costs):]

def __gmg_bcu(self):


Loading…
Cancel
Save