37 std::size_t num_threads_;
38 std::size_t num_solutions_;
39 std::string centralities_;
40 std::string set_distances_;
41 std::string ml_method_;
44 std::string options_(
const std::string & dataset)
const {
45 std::string options(
"");
46 options +=
"--threads " + std::to_string(num_threads_) +
" --max-num-solutions " + std::to_string(num_solutions_) +
" --centrality-method " + centralities_;
47 if (set_distances_ !=
"") {
48 options +=
" --led-method " + set_distances_;
49 options +=
" --load ../output/" + dataset +
"_ring_" + set_distances_ +
".ini";
51 if (ml_method_ !=
"") {
53 if (ml_method_ ==
"DNN" or ml_method_ ==
"SVM") {
54 options +=
" --ml-method " + ml_method_;
56 else if (ml_method_ ==
"ONE_CLASS_SVM_LIKELIHOOD") {
57 options +=
" --ml-method ONE_CLASS_SVM --one-class-svm-likelihood TRUE";
60 options +=
" --ml-method ONE_CLASS_SVM --one-class-svm-likelihood FALSE";
62 if (ml_method_ ==
"DNN") {
63 options +=
" --load ../output/" + dataset + ged_method_name +
"dnn.ini";
65 else if (ml_method_ ==
"SVM") {
66 options +=
" --load ../output/" + dataset + ged_method_name +
"svm.ini";
69 options +=
" --load ../output/" + dataset + ged_method_name +
"one_class_svm.ini";
73 options +=
" --load ../output/" + dataset +
"_walks.ini";
76 options +=
" --load ../output/" + dataset +
"_subgraph.ini";
82 Method(
ged::Options::GEDMethod ged_method, std::size_t threads, std::size_t solutions, std::string centralities,
const std::string & set_distances =
"",
const std::string ml_method =
"") :
83 ged_method_{ged_method},
84 num_threads_{threads},
85 num_solutions_{solutions},
86 centralities_{centralities},
87 set_distances_{set_distances},
88 ml_method_{ml_method} {
89 if (num_threads_ <= 0) {
90 throw ged::Error(
"Invalid number of threads.");
92 if (num_solutions_ <= 0) {
93 throw ged::Error(
"Invalid number of solutions.");
95 if (centralities_ !=
"NONE" and centralities_ !=
"DEGREE" and centralities_ !=
"EIGENVALUE" and centralities_ !=
"PAGERANK") {
96 throw ged::Error(
"Invalid node centralities.");
99 if (set_distances !=
"LSAPE_OPTIMAL" and set_distances !=
"LSAPE_GREEDY" and set_distances !=
"GAMMA") {
103 else if (set_distances_ !=
"") {
107 if (ml_method !=
"DNN" and ml_method !=
"SVM" and ml_method !=
"ONE_CLASS_SVM_LIKELIHOOD" and ml_method !=
"ONE_CLASS_SVM_SCALE") {
108 throw ged::Error(
"Invalid machine learning method.");
111 else if (ml_method_ !=
"") {
112 throw ged::Error(
"Invalid machine learning method.");
116 std::string name()
const {
117 std::stringstream name;
118 name << ged_method_ <<
"__C-" << centralities_;
119 if (set_distances_ !=
"") {
120 name <<
"__LED-" << set_distances_;
122 if (ml_method_ !=
"") {
123 name <<
"__ML-" << ml_method_;
128 std::size_t num_threads()
const {
132 std::size_t num_solutions()
const {
133 return num_solutions_;
137 env.
set_method(ged_method_, options_(dataset));
141 std::cout <<
"\r\t" << name() <<
", " << num_threads_ <<
" threads, " << num_solutions_ <<
" solutions: " << progress_bar << std::flush;
143 double distance_to_closest_graph{std::numeric_limits<double>::infinity()};
146 avg_classification_ratio = 0;
148 closest_graph_id = std::numeric_limits<ged::GEDGraph::GraphID>::max();
149 distance_to_closest_graph = std::numeric_limits<double>::infinity();
159 closest_graph_id = h_id;
161 progress_bar.increment();
162 std::cout <<
"\r\t" << name() <<
", " << num_threads() <<
" threads, " << num_solutions() <<
" solutions: " << progress_bar << std::flush;
165 avg_classification_ratio += 1.0;
168 avg_ub /=
static_cast<double>(num_runs);
169 avg_runtime /=
static_cast<double>(num_runs);
170 avg_classification_ratio /=
static_cast<double>(env.
graph_ids().second);
176 void test_on_dataset(
const std::string & dataset,
const std::vector<string> & ml_methods,
bool quick) {
179 std::cout <<
"\n=== " << dataset <<
" ===\n";
180 std::cout <<
"\tInitializing the environment ...\n";
182 util::setup_environment(dataset,
false, env);
186 std::vector<std::string> set_distances{
"GAMMA",
"LSAPE_GREEDY",
"LSAPE_OPTIMAL"};
187 std::vector<std::string> centralities{
"NONE",
"PAGERANK"};
188 std::vector<std::size_t> threads{1, 4, 7, 10};
189 std::vector<std::size_t> solutions{1, 4, 7, 10};
191 centralities = {
"NONE"};
195 std::vector<Method> methods;
196 for (
auto ged_method : ged_methods) {
197 for (
auto num_threads : threads) {
198 for (
auto num_solutions : solutions) {
199 for (
const auto & centrality_method : centralities) {
201 for (
const auto & set_distance : set_distances) {
202 methods.emplace_back(ged_method, num_threads, num_solutions, centrality_method, set_distance);
206 for (
const auto & ml_method : ml_methods) {
207 methods.emplace_back(ged_method, num_threads, num_solutions, centrality_method,
"", ml_method);
211 methods.emplace_back(ged_method, num_threads, num_solutions, centrality_method);
217 std::string result_filename(
"../output/");
218 result_filename += dataset +
"__RESULTS.csv";
219 std::ofstream result_file(result_filename.c_str());
220 result_file <<
"method,num_threads,num_solutions,avg_ub,avg_runtime,avg_classification_ratio\n";
223 double avg_runtime{0};
224 double avg_classification_ratio{0};
225 for (
auto & method : methods) {
226 method.run_on_dataset(dataset, env, avg_ub, avg_runtime, avg_classification_ratio);
227 result_file.open(result_filename.c_str(),std::ios_base::app);
228 result_file << method.name() <<
"," << method.num_threads() <<
"," << method.num_solutions() <<
",";
229 result_file << avg_ub <<
"," << avg_runtime <<
"," << avg_classification_ratio <<
"\n";
234 int main(
int argc,
char* argv[]) {
235 std::vector<std::string> datasets;
236 std::vector<std::string> ml_methods{
"DNN",
"SVM",
"ONE_CLASS_SVM_LIKELIHOOD",
"ONE_CLASS_SVM_SCALE"};
240 std::string first_option(argv[i]);
241 if (first_option ==
"--no-svm") {
242 ml_methods = {
"DNN",
"ONE_CLASS_SVM_LIKELIHOOD"};
245 else if (first_option ==
"--quick") {
246 ml_methods = {
"DNN",
"ONE_CLASS_SVM_LIKELIHOOD"};
251 std::cout <<
"first option = \"" << first_option <<
"\"\n";
254 for (; i < argc; i++) {
255 datasets.push_back(std::string(argv[i]));
256 util::check_dataset(datasets.back());
258 if (datasets.empty()) {
259 util::setup_datasets(datasets);
261 for (
auto dataset : datasets) {
263 test_on_dataset(dataset, ml_methods, quick);
265 catch (
const std::exception & error) {
266 std::cerr << error.what() <<
". " <<
"Error on " << dataset <<
".\n";
std::pair< GEDGraph::GraphID, GEDGraph::GraphID > graph_ids() const
Provides access to the IDs of the graphs contained in the environment.
std::vector< GEDGraph >::size_type GraphID
Type of internally used graph IDs.
void init_method()
Initializes the method specified by call to set_method().
GEDMethod
Selects the method.
const std::string & get_graph_class(GEDGraph::GraphID graph_id) const
Returns the graph class.
double get_runtime(GEDGraph::GraphID g_id, GEDGraph::GraphID h_id) const
Returns runtime.
Provides utility functions for tests of PR submission.
Selects ged::BipartiteML.
double get_upper_bound(GEDGraph::GraphID g_id, GEDGraph::GraphID h_id) const
Returns upper bound for edit distance between the input graphs.
void run_method(GEDGraph::GraphID g_id, GEDGraph::GraphID h_id)
Runs the GED method specified by call to set_method() between the graphs with IDs g_id and h_id...
void set_method(Options::GEDMethod method, const std::string &options=std::string(""))
Sets the GEDMethod to be used by run_method().
Provides the API of GEDLIB.