diff --git a/Cargo.toml b/Cargo.toml index b1594b7e6a..4ad9b88f5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -474,6 +474,6 @@ path = "module/test/c" default-features = true -# [patch.crates-io] -# pathfinder_geometry = { git = "https://github.com/servo/pathfinder.git" } -# pathfinder_simd = { git = "https://github.com/servo/pathfinder.git" } +[patch.crates-io] +pathfinder_geometry = { git = "https://github.com/servo/pathfinder.git" } +pathfinder_simd = { git = "https://github.com/servo/pathfinder.git" } diff --git a/module/move/optimization_tools/Cargo.toml b/module/move/optimization_tools/Cargo.toml index 79f8029589..3f2473242e 100644 --- a/module/move/optimization_tools/Cargo.toml +++ b/module/move/optimization_tools/Cargo.toml @@ -37,7 +37,7 @@ dynamic_plot = [ "static_plot", "plotters-backend", "piston_window" ] lp_parse = [ "exmex" ] [dependencies] -derive_tools = { workspace = true, features = [ "derive_more", "full" ] } +derive_tools = { workspace = true, features = [ "derive_more", "full", "strum" ] } deterministic_rand = { workspace = true, features = [ "default" ] } iter_tools = { workspace = true, features = [ "default" ] } meta_tools = { workspace = true, features = [ "meta_constructors" ] } @@ -48,7 +48,16 @@ rand = "0.8.5" statrs = "0.16.0" faer = { version = "0.16.0", features = [ "ndarray" ] } ndarray = "0.15.6" -plotters = { version = "0.3.5" } +plotters = { git = "https://github.com/plotters-rs/plotters.git" } +# plotters = { version = "0.3.5", default-features=false, features = [ +# "bitmap_encoder", +# "ttf", +# "area_series", +# "point_series", +# "line_series", +# "full_palette", +# "bitmap_backend", +# ] } plotters-backend = { version = "0.3.5", optional = true } piston_window = { version = "0.120.0", optional = true } exmex = { version = "0.18.0", features = [ "partial" ], optional = true } diff --git a/module/move/optimization_tools/src/hybrid_optimizer/mod.rs b/module/move/optimization_tools/src/hybrid_optimizer/mod.rs index ac91811d33..90f381f6b6 100644 --- a/module/move/optimization_tools/src/hybrid_optimizer/mod.rs +++ b/module/move/optimization_tools/src/hybrid_optimizer/mod.rs @@ -8,7 +8,7 @@ use iter_tools::Itertools; use std::ops::RangeInclusive; use rayon::iter::{ ParallelIterator, IndexedParallelIterator}; use deterministic_rand::{ Seed, seq::{ SliceRandom, IteratorRandom } }; -use derive_tools::Display; +use derive_tools::exposed::Display; use optimal_params_search::OptimalProblem; mod gen_alg; diff --git a/module/move/optimization_tools/src/hybrid_optimizer/sim_anneal.rs b/module/move/optimization_tools/src/hybrid_optimizer/sim_anneal.rs index 112760b289..c176729441 100644 --- a/module/move/optimization_tools/src/hybrid_optimizer/sim_anneal.rs +++ b/module/move/optimization_tools/src/hybrid_optimizer/sim_anneal.rs @@ -1,6 +1,6 @@ //! Implementation of Simulated Annealing for Hybrid Optimizer. -use derive_tools::{ FromInner, InnerFrom, Display }; +use derive_tools::{ FromInner, InnerFrom, exposed::Display }; /// Represents temperature of SA process. #[ derive( Default, Debug, Display, Clone, Copy, PartialEq, PartialOrd, FromInner, InnerFrom ) ] pub struct Temperature( f64 ); diff --git a/module/move/optimization_tools/src/optimal_params_search/mod.rs b/module/move/optimization_tools/src/optimal_params_search/mod.rs index 76b84b8492..39390502e0 100644 --- a/module/move/optimization_tools/src/optimal_params_search/mod.rs +++ b/module/move/optimization_tools/src/optimal_params_search/mod.rs @@ -31,7 +31,7 @@ impl Default for OptimalParamsConfig { improvement_threshold : 0.005, max_no_improvement_steps : 10, - max_iterations : 100, + max_iterations : 50, } } } diff --git a/module/move/optimization_tools/src/optimal_params_search/nelder_mead.rs b/module/move/optimization_tools/src/optimal_params_search/nelder_mead.rs index 6a93d13e2f..c379c7441f 100644 --- a/module/move/optimization_tools/src/optimal_params_search/nelder_mead.rs +++ b/module/move/optimization_tools/src/optimal_params_search/nelder_mead.rs @@ -4,10 +4,7 @@ use std:: { - collections::HashMap, - fs::{ File, OpenOptions }, - ops::{ Bound, RangeBounds }, - sync::{ Arc, Mutex }, + collections::HashMap, fs::{ File, OpenOptions }, ops::{ Bound, RangeBounds }, sync::{ Arc, Mutex } }; use deterministic_rand::{ Hrng, Seed, Rng }; use iter_tools::Itertools; @@ -65,7 +62,9 @@ impl Constraints #[ derive( Debug, Clone ) ] pub struct Stats { - + pub number_of_iterations : usize, + pub number_of_starting_points : usize, + pub resumed_after_stale : usize, pub starting_point : Point, pub differences : Vec< Vec< f64 > >, pub positive_change : Vec< usize >, @@ -79,6 +78,9 @@ impl Stats let dimensions = starting_point.coords.len(); Self { + number_of_iterations : 0, + number_of_starting_points : 1, + resumed_after_stale : 0, starting_point, differences : vec![ Vec::new(); dimensions ], positive_change : vec![ 0; dimensions ], @@ -488,6 +490,7 @@ where R : RangeBounds< f64 > + Sync, let results = points.into_par_iter().map( | point | { let mut stats = Stats::new( point.clone() ); + stats.number_of_starting_points = points_number; let x0 = point.clone(); let dimensions = x0.coords.len(); let mut prev_best = self.evaluate_point( &x0, &mut stats ); @@ -509,7 +512,8 @@ where R : RangeBounds< f64 > + Sync, if self.max_iterations <= iterations { - return Result::< Solution, Error >::Ok ( Solution + stats.number_of_iterations = iterations; + return Result::< Solution, Error >::Ok ( Solution { point : res[ 0 ].0.clone(), objective : res[ 0 ].1, @@ -517,11 +521,13 @@ where R : RangeBounds< f64 > + Sync, stats : Some( stats ), } ) } - - iterations += 1; - + if best.1 < prev_best - self.improvement_threshold { + if steps_with_no_improv > 0 + { + stats.resumed_after_stale += 1; + } steps_with_no_improv = 0; prev_best = best.1; } @@ -532,7 +538,8 @@ where R : RangeBounds< f64 > + Sync, if steps_with_no_improv >= self.max_no_improvement_steps { - return Ok ( Solution + stats.number_of_iterations = iterations; + return Ok ( Solution { point : res[ 0 ].0.clone(), objective : res[ 0 ].1, @@ -541,6 +548,8 @@ where R : RangeBounds< f64 > + Sync, } ) } + iterations += 1; + //centroid let mut x0_center = vec![ 0.0; dimensions ]; for ( point, _ ) in res.iter().take( res.len() - 1 ) @@ -569,7 +578,6 @@ where R : RangeBounds< f64 > + Sync, let prev_point = res.pop().unwrap().0; stats.record_positive_change( &prev_point, &x_ref ); res.push( ( x_ref, reflection_score ) ); - // log::info!("reflection"); continue; } @@ -591,7 +599,6 @@ where R : RangeBounds< f64 > + Sync, let prev_point = res.pop().unwrap().0; stats.record_positive_change( &prev_point, &x_exp ); res.push( ( x_exp, expansion_score ) ); - // log::info!("expansion"); continue; } @@ -600,7 +607,6 @@ where R : RangeBounds< f64 > + Sync, let prev_point = res.pop().unwrap().0; stats.record_positive_change( &prev_point, &x_ref ); res.push( ( x_ref, reflection_score ) ); - // log::info!("expansion"); continue; } } @@ -620,7 +626,6 @@ where R : RangeBounds< f64 > + Sync, let prev_point = res.pop().unwrap().0; stats.record_positive_change( &prev_point, &x_con ); res.push( ( x_con, contraction_score ) ); - // log::info!("contraction"); continue; } @@ -639,7 +644,6 @@ where R : RangeBounds< f64 > + Sync, let score = self.evaluate_point( &x_shrink, &mut stats ); new_res.push( ( x_shrink, score ) ); } - // log::info!("shrink"); res = new_res; } } ).collect::< Vec< _ > >(); @@ -828,7 +832,7 @@ pub struct Solution } /// Reasons for termination of optimization process. -#[ derive( Debug, Clone ) ] +#[ derive( Debug, Clone, derive_tools::Display ) ] pub enum TerminationReason { /// Reached limit of total iterations. diff --git a/module/move/optimization_tools/src/problems/sudoku/cell_val.rs b/module/move/optimization_tools/src/problems/sudoku/cell_val.rs index f5b5394b95..f17b3db378 100644 --- a/module/move/optimization_tools/src/problems/sudoku/cell_val.rs +++ b/module/move/optimization_tools/src/problems/sudoku/cell_val.rs @@ -1,7 +1,7 @@ //! Contains CellVal structure that corresponds to single digit on Sudoku field. //! -use derive_tools::Display; +use derive_tools::exposed::Display; /// Represents the value of a cell in Sudoku. It can have a value from 1 to 9 or 0 if the cell is not assigned. #[ derive( Default, Debug, Display, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash ) ] diff --git a/module/move/optimization_tools/src/problems/sudoku/sudoku.rs b/module/move/optimization_tools/src/problems/sudoku/sudoku.rs index e71e3bb1d6..26b83e8e7b 100644 --- a/module/move/optimization_tools/src/problems/sudoku/sudoku.rs +++ b/module/move/optimization_tools/src/problems/sudoku/sudoku.rs @@ -4,7 +4,7 @@ use std::collections::HashSet; use crate::hybrid_optimizer::*; use crate::problems::sudoku::*; -use derive_tools::{ FromInner, InnerFrom, Display }; +use derive_tools::{ FromInner, InnerFrom, exposed::Display }; use deterministic_rand::{ Hrng, Rng, seq::SliceRandom }; use iter_tools::Itertools; diff --git a/module/move/optimization_tools/sudoku_results.md b/module/move/optimization_tools/sudoku_results.md index e346a06069..d6b9c2b786 100644 --- a/module/move/optimization_tools/sudoku_results.md +++ b/module/move/optimization_tools/sudoku_results.md @@ -2,19 +2,23 @@ ## For hybrid: - - max number of iterations: 100 + - max number of iterations: 50 - max no improvement iterations : 10 - improvement threshold : 0.005s - - calculated points: 19 from 48 + - termination reason: NoImprovement - - points from cache: 29 from 48 + - iterations number: 48 + + - resumed after stale: 8 + + - points from cache: 43/133 - level: Easy - - execution time: 0.154s + - execution time: 0.117s - parameters: @@ -22,32 +26,32 @@ ┌─────────────┬────────┬────────┬─────────┬─────────────┬──────────┬─────────┬────────┐ │ │ start │ min │ max │ sum of diff │ expected │ changes │ final │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ temperature │ 0.8561 │ 0.00 │ 1.00 │ 0.02 │ 0.00 │ 9 │ 0.9995 │ +│ temperature │ 0.4043 │ 0.00 │ 1.00 │ 0.10 │ 0.00 │ 41 │ 1.0000 │ │ decrease │ │ │ │ │ │ │ │ │ coefficient │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 106 │ 10.00 │ 200.00 │ 311.97 │ 7.43 │ 9 │ 108 │ +│ max │ 37 │ 10.00 │ 200.00 │ 8265.03 │ 65.08 │ 41 │ 177 │ │ mutations │ │ │ │ │ │ │ │ │ per │ │ │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ mutation │ 0.42 │ 0.00 │ 1.00 │ 1.31 │ 0.03 │ 9 │ 0.23 │ +│ mutation │ 0.16 │ 0.00 │ 1.00 │ 17.64 │ 0.14 │ 41 │ 0.41 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ crossover │ 0.66 │ 0.00 │ 1.00 │ 1.70 │ 0.04 │ 9 │ 0.54 │ +│ crossover │ 0.93 │ 0.00 │ 1.00 │ 42.41 │ 0.33 │ 41 │ 0.10 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ elitism │ -0.09 │ - │ - │ - │ - │ - │ 0.23 │ +│ elitism │ -0.09 │ - │ - │ - │ - │ - │ 0.49 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 81 │ 1.00 │ 100.00 │ 1404.93 │ 33.45 │ 9 │ 62 │ +│ max │ 30 │ 1.00 │ 100.00 │ 160.48 │ 1.26 │ 41 │ 31 │ │ stale │ │ │ │ │ │ │ │ │ iterations │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ population │ 116 │ 1.00 │ 1000.00 │ 9233.07 │ 219.83 │ 9 │ 3 │ +│ population │ 549 │ 1.00 │ 1000.00 │ 33602.75 │ 264.59 │ 41 │ 11 │ │ size │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ dynasties │ 249 │ 100.00 │ 2000.00 │ 19863.18 │ 472.93 │ 9 │ 1486 │ +│ dynasties │ 439 │ 100.00 │ 2000.00 │ 58761.38 │ 462.69 │ 41 │ 1521 │ │ limit │ │ │ │ │ │ │ │ └─────────────┴────────┴────────┴─────────┴─────────────┴──────────┴─────────┴────────┘ ``` @@ -59,7 +63,9 @@ - `max number of iterations` : limit of total iterations of optimization process, termination condition - `max no improvement iterations` : max amount of steps performed without detected improvement, termination condition - `improvement threshold` : minimal value detected as improvement in objective function result - - `calculated points` : new calculated points that were not found in cache + - `termination reason` : the reason why optimization process was stopped + - `iterations number` : actual number of iterations performed during optimization + - `resumed after stale` : how many times optimization progress was resumed after some iterations without improvement - `points from cache` : points calculated during previous optimizations and read from cache - `level` : sudoku board difficulty level - `execution time` : duration of shortest found hybrid optimization process using final parameters, measured in seconds @@ -73,19 +79,23 @@ - `final` : calculated value of parameter for which execution time was the lowest ## For SA: - - max number of iterations: 100 + - max number of iterations: 50 - max no improvement iterations : 10 - improvement threshold : 0.005s - - calculated points: 0 from 22 + - termination reason: NoImprovement + + - iterations number: 12 - - points from cache: 22 from 22 + - resumed after stale: 1 + + - points from cache: 31/32 - level: Easy - - execution time: 0.019s + - execution time: 0.026s - parameters: @@ -93,11 +103,11 @@ ┌─────────────┬────────┬────────┬─────────┬─────────────┬──────────┬─────────┬────────┐ │ │ start │ min │ max │ sum of diff │ expected │ changes │ final │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ temperature │ 0.8244 │ 0.00 │ 1.00 │ 0.48 │ 0.03 │ 12 │ 0.9554 │ +│ temperature │ 0.8244 │ 0.00 │ 1.00 │ 0.83 │ 0.03 │ 11 │ 0.9554 │ │ decrease │ │ │ │ │ │ │ │ │ coefficient │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 157 │ 10.00 │ 200.00 │ 261.00 │ 18.64 │ 12 │ 116 │ +│ max │ 157 │ 10.00 │ 200.00 │ 423.98 │ 17.67 │ 11 │ 116 │ │ mutations │ │ │ │ │ │ │ │ │ per │ │ │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ @@ -111,14 +121,14 @@ │ elitism │ -0.00 │ - │ - │ - │ - │ - │ 0.00 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 67 │ 1.00 │ 100.00 │ 214.24 │ 15.30 │ 12 │ 39 │ +│ max │ 67 │ 1.00 │ 100.00 │ 265.64 │ 11.07 │ 11 │ 39 │ │ stale │ │ │ │ │ │ │ │ │ iterations │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ │ population │ 1 │ 1.00 │ 1.00 │ 0.00 │ 0.00 │ 0 │ 1 │ │ size │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ dynasties │ 3455 │ 100.00 │ 5000.00 │ 13134.94 │ 938.21 │ 12 │ 1646 │ +│ dynasties │ 3455 │ 100.00 │ 5000.00 │ 17618.46 │ 734.10 │ 11 │ 1646 │ │ limit │ │ │ │ │ │ │ │ └─────────────┴────────┴────────┴─────────┴─────────────┴──────────┴─────────┴────────┘ ``` @@ -130,7 +140,9 @@ - `max number of iterations` : limit of total iterations of optimization process, termination condition - `max no improvement iterations` : max amount of steps performed without detected improvement, termination condition - `improvement threshold` : minimal value detected as improvement in objective function result - - `calculated points` : new calculated points that were not found in cache + - `termination reason` : the reason why optimization process was stopped + - `iterations number` : actual number of iterations performed during optimization + - `resumed after stale` : how many times optimization progress was resumed after some iterations without improvement - `points from cache` : points calculated during previous optimizations and read from cache - `level` : sudoku board difficulty level - `execution time` : duration of shortest found hybrid optimization process using final parameters, measured in seconds @@ -144,19 +156,23 @@ - `final` : calculated value of parameter for which execution time was the lowest ## For GA: - - max number of iterations: 100 + - max number of iterations: 50 - max no improvement iterations : 10 - improvement threshold : 0.005s - - calculated points: 81 from 120 + - termination reason: NoImprovement + + - iterations number: 30 + + - resumed after stale: 4 - - points from cache: 39 from 120 + - points from cache: 87/93 - level: Easy - - execution time: 0.263s + - execution time: 0.175s - parameters: @@ -164,32 +180,32 @@ ┌─────────────┬────────┬────────┬─────────┬─────────────┬──────────┬─────────┬────────┐ │ │ start │ min │ max │ sum of diff │ expected │ changes │ final │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ temperature │ 0.6847 │ 0.00 │ 1.00 │ 0.45 │ 0.00 │ 36 │ 0.9995 │ +│ temperature │ 0.3698 │ 0.00 │ 1.00 │ 4.51 │ 0.05 │ 25 │ 0.9432 │ │ decrease │ │ │ │ │ │ │ │ │ coefficient │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 174 │ 10.00 │ 200.00 │ 514.31 │ 4.40 │ 36 │ 97 │ +│ max │ 108 │ 10.00 │ 200.00 │ 751.96 │ 8.74 │ 25 │ 109 │ │ mutations │ │ │ │ │ │ │ │ │ per │ │ │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ mutation │ 0.78 │ 0.10 │ 1.00 │ 5.51 │ 0.05 │ 36 │ 0.22 │ +│ mutation │ 0.22 │ 0.10 │ 1.00 │ 4.71 │ 0.05 │ 25 │ 0.32 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ crossover │ 0.73 │ 0.10 │ 1.00 │ 2.09 │ 0.02 │ 36 │ 0.51 │ +│ crossover │ 0.16 │ 0.10 │ 1.00 │ 3.75 │ 0.04 │ 25 │ 0.54 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ elitism │ -0.52 │ - │ - │ - │ - │ - │ 0.26 │ +│ elitism │ 0.61 │ - │ - │ - │ - │ - │ 0.15 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 29 │ 1.00 │ 100.00 │ 134.61 │ 1.15 │ 36 │ 31 │ +│ max │ 61 │ 1.00 │ 100.00 │ 523.70 │ 6.09 │ 25 │ 35 │ │ stale │ │ │ │ │ │ │ │ │ iterations │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ population │ 846 │ 10.00 │ 2000.00 │ 24289.87 │ 207.61 │ 36 │ 84 │ +│ population │ 1743 │ 10.00 │ 2000.00 │ 29942.40 │ 348.17 │ 25 │ 12 │ │ size │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ dynasties │ 859 │ 100.00 │ 2000.00 │ 8440.12 │ 72.14 │ 36 │ 1075 │ +│ dynasties │ 1626 │ 100.00 │ 2000.00 │ 10424.65 │ 121.22 │ 25 │ 1092 │ │ limit │ │ │ │ │ │ │ │ └─────────────┴────────┴────────┴─────────┴─────────────┴──────────┴─────────┴────────┘ ``` @@ -201,7 +217,9 @@ - `max number of iterations` : limit of total iterations of optimization process, termination condition - `max no improvement iterations` : max amount of steps performed without detected improvement, termination condition - `improvement threshold` : minimal value detected as improvement in objective function result - - `calculated points` : new calculated points that were not found in cache + - `termination reason` : the reason why optimization process was stopped + - `iterations number` : actual number of iterations performed during optimization + - `resumed after stale` : how many times optimization progress was resumed after some iterations without improvement - `points from cache` : points calculated during previous optimizations and read from cache - `level` : sudoku board difficulty level - `execution time` : duration of shortest found hybrid optimization process using final parameters, measured in seconds @@ -221,11 +239,11 @@ │ │ coefficient │ per │ │ │ │ iterations │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ ├────────┼─────────────┼───────────┼──────────┼───────────┼─────────┼────────────┼────────────┼───────────┼───────────┤ -│ hybrid │ 0.9995 │ 108 │ 0.23 │ 0.54 │ 0.23 │ 62 │ 3 │ 1486 │ 0.154s │ +│ hybrid │ 1.0000 │ 177 │ 0.41 │ 0.10 │ 0.49 │ 31 │ 11 │ 1521 │ 0.117s │ ├────────┼─────────────┼───────────┼──────────┼───────────┼─────────┼────────────┼────────────┼───────────┼───────────┤ -│ SA │ 0.9554 │ 116 │ 1.00 │ 0.00 │ 0.00 │ 39 │ 1 │ 1646 │ 0.019s │ +│ SA │ 0.9554 │ 116 │ 1.00 │ 0.00 │ 0.00 │ 39 │ 1 │ 1646 │ 0.026s │ ├────────┼─────────────┼───────────┼──────────┼───────────┼─────────┼────────────┼────────────┼───────────┼───────────┤ -│ GA │ 0.9995 │ 97 │ 0.22 │ 0.51 │ 0.26 │ 31 │ 84 │ 1075 │ 0.263s │ +│ GA │ 0.9432 │ 109 │ 0.32 │ 0.54 │ 0.15 │ 35 │ 12 │ 1092 │ 0.175s │ └────────┴─────────────┴───────────┴──────────┴───────────┴─────────┴────────────┴────────────┴───────────┴───────────┘ ``` diff --git a/module/move/optimization_tools/tests/opt_params.rs b/module/move/optimization_tools/tests/opt_params.rs index ad4250ad9e..d50ffdba76 100644 --- a/module/move/optimization_tools/tests/opt_params.rs +++ b/module/move/optimization_tools/tests/opt_params.rs @@ -230,7 +230,9 @@ fn write_results " - `max number of iterations` : limit of total iterations of optimization process, termination condition\n", " - `max no improvement iterations` : max amount of steps performed without detected improvement, termination condition\n", " - `improvement threshold` : minimal value detected as improvement in objective function result\n", - " - `calculated points` : new calculated points that were not found in cache\n", + " - `termination reason` : the reason why optimization process was stopped\n", + " - `iterations number` : actual number of iterations performed during optimization\n", + " - `resumed after stale` : how many times optimization progress was resumed after some iterations without improvement\n", " - `points from cache` : points calculated during previous optimizations and read from cache\n", ); @@ -337,138 +339,76 @@ fn find_opt_params_sudoku() -> Result< (), Box< dyn std::error::Error > > let config = OptimalParamsConfig::default(); let initial = SudokuInitial::new( Board::from( easy ) ); - let hybrid_problem = Problem::new - ( - initial.clone(), - BestRowsColumnsCrossover, - RandomPairInBlockMutation, - ); - let starting_params = hybrid_optimizer::starting_params_for_hybrid()?; - let res = optimal_params_search::find_hybrid_optimal_params - ( - config.clone(), - starting_params.clone(), - hybrid_problem, - Some( path.clone() ), - ); - assert!( res.is_ok() ); - let mut hybrid_res = Statistics::new(); - if let Ok( solution ) = res - { - let cached = solution.stats.clone().unwrap().cached_points; - hybrid_res = Statistics - { - table_params : named_results_list - ( - solution.point.coords - .into_iter() - .map( | val | val ) - .collect_vec(), - solution.stats.unwrap(), - starting_params.bounds, - ), - list_params : vec! - [ - ( String::from( "max number of iterations" ), format!( "{}", config.max_iterations ) ), - ( String::from( "max no improvement iterations " ), format!( "{}", config.max_no_improvement_steps ) ), - ( String::from( "improvement threshold " ), format!( "{}s", config.improvement_threshold ) ), - ( String::from( "calculated points" ), format!( "{} from {}", cached.1, cached.1 + cached.0 ) ), - ( String::from( "points from cache" ), format!( "{} from {}", cached.0, cached.1 + cached.0 ) ), - ( String::from( "level" ), format!( "{:?}", Board::from( easy ).calculate_level() ) ), - ( String::from( "execution time" ), format!( "{:.3}s", solution.objective ) ), - ] - } - } - - // SA - let hybrid_problem = Problem::new - ( - initial.clone(), - BestRowsColumnsCrossover, - RandomPairInBlockMutation, - ); - let starting_params = hybrid_optimizer::starting_params_for_sa()?; - let res = optimal_params_search::find_hybrid_optimal_params - ( - config.clone(), - starting_params.clone(), - hybrid_problem, - Some( path.clone() ), - ); - assert!( res.is_ok() ); - let mut sa_res = Statistics::new(); - if let Ok( solution ) = res + let mut ga_res = Statistics::new(); + for mode in [ "hybrid", "sa", "ga" ] { - let cached = solution.stats.clone().unwrap().cached_points; - sa_res = Statistics + let mut starting_params = hybrid_optimizer::starting_params_for_hybrid()?; + match mode { - table_params : named_results_list - ( - solution.point.coords - .into_iter() - .map( | val | val ) - .collect_vec(), - solution.stats.unwrap(), - starting_params.bounds, - ), - list_params : vec! - [ - ( String::from( "max number of iterations" ), format!( "{}", config.max_iterations ) ), - ( String::from( "max no improvement iterations " ), format!( "{}", config.max_no_improvement_steps ) ), - ( String::from( "improvement threshold " ), format!( "{}s", config.improvement_threshold ) ), - ( String::from( "calculated points" ), format!( "{} from {}", cached.1, cached.1 + cached.0 ) ), - ( String::from( "points from cache" ), format!( "{} from {}", cached.0, cached.1 + cached.0 ) ), - ( String::from( "level" ), format!( "{:?}", Board::from( easy ).calculate_level() ) ), - ( String::from( "execution time" ), format!( "{:.3}s", solution.objective ) ), - ] + "hybrid" => {}, + "sa" => starting_params = hybrid_optimizer::starting_params_for_sa()?, + "ga" => starting_params = hybrid_optimizer::starting_params_for_ga()?, + _ => unreachable!(), } - } - // GA - let hybrid_problem = Problem::new( - initial.clone(), - BestRowsColumnsCrossover, - RandomPairInBlockMutation, - ); - let starting_params = hybrid_optimizer::starting_params_for_ga()?; - let res = optimal_params_search::find_hybrid_optimal_params - ( - config.clone(), - starting_params.clone(), - hybrid_problem, - Some( path ), - ); - assert!( res.is_ok() ); + let hybrid_problem = Problem::new + ( + initial.clone(), + BestRowsColumnsCrossover, + RandomPairInBlockMutation, + ); - let mut ga_res = Statistics::new(); - if let Ok( solution ) = res - { - let cached = solution.stats.clone().unwrap().cached_points; - ga_res = Statistics + let res = optimal_params_search::find_hybrid_optimal_params + ( + config.clone(), + starting_params.clone(), + hybrid_problem, + Some( path.clone() ), + ); + assert!( res.is_ok() ); + + if let Ok( solution ) = res { - table_params : named_results_list - ( - solution.point.coords - .into_iter() - .map( | val | val ) - .collect_vec(), - solution.stats.unwrap(), - starting_params.bounds, - ), - list_params : vec! - [ - ( String::from( "max number of iterations" ), format!( "{}", config.max_iterations ) ), - ( String::from( "max no improvement iterations " ), format!( "{}", config.max_no_improvement_steps ) ), - ( String::from( "improvement threshold " ), format!( "{}s", config.improvement_threshold ) ), - ( String::from( "calculated points" ), format!( "{} from {}", cached.1, cached.1 + cached.0 ) ), - ( String::from( "points from cache" ), format!( "{} from {}", cached.0, cached.1 + cached.0 ) ), - ( String::from( "level" ), format!( "{:?}", Board::from( easy ).calculate_level() ) ), - ( String::from( "execution time" ), format!( "{:.3}s", solution.objective ) ), - ] + assert!( solution.stats.is_some() ); + let stats = solution.stats.clone().unwrap(); + let cached = stats.cached_points; + let final_res = Statistics + { + table_params : named_results_list + ( + solution.point.coords + .into_iter() + .map( | val | val ) + .collect_vec(), + solution.stats.unwrap(), + starting_params.bounds, + ), + list_params : vec! + [ + ( String::from( "max number of iterations" ), format!( "{}", config.max_iterations ) ), + ( String::from( "max no improvement iterations " ), format!( "{}", config.max_no_improvement_steps ) ), + ( String::from( "improvement threshold " ), format!( "{}s", config.improvement_threshold ) ), + ( String::from( "termination reason" ), format!( "{}", solution.reason ) ), + ( String::from( "iterations number" ), format!( "{}", stats.number_of_iterations ) ), + ( String::from( "resumed after stale" ), format!( "{}", stats.resumed_after_stale ) ), + ( String::from( "points from cache" ), format!( "{}/{}", cached.0, cached.1 + cached.0 ) ), + ( String::from( "level" ), format!( "{:?}", Board::from( easy ).calculate_level() ) ), + ( String::from( "execution time" ), format!( "{:.3}s", solution.objective ) ), + ] + }; + + match mode + { + "hybrid" => hybrid_res = final_res, + "sa" => sa_res = final_res, + "ga" => ga_res = final_res, + _ => unreachable!(), + } } } + write_results( String::from( "sudoku_results" ), String::from( "Sudoku Problem" ), hybrid_res, sa_res, ga_res )?; Ok( () ) } diff --git a/module/move/optimization_tools/tsp_results.md b/module/move/optimization_tools/tsp_results.md index 78b5195456..22ec13075b 100644 --- a/module/move/optimization_tools/tsp_results.md +++ b/module/move/optimization_tools/tsp_results.md @@ -2,19 +2,19 @@ ## For hybrid: - - max number of iterations: 100 + - max number of iterations: 50 - max no improvement iterations : 10 - improvement threshold : 0.005s - - calculated points: 124 from 133 + - calculated points: 79 from 79 - - points from cache: 9 from 133 + - points from cache: 0 from 79 - number of nodes: 4 - - execution time: 0.008s + - execution time: 0.018s - parameters: @@ -22,32 +22,32 @@ ┌─────────────┬────────┬────────┬─────────┬─────────────┬──────────┬─────────┬────────┐ │ │ start │ min │ max │ sum of diff │ expected │ changes │ final │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ temperature │ 0.7726 │ 0.00 │ 1.00 │ 28.88 │ 0.21 │ 74 │ 0.7349 │ +│ temperature │ 0.8572 │ 0.00 │ 1.00 │ 0.14 │ 0.00 │ 50 │ 0.9999 │ │ decrease │ │ │ │ │ │ │ │ │ coefficient │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 14 │ 10.00 │ 200.00 │ 6917.13 │ 49.76 │ 74 │ 33 │ +│ max │ 150 │ 10.00 │ 200.00 │ 2920.64 │ 35.19 │ 50 │ 54 │ │ mutations │ │ │ │ │ │ │ │ │ per │ │ │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ mutation │ 0.00 │ 0.00 │ 1.00 │ 23.18 │ 0.17 │ 74 │ 0.13 │ +│ mutation │ 0.57 │ 0.00 │ 1.00 │ 21.60 │ 0.26 │ 50 │ 0.02 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ crossover │ 0.63 │ 0.00 │ 1.00 │ 40.81 │ 0.29 │ 74 │ 0.86 │ +│ crossover │ 0.56 │ 0.00 │ 1.00 │ 17.49 │ 0.21 │ 50 │ 0.31 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ elitism │ 0.37 │ - │ - │ - │ - │ - │ 0.01 │ +│ elitism │ -0.13 │ - │ - │ - │ - │ - │ 0.66 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 58 │ 1.00 │ 100.00 │ 3695.03 │ 26.58 │ 74 │ 62 │ +│ max │ 35 │ 1.00 │ 100.00 │ 152.19 │ 1.83 │ 50 │ 30 │ │ stale │ │ │ │ │ │ │ │ │ iterations │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ population │ 674 │ 1.00 │ 1000.00 │ 46923.94 │ 337.58 │ 74 │ 1 │ +│ population │ 148 │ 1.00 │ 1000.00 │ 20174.02 │ 243.06 │ 50 │ 10 │ │ size │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ dynasties │ 824 │ 100.00 │ 2000.00 │ 79548.00 │ 572.29 │ 74 │ 138 │ +│ dynasties │ 1982 │ 100.00 │ 2000.00 │ 63109.09 │ 760.35 │ 50 │ 130 │ │ limit │ │ │ │ │ │ │ │ └─────────────┴────────┴────────┴─────────┴─────────────┴──────────┴─────────┴────────┘ ``` @@ -59,7 +59,9 @@ - `max number of iterations` : limit of total iterations of optimization process, termination condition - `max no improvement iterations` : max amount of steps performed without detected improvement, termination condition - `improvement threshold` : minimal value detected as improvement in objective function result - - `calculated points` : new calculated points that were not found in cache + - `termination reason` : the reason why optimization process was stopped + - `iterations number` : actual number of iterations performed during optimization + - `resumed after stale` : how many times optimization progress was resumed after some iterations without improvement - `points from cache` : points calculated during previous optimizations and read from cache - `number of nodes` : number of nodes in graph representing cities from traveling salesman problem - `execution time` : duration of shortest found hybrid optimization process using final parameters, measured in seconds @@ -73,15 +75,15 @@ - `final` : calculated value of parameter for which execution time was the lowest ## For SA: - - max number of iterations: 100 + - max number of iterations: 50 - max no improvement iterations : 10 - improvement threshold : 0.005s - - calculated points: 16 from 26 + - calculated points: 33 from 33 - - points from cache: 10 from 26 + - points from cache: 0 from 33 - number of nodes: 4 @@ -93,11 +95,11 @@ ┌─────────────┬────────┬────────┬─────────┬─────────────┬──────────┬─────────┬────────┐ │ │ start │ min │ max │ sum of diff │ expected │ changes │ final │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ temperature │ 0.4533 │ 0.00 │ 1.00 │ 0.28 │ 0.01 │ 12 │ 0.9997 │ +│ temperature │ 0.1471 │ 0.00 │ 1.00 │ 8.73 │ 0.35 │ 17 │ 1.0000 │ │ decrease │ │ │ │ │ │ │ │ │ coefficient │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 54 │ 10.00 │ 200.00 │ 397.21 │ 20.91 │ 12 │ 120 │ +│ max │ 112 │ 10.00 │ 200.00 │ 188.84 │ 7.55 │ 17 │ 110 │ │ mutations │ │ │ │ │ │ │ │ │ per │ │ │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ @@ -111,14 +113,14 @@ │ elitism │ -0.00 │ - │ - │ - │ - │ - │ 0.00 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 91 │ 1.00 │ 100.00 │ 920.69 │ 48.46 │ 12 │ 87 │ +│ max │ 99 │ 1.00 │ 100.00 │ 1208.63 │ 48.35 │ 17 │ 100 │ │ stale │ │ │ │ │ │ │ │ │ iterations │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ │ population │ 1 │ 1.00 │ 1.00 │ 0.00 │ 0.00 │ 0 │ 1 │ │ size │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ dynasties │ 2849 │ 100.00 │ 5000.00 │ 35258.61 │ 1855.72 │ 12 │ 117 │ +│ dynasties │ 808 │ 100.00 │ 5000.00 │ 38996.81 │ 1559.87 │ 17 │ 123 │ │ limit │ │ │ │ │ │ │ │ └─────────────┴────────┴────────┴─────────┴─────────────┴──────────┴─────────┴────────┘ ``` @@ -130,7 +132,9 @@ - `max number of iterations` : limit of total iterations of optimization process, termination condition - `max no improvement iterations` : max amount of steps performed without detected improvement, termination condition - `improvement threshold` : minimal value detected as improvement in objective function result - - `calculated points` : new calculated points that were not found in cache + - `termination reason` : the reason why optimization process was stopped + - `iterations number` : actual number of iterations performed during optimization + - `resumed after stale` : how many times optimization progress was resumed after some iterations without improvement - `points from cache` : points calculated during previous optimizations and read from cache - `number of nodes` : number of nodes in graph representing cities from traveling salesman problem - `execution time` : duration of shortest found hybrid optimization process using final parameters, measured in seconds @@ -144,19 +148,19 @@ - `final` : calculated value of parameter for which execution time was the lowest ## For GA: - - max number of iterations: 100 + - max number of iterations: 50 - max no improvement iterations : 10 - improvement threshold : 0.005s - - calculated points: 40 from 67 + - calculated points: 51 from 58 - - points from cache: 27 from 67 + - points from cache: 7 from 58 - number of nodes: 4 - - execution time: 0.033s + - execution time: 0.036s - parameters: @@ -164,32 +168,32 @@ ┌─────────────┬────────┬────────┬─────────┬─────────────┬──────────┬─────────┬────────┐ │ │ start │ min │ max │ sum of diff │ expected │ changes │ final │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ temperature │ 0.9963 │ 0.00 │ 1.00 │ 0.05 │ 0.00 │ 35 │ 1.0000 │ +│ temperature │ 0.9963 │ 0.00 │ 1.00 │ 0.05 │ 0.00 │ 32 │ 1.0000 │ │ decrease │ │ │ │ │ │ │ │ │ coefficient │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 170 │ 10.00 │ 200.00 │ 4452.25 │ 71.81 │ 35 │ 18 │ +│ max │ 170 │ 10.00 │ 200.00 │ 2888.32 │ 53.49 │ 32 │ 24 │ │ mutations │ │ │ │ │ │ │ │ │ per │ │ │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ mutation │ 0.39 │ 0.10 │ 1.00 │ 7.29 │ 0.12 │ 35 │ 0.13 │ +│ mutation │ 0.39 │ 0.10 │ 1.00 │ 7.22 │ 0.13 │ 32 │ 0.10 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ crossover │ 0.81 │ 0.10 │ 1.00 │ 10.88 │ 0.18 │ 35 │ 0.29 │ +│ crossover │ 0.81 │ 0.10 │ 1.00 │ 8.82 │ 0.16 │ 32 │ 0.28 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ elitism │ -0.20 │ - │ - │ - │ - │ - │ 0.58 │ +│ elitism │ -0.20 │ - │ - │ - │ - │ - │ 0.61 │ │ rate │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ max │ 58 │ 1.00 │ 100.00 │ 1560.73 │ 25.17 │ 35 │ 28 │ +│ max │ 58 │ 1.00 │ 100.00 │ 1589.45 │ 29.43 │ 32 │ 100 │ │ stale │ │ │ │ │ │ │ │ │ iterations │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ population │ 572 │ 10.00 │ 2000.00 │ 44693.82 │ 720.87 │ 35 │ 19 │ +│ population │ 572 │ 10.00 │ 2000.00 │ 38470.00 │ 712.41 │ 32 │ 46 │ │ size │ │ │ │ │ │ │ │ ├─────────────┼────────┼────────┼─────────┼─────────────┼──────────┼─────────┼────────┤ -│ dynasties │ 1824 │ 100.00 │ 2000.00 │ 43273.64 │ 697.96 │ 35 │ 123 │ +│ dynasties │ 1824 │ 100.00 │ 2000.00 │ 34862.61 │ 645.60 │ 32 │ 115 │ │ limit │ │ │ │ │ │ │ │ └─────────────┴────────┴────────┴─────────┴─────────────┴──────────┴─────────┴────────┘ ``` @@ -201,7 +205,9 @@ - `max number of iterations` : limit of total iterations of optimization process, termination condition - `max no improvement iterations` : max amount of steps performed without detected improvement, termination condition - `improvement threshold` : minimal value detected as improvement in objective function result - - `calculated points` : new calculated points that were not found in cache + - `termination reason` : the reason why optimization process was stopped + - `iterations number` : actual number of iterations performed during optimization + - `resumed after stale` : how many times optimization progress was resumed after some iterations without improvement - `points from cache` : points calculated during previous optimizations and read from cache - `number of nodes` : number of nodes in graph representing cities from traveling salesman problem - `execution time` : duration of shortest found hybrid optimization process using final parameters, measured in seconds @@ -221,11 +227,11 @@ │ │ coefficient │ per │ │ │ │ iterations │ │ │ │ │ │ │ dynasty │ │ │ │ │ │ │ │ ├────────┼─────────────┼───────────┼──────────┼───────────┼─────────┼────────────┼────────────┼───────────┼───────────┤ -│ hybrid │ 0.7349 │ 33 │ 0.13 │ 0.86 │ 0.01 │ 62 │ 1 │ 138 │ 0.008s │ +│ hybrid │ 0.9999 │ 54 │ 0.02 │ 0.31 │ 0.66 │ 30 │ 10 │ 130 │ 0.018s │ ├────────┼─────────────┼───────────┼──────────┼───────────┼─────────┼────────────┼────────────┼───────────┼───────────┤ -│ SA │ 0.9997 │ 120 │ 1.00 │ 0.00 │ 0.00 │ 87 │ 1 │ 117 │ 0.007s │ +│ SA │ 1.0000 │ 110 │ 1.00 │ 0.00 │ 0.00 │ 100 │ 1 │ 123 │ 0.007s │ ├────────┼─────────────┼───────────┼──────────┼───────────┼─────────┼────────────┼────────────┼───────────┼───────────┤ -│ GA │ 1.0000 │ 18 │ 0.13 │ 0.29 │ 0.58 │ 28 │ 19 │ 123 │ 0.033s │ +│ GA │ 1.0000 │ 24 │ 0.10 │ 0.28 │ 0.61 │ 100 │ 46 │ 115 │ 0.036s │ └────────┴─────────────┴───────────┴──────────┴───────────┴─────────┴────────────┴────────────┴───────────┴───────────┘ ``` diff --git a/module/move/unitore/src/action/config.rs b/module/move/unitore/src/action/config.rs index 49b63a4773..fae3bcf67d 100644 --- a/module/move/unitore/src/action/config.rs +++ b/module/move/unitore/src/action/config.rs @@ -40,7 +40,6 @@ pub async fn config_add( mut storage : FeedStorage< SledStorage >, path : &PathB return Err( error_tools::for_app::Error::msg( err_str ) ); } - //let abs_path = proper_path_tools::path::canonicalize( path )?; let abs_path = path.canonicalize()?; let config = Config::new( abs_path.to_string_lossy().to_string() ); @@ -101,7 +100,7 @@ impl ConfigReport impl std::fmt::Display for ConfigReport { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { const EMPTY_CELL : &'static str = ""; @@ -112,7 +111,7 @@ impl std::fmt::Display for ConfigReport writeln!( f, "Added {} config file(s)", number )?; writeln!( f, - "Added {} feeds", + "Added {} feed(s)", self.new_feeds .as_ref() .and_then( | payload | diff --git a/module/move/unitore/src/action/feed.rs b/module/move/unitore/src/action/feed.rs index f7840a5f55..70063de854 100644 --- a/module/move/unitore/src/action/feed.rs +++ b/module/move/unitore/src/action/feed.rs @@ -29,7 +29,7 @@ impl FeedsReport impl std::fmt::Display for FeedsReport { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { writeln!( f, "Selected feeds:" )?; if !self.0.selected_rows.is_empty() diff --git a/module/move/unitore/src/action/frame.rs b/module/move/unitore/src/action/frame.rs index f26d538e20..2acb4cd168 100644 --- a/module/move/unitore/src/action/frame.rs +++ b/module/move/unitore/src/action/frame.rs @@ -111,7 +111,7 @@ impl FramesReport impl std::fmt::Display for FramesReport { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { let initial = vec![ vec![ format!( "Feed title: {}", self.feed_link ) ] ]; let table = tool::table_display::table_with_headers( initial[ 0 ].clone(), Vec::new() ); @@ -192,7 +192,7 @@ impl SelectedEntries impl std::fmt::Display for SelectedEntries { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { if !self.selected_columns.is_empty() { @@ -216,7 +216,7 @@ pub struct UpdateReport( pub Vec< FramesReport > ); impl std::fmt::Display for UpdateReport { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { for report in &self.0 { @@ -244,7 +244,7 @@ pub struct ListReport( pub Vec< FramesReport > ); impl std::fmt::Display for ListReport { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { for report in &self.0 { diff --git a/module/move/unitore/src/action/table.rs b/module/move/unitore/src/action/table.rs index 5e0c92663b..ce9a4e756f 100644 --- a/module/move/unitore/src/action/table.rs +++ b/module/move/unitore/src/action/table.rs @@ -245,7 +245,7 @@ pub struct TablesColumnsReport( pub Vec< ColumnsReport > ); impl std::fmt::Display for TablesColumnsReport { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { for report in &self.0 { @@ -283,7 +283,7 @@ impl ColumnsReport impl std::fmt::Display for ColumnsReport { - fn fmt( &self, f : &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { writeln!( f, "Table name: {}", self.table_name )?; writeln!( f, "Description: {}", self.table_description )?; diff --git a/module/move/unitore/src/sled_adapter/config.rs b/module/move/unitore/src/sled_adapter/config.rs index 35ad1ae3cd..a3b0cc73d8 100644 --- a/module/move/unitore/src/sled_adapter/config.rs +++ b/module/move/unitore/src/sled_adapter/config.rs @@ -26,7 +26,7 @@ impl ConfigStore for FeedStorage< SledStorage > "path", ) .values( vec![ vec![ text( config.path() ) ] ] ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await; Ok( res? ) @@ -37,7 +37,7 @@ impl ConfigStore for FeedStorage< SledStorage > let res = table( "config" ) .delete() .filter( col( "path" ).eq( format!( "'{}'", config.path() ) ) ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await?; if res == Payload::Delete( 0 ) @@ -50,7 +50,7 @@ impl ConfigStore for FeedStorage< SledStorage > async fn config_list( &mut self ) -> Result< Payload > { - let res = table( "config" ).select().execute( &mut *self.storage.lock().await ).await?; + let res = table( "config" ).select().execute( &mut *self.0.lock().await ).await?; Ok( res ) } } diff --git a/module/move/unitore/src/sled_adapter/feed.rs b/module/move/unitore/src/sled_adapter/feed.rs index 2659657103..fb38e02075 100644 --- a/module/move/unitore/src/sled_adapter/feed.rs +++ b/module/move/unitore/src/sled_adapter/feed.rs @@ -35,7 +35,7 @@ impl FeedStore for FeedStorage< SledStorage > let res = table( "feed" ) .select() .project( "title, link, update_period, config_file" ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await? ; @@ -74,7 +74,7 @@ impl FeedStore for FeedStorage< SledStorage > feed.published.map( | d | timestamp( d.to_rfc3339_opts( SecondsFormat::Millis, true ) ) ).unwrap_or( null() ), ) .filter( col( "link" ).eq( feed.link.to_string() ) ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await .context( "Failed to insert feed" )? ; @@ -101,7 +101,7 @@ impl FeedStore for FeedStorage< SledStorage > .select() .filter( col( "feed_link" ).eq( text( feed.2.to_string() ) ) ) .project( "id, published" ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await .context( "Failed to get existing frames while saving new frames" )? ; @@ -187,7 +187,7 @@ impl FeedStore for FeedStorage< SledStorage > config_file", ) .values( feeds_rows ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await .context( "Failed to insert feeds" )? ; diff --git a/module/move/unitore/src/sled_adapter/frame.rs b/module/move/unitore/src/sled_adapter/frame.rs index e2224f4958..84d4687bf4 100644 --- a/module/move/unitore/src/sled_adapter/frame.rs +++ b/module/move/unitore/src/sled_adapter/frame.rs @@ -23,7 +23,7 @@ impl FrameStore for FeedStorage< SledStorage > { async fn frames_list( &mut self ) -> Result< ListReport > { - let res = table( "frame" ).select().execute( &mut *self.storage.lock().await ).await?; + let res = table( "frame" ).select().execute( &mut *self.0.lock().await ).await?; let mut reports = Vec::new(); let all_frames = @@ -91,7 +91,7 @@ impl FrameStore for FeedStorage< SledStorage > feed_link" ) .values( entries_rows ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await .context( "Failed to insert frames" )? ; @@ -114,7 +114,7 @@ impl FrameStore for FeedStorage< SledStorage > .set( "published", entry[ 8 ].to_owned() ) .set( "media", entry[ 9 ].to_owned() ) .filter( col( "id" ).eq( entry[ 0 ].to_owned() ) ) - .execute( &mut *self.storage.lock().await ) + .execute( &mut *self.0.lock().await ) .await .context( "Failed to update frames" )? ; diff --git a/module/move/unitore/src/sled_adapter/mod.rs b/module/move/unitore/src/sled_adapter/mod.rs index 77e7ab93e6..ac4780a6f1 100644 --- a/module/move/unitore/src/sled_adapter/mod.rs +++ b/module/move/unitore/src/sled_adapter/mod.rs @@ -23,17 +23,13 @@ mod config; /// Storage for feed frames. #[ derive( Clone ) ] -pub struct FeedStorage< S : GStore + GStoreMut + Send > -{ - /// GlueSQL storage. - pub storage : Arc< Mutex< Glue< S > > >, -} +pub struct FeedStorage< S : GStore + GStoreMut + Send >( Arc< Mutex< Glue< S > > > ); impl< S : GStore + GStoreMut + Send > std::fmt::Debug for FeedStorage< S > { - fn fmt( &self, f: &mut std::fmt::Formatter<'_> ) -> std::fmt::Result + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { - writeln!(f, "GlueSQL storage" ) + writeln!( f, "GlueSQL storage" ) } } @@ -93,7 +89,7 @@ impl FeedStorage< SledStorage > frame_table.execute( &mut glue ).await?; - Ok( Self{ storage : Arc::new( Mutex::new( glue ) ) } ) + Ok( Self( Arc::new( Mutex::new( glue ) ) ) ) } } @@ -111,7 +107,7 @@ impl< S : GStore + GStoreMut + Send > Store for FeedStorage< S > { async fn query_execute( &mut self, query : String ) -> Result< QueryReport > { - let glue = &mut *self.storage.lock().await; + let glue = &mut *self.0.lock().await; let payloads = glue.execute( &query ).await.context( "Failed to execute query" )?; let report = QueryReport ( payloads ); diff --git a/module/move/unitore/src/sled_adapter/table.rs b/module/move/unitore/src/sled_adapter/table.rs index ddf0664bfc..71763918ee 100644 --- a/module/move/unitore/src/sled_adapter/table.rs +++ b/module/move/unitore/src/sled_adapter/table.rs @@ -16,7 +16,7 @@ impl TableStore for FeedStorage< SledStorage > { async fn tables_list( &mut self ) -> Result< TablesReport > { - let glue = &mut *self.storage.lock().await; + let glue = &mut *self.0.lock().await; let payloads = glue.execute( "SELECT * FROM GLUE_TABLE_COLUMNS" ).await?; let report = TablesReport::new( payloads ); @@ -26,7 +26,7 @@ impl TableStore for FeedStorage< SledStorage > async fn table_list( &mut self, table_name : String ) -> Result< Vec< Payload > > { - let glue = &mut *self.storage.lock().await; + let glue = &mut *self.0.lock().await; let query_str = format!( "SELECT * FROM GLUE_TABLE_COLUMNS WHERE TABLE_NAME='{}'", table_name ); let payloads = glue.execute( &query_str ).await?; diff --git a/module/move/unitore/tests/config_delete.rs b/module/move/unitore/tests/config_delete.rs index 336d2627b5..63a792725e 100644 --- a/module/move/unitore/tests/config_delete.rs +++ b/module/move/unitore/tests/config_delete.rs @@ -14,6 +14,7 @@ use error_tools::Result; #[ tokio::test ] async fn config_delete() -> Result< () > { + let path = std::path::PathBuf::from( "./tests/fixtures/test_config.toml" ); let temp_path = proper_path_tools::path::unique_folder_name().unwrap();