From c4b80fc9c355e12469856d2553c0023c95dbeff9 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 19 Oct 2023 10:12:38 -0300 Subject: [PATCH] Updates --- .github/workflows/ci.yaml | 2 +- .gitignore | 4 +- {scripts => .scripts}/fuzz.sh | 0 .scripts/tests.sh | 20 + Cargo.lock | 433 ++++++--------- Cargo.toml | 8 +- README.md | 13 +- clippy.toml | 1 + mop-bindings/Cargo.toml | 25 - mop-bindings/src/lib.rs | 2 - mop-blocks-fuzz/.gitignore | 4 - mop-blocks/Cargo.toml | 28 - mop-blocks/LICENSE | 201 ------- mop-blocks/README.md | 3 - mop-blocks/src/gp/gp_operations.rs | 43 -- mop-blocks/src/gp/gp_operations/mph_mp_mph.rs | 53 -- .../src/gp/gp_operations/mphs_mp_mphs.rs | 59 --- mop-blocks/src/gp/gp_ors_evaluators.rs | 178 ------- mop-blocks/src/lib.rs | 29 -- mop-blocks/src/objs.rs | 4 - mop-common/Cargo.toml | 14 - mop-common/LICENSE | 201 ------- mop-common/README.md | 3 - mop-common/src/lib.rs | 10 - mop-common/src/solver.rs | 30 -- mop-common/src/trait_cfg.rs | 11 - mop-facades/Cargo.toml | 20 - mop-facades/LICENSE | 201 ------- mop-facades/README.md | 3 - mop-facades/src/lib.rs | 3 - {mop-blocks-fuzz => mop-fuzz}/Cargo.toml | 6 +- {mop-blocks-fuzz => mop-fuzz}/dr_matrix.rs | 2 +- {mop-blocks-fuzz => mop-fuzz}/gp.rs | 2 +- mop-problems/Cargo.lock | 491 ------------------ mop-problems/Cargo.toml | 32 -- mop-problems/src/cvrp.rs | 216 -------- mop-problems/src/lib.rs | 24 - mop-problems/src/main.rs | 133 ----- mop-solvers/Cargo.toml | 22 - mop-solvers/LICENSE | 201 ------- mop-solvers/README.md | 3 - mop-solvers/src/genetic_algorithm.rs | 9 - mop/Cargo.toml | 33 +- {mop-bindings => mop}/LICENSE | 0 mop/README.md | 4 +- .../src => mop/examples}/binh_and_korn.rs | 27 +- mop/examples/common/mod.rs | 140 +++++ {mop-problems/src => mop/examples}/constr.rs | 27 +- mop/examples/cvrp.rs | 236 +++++++++ .../src => mop/examples}/rastrigin.rs | 20 +- .../examples}/schaffer_function_2.rs | 23 +- .../src => mop/examples}/test_function_4.rs | 29 +- {mop-blocks => mop}/src/criteria.rs | 0 {mop-blocks => mop}/src/criteria/cstr.rs | 0 {mop-blocks => mop}/src/criteria/obj.rs | 3 +- {mop-blocks => mop}/src/doc_tests.rs | 0 {mop-blocks => mop}/src/domain.rs | 41 +- {mop-blocks => mop}/src/dr_matrix.rs | 77 +-- .../src/dr_matrix/dr_matrix_error.rs | 4 +- .../src/dr_matrix/dr_matrix_row_iter_impls.rs | 16 +- .../dr_matrix/dr_matrix_row_par_iter_impls.rs | 90 ++++ .../dr_matrix/dr_matrix_rows_constructor.rs | 28 +- mop/src/either.rs | 32 ++ {mop-blocks => mop}/src/error.rs | 24 +- {mop-blocks => mop}/src/gp.rs | 36 +- {mop-blocks => mop}/src/gp/gp_definitions.rs | 14 +- .../src/gp/gp_definitions_builder.rs | 42 +- mop/src/gp/gp_operations.rs | 43 ++ mop/src/gp/gp_operations/mph_mp_mph.rs | 49 ++ mop/src/gp/gp_operations/mphs_mp_mphs.rs | 55 ++ {mop-blocks => mop}/src/gp/gp_or.rs | 29 +- {mop-blocks => mop}/src/gp/gp_ors.rs | 155 ++++-- .../src/gp/gp_ors_constructor.rs | 64 +-- mop/src/gp/gp_ors_evaluators.rs | 190 +++++++ mop/src/lib.rs | 50 +- {mop-blocks => mop}/src/obj_direction.rs | 0 mop/src/objs.rs | 5 + .../src/objs/min_cstrs_rslts.rs | 23 +- .../src/objs/min_weighted_sum.rs | 26 +- {mop-facades => mop}/src/opt.rs | 0 {mop-facades => mop}/src/opt/opt_facade.rs | 52 +- {mop-facades => mop}/src/opt/opt_hooks.rs | 0 .../src/opt/opt_hooks_fn_builder.rs | 15 +- mop/src/par_bounds.rs | 13 + {mop-blocks => mop}/src/pct.rs | 8 +- {mop-blocks => mop}/src/quality_comparator.rs | 0 .../src/quality_comparator/nsga2.rs | 16 +- .../src/quality_comparator/objs_avg.rs | 4 +- {mop-blocks => mop}/src/solution.rs | 6 +- mop/src/solver.rs | 19 + mop-solvers/src/lib.rs => mop/src/solvers.rs | 2 - mop/src/solvers/genetic_algorithm.rs | 8 + .../genetic_algorithm_params.rs | 0 .../genetic_algorithm_params_builder.rs | 10 +- .../solvers}/genetic_algorithm/operators.rs | 0 .../genetic_algorithm/operators/crossover.rs | 0 .../operators/crossover/multi_point.rs | 45 +- .../operators/mating_selection.rs | 0 .../operators/mating_selection/tournament.rs | 33 +- .../genetic_algorithm/operators/mutation.rs | 3 +- .../mutation/random_domain_assignments.rs | 18 +- .../operators/mutation/swap.rs | 20 +- .../src/solvers}/genetic_algorithm/spea2.rs | 153 +++--- .../spea2/arch_union_popul.rs | 2 +- ...environment_selection_truncation_result.rs | 0 {mop-solvers/src => mop/src/solvers}/utils.rs | 0 {mop-blocks => mop}/src/utils.rs | 26 +- {mop-bindings => mop}/src/wasm_bindgen.rs | 74 ++- rustfmt.toml | 11 +- scripts/publish.sh | 19 - scripts/tests.sh | 39 -- 111 files changed, 1801 insertions(+), 3177 deletions(-) rename {scripts => .scripts}/fuzz.sh (100%) create mode 100755 .scripts/tests.sh create mode 100644 clippy.toml delete mode 100644 mop-bindings/Cargo.toml delete mode 100644 mop-bindings/src/lib.rs delete mode 100644 mop-blocks-fuzz/.gitignore delete mode 100644 mop-blocks/Cargo.toml delete mode 100644 mop-blocks/LICENSE delete mode 100644 mop-blocks/README.md delete mode 100644 mop-blocks/src/gp/gp_operations.rs delete mode 100644 mop-blocks/src/gp/gp_operations/mph_mp_mph.rs delete mode 100644 mop-blocks/src/gp/gp_operations/mphs_mp_mphs.rs delete mode 100644 mop-blocks/src/gp/gp_ors_evaluators.rs delete mode 100644 mop-blocks/src/lib.rs delete mode 100644 mop-blocks/src/objs.rs delete mode 100644 mop-common/Cargo.toml delete mode 100644 mop-common/LICENSE delete mode 100644 mop-common/README.md delete mode 100644 mop-common/src/lib.rs delete mode 100644 mop-common/src/solver.rs delete mode 100644 mop-common/src/trait_cfg.rs delete mode 100644 mop-facades/Cargo.toml delete mode 100644 mop-facades/LICENSE delete mode 100644 mop-facades/README.md delete mode 100644 mop-facades/src/lib.rs rename {mop-blocks-fuzz => mop-fuzz}/Cargo.toml (74%) rename {mop-blocks-fuzz => mop-fuzz}/dr_matrix.rs (96%) rename {mop-blocks-fuzz => mop-fuzz}/gp.rs (97%) delete mode 100644 mop-problems/Cargo.lock delete mode 100644 mop-problems/Cargo.toml delete mode 100644 mop-problems/src/cvrp.rs delete mode 100644 mop-problems/src/lib.rs delete mode 100644 mop-problems/src/main.rs delete mode 100644 mop-solvers/Cargo.toml delete mode 100644 mop-solvers/LICENSE delete mode 100644 mop-solvers/README.md delete mode 100755 mop-solvers/src/genetic_algorithm.rs rename {mop-bindings => mop}/LICENSE (100%) mode change 120000 => 100644 mop/README.md rename {mop-problems/src => mop/examples}/binh_and_korn.rs (74%) create mode 100644 mop/examples/common/mod.rs rename {mop-problems/src => mop/examples}/constr.rs (70%) create mode 100644 mop/examples/cvrp.rs rename {mop-problems/src => mop/examples}/rastrigin.rs (69%) rename {mop-problems/src => mop/examples}/schaffer_function_2.rs (70%) rename {mop-problems/src => mop/examples}/test_function_4.rs (72%) rename {mop-blocks => mop}/src/criteria.rs (100%) rename {mop-blocks => mop}/src/criteria/cstr.rs (100%) rename {mop-blocks => mop}/src/criteria/obj.rs (94%) rename {mop-blocks => mop}/src/doc_tests.rs (100%) rename {mop-blocks => mop}/src/domain.rs (73%) rename {mop-blocks => mop}/src/dr_matrix.rs (86%) rename {mop-blocks => mop}/src/dr_matrix/dr_matrix_error.rs (89%) rename {mop-blocks => mop}/src/dr_matrix/dr_matrix_row_iter_impls.rs (83%) create mode 100644 mop/src/dr_matrix/dr_matrix_row_par_iter_impls.rs rename {mop-blocks => mop}/src/dr_matrix/dr_matrix_rows_constructor.rs (75%) create mode 100644 mop/src/either.rs rename {mop-blocks => mop}/src/error.rs (78%) rename {mop-blocks => mop}/src/gp.rs (83%) rename {mop-blocks => mop}/src/gp/gp_definitions.rs (90%) rename {mop-blocks => mop}/src/gp/gp_definitions_builder.rs (87%) create mode 100644 mop/src/gp/gp_operations.rs create mode 100644 mop/src/gp/gp_operations/mph_mp_mph.rs create mode 100644 mop/src/gp/gp_operations/mphs_mp_mphs.rs rename {mop-blocks => mop}/src/gp/gp_or.rs (74%) rename {mop-blocks => mop}/src/gp/gp_ors.rs (61%) rename {mop-blocks => mop}/src/gp/gp_ors_constructor.rs (54%) create mode 100644 mop/src/gp/gp_ors_evaluators.rs rename {mop-blocks => mop}/src/obj_direction.rs (100%) create mode 100644 mop/src/objs.rs rename {mop-blocks => mop}/src/objs/min_cstrs_rslts.rs (62%) rename {mop-blocks => mop}/src/objs/min_weighted_sum.rs (64%) rename {mop-facades => mop}/src/opt.rs (100%) rename {mop-facades => mop}/src/opt/opt_facade.rs (88%) rename {mop-facades => mop}/src/opt/opt_hooks.rs (100%) rename {mop-facades => mop}/src/opt/opt_hooks_fn_builder.rs (86%) create mode 100644 mop/src/par_bounds.rs rename {mop-blocks => mop}/src/pct.rs (87%) rename {mop-blocks => mop}/src/quality_comparator.rs (100%) rename {mop-blocks => mop}/src/quality_comparator/nsga2.rs (78%) rename {mop-blocks => mop}/src/quality_comparator/objs_avg.rs (87%) rename {mop-blocks => mop}/src/solution.rs (91%) create mode 100644 mop/src/solver.rs rename mop-solvers/src/lib.rs => mop/src/solvers.rs (64%) mode change 100755 => 100644 create mode 100755 mop/src/solvers/genetic_algorithm.rs rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/genetic_algorithm_params.rs (100%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/genetic_algorithm_params_builder.rs (76%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators.rs (100%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators/crossover.rs (100%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators/crossover/multi_point.rs (67%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators/mating_selection.rs (100%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators/mating_selection/tournament.rs (68%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators/mutation.rs (80%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators/mutation/random_domain_assignments.rs (78%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/operators/mutation/swap.rs (77%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/spea2.rs (78%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/spea2/arch_union_popul.rs (92%) rename {mop-solvers/src => mop/src/solvers}/genetic_algorithm/spea2/environment_selection_truncation_result.rs (100%) rename {mop-solvers/src => mop/src/solvers}/utils.rs (100%) rename {mop-blocks => mop}/src/utils.rs (73%) rename {mop-bindings => mop}/src/wasm_bindgen.rs (86%) delete mode 100755 scripts/publish.sh delete mode 100755 scripts/tests.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8a659f7..6a760e2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,7 +38,7 @@ jobs: uses: actions-rs/toolchain@v1 with: components: clippy, rustfmt - toolchain: stable + toolchain: nightly-2022-01-28 profile: minimal override: true diff --git a/.gitignore b/.gitignore index c4b2fdd..c431b5b 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.rs.bk -target \ No newline at end of file +artifacts +corpus +target diff --git a/scripts/fuzz.sh b/.scripts/fuzz.sh similarity index 100% rename from scripts/fuzz.sh rename to .scripts/fuzz.sh diff --git a/.scripts/tests.sh b/.scripts/tests.sh new file mode 100755 index 0000000..f17a55d --- /dev/null +++ b/.scripts/tests.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +rt='rust-tools --template you-rust' + +export CARGO_TARGET_DIR="$($rt target-dir)" +export RUST_BACKTRACE=1 +export RUSTFLAGS="$($rt rust-flags '' -Dmissing_docs,-Dunstable_features,-Dunused_crate_dependencies,-Dvariant_size_differences)" + +$rt rustfmt +#$rt clippy + +$rt test-generic mop +$rt test-with-features mop ndstruct +$rt test-with-features mop rand +$rt test-with-features mop rayon +$rt test-with-features mop serde +$rt test-with-features mop std +$rt test-with-features mop wasm-bindgen diff --git a/Cargo.lock b/Cargo.lock index 59834d0..0155586 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,42 +4,40 @@ version = 3 [[package]] name = "arbitrary" -version = "1.0.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" +checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" dependencies = [ "derive_arbitrary", ] [[package]] name = "arrayvec" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "cc" -version = "1.0.69" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] [[package]] name = "cfg-if" @@ -48,144 +46,113 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "cl-traits" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2f7b27358fcd71b173cffa2ded37fc55b2bc35384c73f9d1f2fc235e000aca" +name = "cl-aux" +version = "2.2.0" dependencies = [ "arrayvec", + "serde", ] [[package]] name = "console_error_panic_hook" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", "wasm-bindgen", ] [[package]] -name = "derive_arbitrary" -version = "1.0.1" +name = "crossbeam-deque" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1281ee141df08871db9fe261ab5312179eac32d1e314134ceaa8dd7c042f5a" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] -name = "futures" -version = "0.3.16" +name = "crossbeam-epoch" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", ] [[package]] -name = "futures-channel" -version = "0.3.16" +name = "crossbeam-utils" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ - "futures-core", - "futures-sink", + "cfg-if", ] [[package]] -name = "futures-core" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" - -[[package]] -name = "futures-io" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" - -[[package]] -name = "futures-sink" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" - -[[package]] -name = "futures-task" -version = "0.3.16" +name = "derive_arbitrary" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "futures-util" -version = "0.3.16" +name = "either" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" -dependencies = [ - "autocfg", - "futures-core", - "futures-sink", - "futures-task", - "pin-project-lite", - "pin-utils", -] +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", - "wasm-bindgen", ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "jobserver" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.51" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" -version = "0.2.98" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libfuzzer-sys" -version = "0.4.2" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a9a84a6e8b55dfefb04235e55edb2b9a2a18488fcae777a6bdaa6f06f1deb3" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" dependencies = [ "arbitrary", "cc", @@ -194,119 +161,64 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.1" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "log" -version = "0.4.14" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "mop" -version = "0.5.0" -dependencies = [ - "mop-blocks", - "mop-facades", - "mop-solvers", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] -name = "mop-bindings" -version = "0.0.0" +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ - "arrayvec", - "getrandom", - "js-sys", - "mop", - "rand", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", + "autocfg", ] [[package]] -name = "mop-blocks" +name = "mop" version = "0.5.0" dependencies = [ "arrayvec", - "cl-traits", - "futures", - "mop-common", - "ndsparse", + "cl-aux", + "js-sys", + "ndstruct", + "num-integer", "num-traits", "rand", + "rayon", "serde", + "wasm-bindgen", + "wasm-bindgen-test", ] [[package]] -name = "mop-blocks-fuzz" +name = "mop-fuzz" version = "0.0.0" dependencies = [ "arbitrary", "libfuzzer-sys", - "mop-blocks", -] - -[[package]] -name = "mop-common" -version = "0.5.0" - -[[package]] -name = "mop-facades" -version = "0.5.0" -dependencies = [ - "cl-traits", - "mop-blocks", - "mop-common", - "num-traits", -] - -[[package]] -name = "mop-problems" -version = "0.0.0" -dependencies = [ - "arrayvec", - "cl-traits", "mop", - "ndsparse", - "plotters", - "rand", - "tokio", ] [[package]] -name = "mop-solvers" -version = "0.5.0" -dependencies = [ - "cl-traits", - "mop-blocks", - "mop-common", - "num-integer", - "num-traits", - "rand", -] - -[[package]] -name = "ndsparse" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9090abf9048afdde1340664ed09cd46b03a15c59318021010d998f94a2d58724" +name = "ndstruct" +version = "1.0.0" dependencies = [ - "cl-traits", + "cl-aux", "rand", ] [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", @@ -314,126 +226,102 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", "libm", ] -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "pin-project-lite" -version = "0.2.7" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "plotters" -version = "0.3.1" +name = "proc-macro2" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", + "unicode-ident", ] [[package]] -name = "plotters-backend" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" - -[[package]] -name = "plotters-svg" -version = "0.3.1" +name = "quote" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ - "plotters-backend", + "proc-macro2", ] [[package]] -name = "proc-macro2" -version = "1.0.28" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "unicode-xid", + "rand_core", ] [[package]] -name = "quote" -version = "1.0.9" +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "proc-macro2", + "getrandom", ] [[package]] -name = "rand" -version = "0.8.4" +name = "rayon" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ - "rand_core", + "either", + "rayon-core", ] [[package]] -name = "rand_core" -version = "0.6.3" +name = "rayon-core" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "getrandom", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", @@ -442,57 +330,46 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.74" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] -name = "tokio" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c" -dependencies = [ - "autocfg", - "num_cpus", - "pin-project-lite", -] - -[[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.74" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.74" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -501,11 +378,11 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.24" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -513,9 +390,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.74" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -523,9 +400,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.74" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -536,15 +413,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.74" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-bindgen-test" -version = "0.3.24" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cab416a9b970464c2882ed92d55b0c33046b08e0bdc9d59b3b718acd4e1bae8" +checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" dependencies = [ "console_error_panic_hook", "js-sys", @@ -556,9 +433,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.24" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4543fc6cf3541ef0d98bf720104cc6bd856d7eba449fd2aa365ef4fed0e782" +checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" dependencies = [ "proc-macro2", "quote", @@ -566,9 +443,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.51" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index fd93f77..5a58af8 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,13 +11,7 @@ rpath = false [workspace] members = [ - "mop-bindings", - "mop-blocks", - "mop-blocks-fuzz", - "mop-common", - "mop-facades", - "mop-problems", - "mop-solvers", "mop", + "mop-fuzz", ] resolver = "2" \ No newline at end of file diff --git a/README.md b/README.md index a1853ad..761a01e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ MOP is a flexible and modular framework for different NP-Problems with different solvers. Through its default pipeline you can define your own custom problem and choose any supported solver combination. -See [this blog post](https://c410-f3r.github.io/posts/a-flexible-and-modular-framework-to-solve-np-problems) for more details or have fun using [the online playground](https://c410-f3r.github.io/mop-playground/). +See [this blog post](https://c410-f3r.github.io/thoughts/a-flexible-and-modular-framework-to-solve-np-problems/) for more details or have fun using [the online playground](https://c410-f3r.github.io/mop-playground/). ## Example @@ -78,8 +78,7 @@ fn print_result(result: MphOrRef) { println!(); } -#[tokio::main] // Or any other runtime -async fn main() -> Result<(), mop::blocks::Error> { +fn main() -> Result<(), mop::blocks::Error> { // Problem definitions and results let mut mph = MphVec::with_capacity( MphDefinitionsBuilder::default() @@ -121,10 +120,10 @@ async fn main() -> Result<(), mop::blocks::Error> { .set_quality_comparator(ObjsAvg) .set_stagnation(Pct::from_percent(2), 10)? .solve_problem_with(&mut mp_ref, spea2) - .await?; + ?; // Transfers all solutions and objectives results of `mp` to `mph`. - MphMpMph::transfer(&mph_defs, &mut mph_rslts, &mp_ref).await?; + MphMpMph::transfer(&mph_defs, &mut mph_rslts, &mp_ref)?; for (result_idx, result) in mph_rslts.iter().enumerate() { println!("***** Result #{} *****", result_idx + 1); @@ -159,6 +158,6 @@ async fn main() -> Result<(), mop::blocks::Error> { - `std` - Bindings (wasm-bindgen) -- Concurrent evaluation (futures) +- Parallel evaluation (rayon) - Deserialization/Serialization (serde) -- Multidimensional storage (ndsparse) +- Multidimensional storage (ndstruct) diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..2b47d11 --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +type-complexity-threshold = 500 \ No newline at end of file diff --git a/mop-bindings/Cargo.toml b/mop-bindings/Cargo.toml deleted file mode 100644 index 10aead4..0000000 --- a/mop-bindings/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[dependencies] -arrayvec = { default-features = false, optional = true, version = "0.7" } -getrandom = { default-features = false, features = ["wasm-bindgen"], optional = true, version = "0.2" } -js-sys = { default-features = false, optional = true, version = "0.3" } -mop = { features = ["with-mop-solvers"], path = "../mop" } -rand = { default-features = false, optional = true, version = "0.8" } -wasm-bindgen = { default-features = false, features = ["std", "spans"], optional = true, version = "0.2" } -wasm-bindgen-futures = { default-features = false, optional = true, version = "0.4" } - -[dev-dependencies] -wasm-bindgen-test = "0.3" - -[lib] -crate-type = ["cdylib"] - -[features] -default = [] -with-futures = ["mop/with-futures"] -with-wasm_bindgen = ["arrayvec", "getrandom", "js-sys", "rand", "wasm-bindgen", "wasm-bindgen-futures"] - -[package] -edition = "2018" -name = "mop-bindings" -publish = false -version = "0.0.0" diff --git a/mop-bindings/src/lib.rs b/mop-bindings/src/lib.rs deleted file mode 100644 index 3b4435a..0000000 --- a/mop-bindings/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[cfg(all(not(feature = "with-futures"), feature = "with-wasm_bindgen"))] -mod wasm_bindgen; diff --git a/mop-blocks-fuzz/.gitignore b/mop-blocks-fuzz/.gitignore deleted file mode 100644 index 572e03b..0000000 --- a/mop-blocks-fuzz/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ - -target -corpus -artifacts diff --git a/mop-blocks/Cargo.toml b/mop-blocks/Cargo.toml deleted file mode 100644 index 9bec2cc..0000000 --- a/mop-blocks/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[dependencies] -arrayvec = { default-features = false, version = "0.7" } -cl-traits = { default-features = false, features = ["alloc", "with-arrayvec"], version = "6.0" } -futures = { default-features = false, features = ["alloc"], optional = true, version = "0.3" } -mop-common = { default-features = false, path = "../mop-common", version = "0.5.0" } -ndsparse = { default-features = false, features = ["with-rand"], optional = true, version = "0.8" } -num-traits = { default-features = false, features = ["libm"], version = "0.2" } -rand = { default-features = false, features = ["getrandom"], optional = true, version = "0.8" } -serde = { default-features = false, features = ["derive"], optional = true, version = "1.0" } - -[features] -default = [] -std = ["cl-traits/std"] -with-futures = ["futures", "mop-common/with-futures"] -with-ndsparse = ["ndsparse"] -with-rand = ["rand"] -with-serde = ["serde"] - -[package] -authors = ["Caio Fernandes "] -description = "Foundation blocks for MOP" -edition = "2018" -keywords = ["mop"] -license = "Apache-2.0" -name = "mop-blocks" -readme = "README.md" -repository = "https://github.com/c410-f3r/mop" -version = "0.5.0" diff --git a/mop-blocks/LICENSE b/mop-blocks/LICENSE deleted file mode 100644 index ae9ecd4..0000000 --- a/mop-blocks/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Caio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/mop-blocks/README.md b/mop-blocks/README.md deleted file mode 100644 index df03c28..0000000 --- a/mop-blocks/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# MOP - Blocks - -Generic foundation blocks intended to construct any type of solver. \ No newline at end of file diff --git a/mop-blocks/src/gp/gp_operations.rs b/mop-blocks/src/gp/gp_operations.rs deleted file mode 100644 index 6b39841..0000000 --- a/mop-blocks/src/gp/gp_operations.rs +++ /dev/null @@ -1,43 +0,0 @@ -pub(crate) mod mph_mp_mph; -pub(crate) mod mphs_mp_mphs; - -use crate::{ - gp::{GpDefinitions, MpDefinitionsBuilder}, - Obj, -}; -use cl_traits::{Push, Storage}; -use mop_common::SolverFuture; - -pub trait GpOperations { - type Error; - - fn convert(a: &AD) -> Result; - fn transfer<'a>(a_defs: &'a AD, a_rslts: &'a mut AR, b: &'a B) -> SolverFuture<'a, Self::Error>; -} - -#[inline] -pub fn mp_defs_from_gp_defs<'a, D, HCS, NOS, O, OR, OS, S, SCS>( - defs: &'a GpDefinitions, -) -> crate::Result> -where - D: Clone, - NOS: Default + Push> + Storage>, - O: Obj + 'a, - OR: 'a, - OS: AsRef<[O]> + Storage, - S: 'a, -{ - Ok(MpDefinitionsBuilder { - domain: Some(defs.domain.clone()), - hard_cstrs: Some(Default::default()), - soft_cstrs: Some(Default::default()), - name: defs.name, - objs: { - let mut objs: NOS = Default::default(); - for obj in defs.objs() { - let _ = objs.push(obj).map_err(|_e| crate::Error::InsufficientCapacity)?; - } - Some(objs) - }, - }) -} diff --git a/mop-blocks/src/gp/gp_operations/mph_mp_mph.rs b/mop-blocks/src/gp/gp_operations/mph_mp_mph.rs deleted file mode 100644 index 4b6249d..0000000 --- a/mop-blocks/src/gp/gp_operations/mph_mp_mph.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::{ - gp::{GpOperations, GpOrsEvaluators, Mp, MphDefinitions, MphOrs}, - Cstr, -}; -use cl_traits::{Length, Push, Storage}; -use mop_common::{SolverFuture, TraitCfg}; - -/// Mph -> Mp -> Mph -#[derive(Debug)] -pub struct MphMpMph; - -impl - GpOperations, MphOrs, Mp> - for MphMpMph -where - AORS: AsMut<[OR]> + Extend + Length + Storage + TraitCfg, - AOS: TraitCfg, - ASS: AsMut<[S]> + Push + Storage + TraitCfg, - BORS: AsRef<[OR]> + Length + Storage + TraitCfg, - BOS: TraitCfg, - D: TraitCfg, - HC: Cstr + TraitCfg, - HCRS: AsMut<[usize]> + Extend + Length + Storage + TraitCfg, - HCS: AsRef<[HC]> + Storage + TraitCfg, - OR: Clone + Default + TraitCfg, - S: Clone + TraitCfg, - SS: AsRef<[S]> + Storage + TraitCfg, -{ - type Error = crate::Error; - - #[inline] - fn convert(_: &MphDefinitions) -> Result, Self::Error> { - Err(Self::Error::UnsupportedConversion) - } - - #[inline] - fn transfer<'a>( - a_defs: &'a MphDefinitions, - a_rslts: &'a mut MphOrs, - b: &'a Mp, - ) -> SolverFuture<'a, Self::Error> { - alloc::boxed::Box::pin(async move { - let mut c = a_rslts.constructor(); - for rslt in b.rslts().iter() { - let ori = rslt.obj_rslts().iter().cloned().rev().skip(1).rev(); - let s = (*rslt.solution()).clone(); - let _ = c.or_os_iter(ori, s); - } - GpOrsEvaluators::eval_hard_cstrs_violations(a_defs, a_rslts).await; - Ok(()) - }) - } -} diff --git a/mop-blocks/src/gp/gp_operations/mphs_mp_mphs.rs b/mop-blocks/src/gp/gp_operations/mphs_mp_mphs.rs deleted file mode 100644 index 409a3f4..0000000 --- a/mop-blocks/src/gp/gp_operations/mphs_mp_mphs.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::{ - gp::{GpOperations, GpOrsEvaluators, Mp, MphsDefinitions, MphsOrs}, - Cstr, -}; -use cl_traits::{Length, Push, Storage}; -use mop_common::{SolverFuture, TraitCfg}; - -/// Mphs -> Mp -> Mphs -#[derive(Debug)] -pub struct MphsMpMphs; - -impl - GpOperations< - MphsDefinitions, - MphsOrs, - Mp, - > for MphsMpMphs -where - AORS: AsMut<[OR]> + Extend + Length + Storage + TraitCfg, - AOS: TraitCfg, - ASS: AsMut<[S]> + Push + Storage + TraitCfg, - BORS: AsRef<[OR]> + Length + Storage + TraitCfg, - BOS: TraitCfg, - D: TraitCfg, - HC: Cstr + TraitCfg, - HCRS: AsMut<[usize]> + Extend + Length + Storage + TraitCfg, - HCS: AsRef<[HC]> + Storage + TraitCfg, - OR: Clone + Default + TraitCfg, - S: Clone + TraitCfg, - SCRS: AsMut<[usize]> + Extend + Length + Storage + TraitCfg, - SCS: AsRef<[HC]> + Storage + TraitCfg, - SS: AsRef<[S]> + Storage + TraitCfg, -{ - type Error = crate::Error; - - #[inline] - fn convert(_: &MphsDefinitions) -> Result, Self::Error> { - Err(Self::Error::UnsupportedConversion) - } - - #[inline] - fn transfer<'a>( - a_defs: &'a MphsDefinitions, - a_rslts: &'a mut MphsOrs, - b: &'a Mp, - ) -> SolverFuture<'a, Self::Error> { - alloc::boxed::Box::pin(async move { - let mut c = a_rslts.constructor(); - for rslt in b.rslts().iter() { - let ori = rslt.obj_rslts().iter().cloned().rev().skip(1).rev(); - let s = (*rslt.solution()).clone(); - let _ = c.or_os_iter(ori, s); - } - GpOrsEvaluators::eval_hard_cstrs_violations(a_defs, a_rslts).await; - GpOrsEvaluators::eval_soft_cstrs_violations(a_defs, a_rslts).await; - Ok(()) - }) - } -} diff --git a/mop-blocks/src/gp/gp_ors_evaluators.rs b/mop-blocks/src/gp/gp_ors_evaluators.rs deleted file mode 100644 index 97fdbe7..0000000 --- a/mop-blocks/src/gp/gp_ors_evaluators.rs +++ /dev/null @@ -1,178 +0,0 @@ -use crate::{ - dr_matrix::DrMatrixVec, - gp::{GpDefinitions, GpOrMut, GpOrRef, GpOrs}, - Cstr, Obj, -}; -use alloc::string::String; -use cl_traits::Storage; -use core::{fmt::Debug, marker::PhantomData}; -#[cfg(feature = "with-futures")] -use futures::stream::{self, StreamExt}; -use mop_common::TraitCfg; - -#[derive(Debug)] -pub struct GpOrsEvaluators { - phantom: PhantomData<(D, HCRS, HCS, ORS, OS, SCRS, SCS, SS)>, -} - -impl - GpOrsEvaluators -where - ORS: AsMut<[OR]> + Storage, - SS: AsMut<[S]> + Storage, -{ - #[inline] - pub async fn eval_hard_cstrs_violations( - defs: &GpDefinitions, - rslts: &mut GpOrs, - ) where - HC: Cstr, - HCRS: AsMut<[usize]> + Storage, - HCS: AsRef<[HC]> + Storage, - SCRS: AsMut<[SCR]> + Storage, - { - let hard_cstrs = defs.hard_cstrs(); - Self::eval_cstrs_rslts(hard_cstrs, rslts, |rslt| (rslt.hard_cstr_rslts, rslt.solution)).await; - } - - #[inline] - pub async fn eval_soft_cstrs_violations( - defs: &GpDefinitions, - rslts: &mut GpOrs, - ) where - HCRS: AsMut<[HCR]> + Storage, - SC: Cstr, - SCRS: AsMut<[usize]> + Storage, - SCS: AsRef<[SC]> + Storage, - { - let soft_cstrs = defs.soft_cstrs(); - Self::eval_cstrs_rslts(soft_cstrs, rslts, |rslt| (rslt.soft_cstr_rslts, rslt.solution)).await; - } - - #[inline] - async fn eval_cstrs_rslts( - cstrs: &[C], - rslts: &mut GpOrs, - cb: F, - ) where - C: Cstr, - F: Fn(GpOrMut<'_, HCR, OR, S, SCR>) -> (&mut [usize], &S), - HCRS: AsMut<[HCR]> + Storage, - SCRS: AsMut<[SCR]> + Storage, - { - let func = |rslt| { - let (hard_cstr_rslts, solution) = cb(rslt); - for (hard_cstr, hard_cstr_rslt) in cstrs.iter().zip(hard_cstr_rslts.iter_mut()) { - *hard_cstr_rslt = hard_cstr.violations(solution); - } - }; - #[cfg(not(feature = "with-futures"))] - rslts.iter_mut().for_each(func); - #[cfg(feature = "with-futures")] - stream::iter(rslts.iter_mut()) - .for_each_concurrent(None, |rslt| async { - func(rslt); - }) - .await; - } -} - -impl - GpOrsEvaluators -where - HCRS: AsRef<[HCR]> + Storage, - ORS: AsRef<[OR]> + Storage, - SCRS: AsRef<[SCR]> + Storage, - SS: AsRef<[S]> + Storage, -{ - #[inline] - pub async fn eval_hard_cstrs_reasons( - defs: &GpDefinitions, - rslts: &mut GpOrs, - ) -> DrMatrixVec - where - HC: Cstr, - HCS: AsRef<[HC]> + Storage, - { - let cols = rslts.hard_cstr_rslts.cols(); - let rows = rslts.hard_cstr_rslts.rows(); - Self::eval_cstrs_reasons([rows, cols], defs.hard_cstrs(), rslts).await - } - - #[inline] - pub async fn eval_soft_cstrs_reasons( - defs: &GpDefinitions, - rslts: &mut GpOrs, - ) -> DrMatrixVec - where - SC: Cstr, - SCS: AsRef<[SC]> + Storage, - { - let cols = rslts.soft_cstr_rslts.cols(); - let rows = rslts.soft_cstr_rslts.rows(); - Self::eval_cstrs_reasons([rows, cols], defs.soft_cstrs(), rslts).await - } - - #[inline] - async fn eval_cstrs_reasons( - [rows, cols]: [usize; 2], - cstrs: &[C], - rslts: &mut GpOrs, - ) -> DrMatrixVec - where - C: Cstr, - { - let mut reasons = DrMatrixVec::with_capacity(rows, cols); - let _ = reasons.constructor().fill_rows(rows, String::with_capacity(256)); - let iter = reasons.row_iter_mut().zip(rslts.iter()); - let func = |(reasons, rslt): (&mut [String], GpOrRef<'_, _, _, _, _>)| { - for (c, r) in cstrs.iter().zip(reasons.iter_mut()) { - *r = c.reasons(rslt.solution); - } - }; - #[cfg(not(feature = "with-futures"))] - iter.for_each(func); - #[cfg(feature = "with-futures")] - stream::iter(iter) - .for_each_concurrent(None, |(reasons, rslt)| async move { - func((reasons, rslt)); - }) - .await; - reasons - } -} - -impl - GpOrsEvaluators -where - HCRS: AsMut<[HCR]> + Storage, - O: Obj + TraitCfg, - ORS: AsMut<[OR]> + Storage, - OS: AsRef<[O]> + Storage, - SCRS: AsMut<[SCR]> + Storage, - SS: AsMut<[S]> + Storage, -{ - #[inline] - pub async fn eval_objs( - defs: &GpDefinitions, - rslts: &mut GpOrs, - ) { - let func = |r| Self::eval_objs_for_solution(defs.objs(), r); - #[cfg(not(feature = "with-futures"))] - rslts.iter_mut().for_each(func); - #[cfg(feature = "with-futures")] - stream::iter(rslts.iter_mut()) - .for_each_concurrent(None, |r| async { - func(r); - }) - .await; - } - - #[inline] - fn eval_objs_for_solution(objs: &[O], rslt: GpOrMut<'_, HCR, OR, S, SCR>) { - for (obj, obj_rslts) in objs.iter().zip(rslt.obj_rslts.iter_mut()) { - let rslt = obj.result(rslt.solution); - *obj_rslts = rslt; - } - } -} diff --git a/mop-blocks/src/lib.rs b/mop-blocks/src/lib.rs deleted file mode 100644 index dc31f09..0000000 --- a/mop-blocks/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Mop (Many Optimizations) - -#![cfg_attr(not(feature = "std"), no_std)] - -extern crate alloc; - -mod criteria; -pub mod doc_tests; -mod domain; -pub mod dr_matrix; -mod error; -pub mod gp; -mod obj_direction; -pub mod objs; -mod pct; -pub mod quality_comparator; -mod solution; -pub mod utils; - -pub use crate::{ - criteria::{cstr::*, obj::*}, - domain::*, - error::*, - obj_direction::*, - pct::*, - solution::*, -}; - -pub type Result = core::result::Result; diff --git a/mop-blocks/src/objs.rs b/mop-blocks/src/objs.rs deleted file mode 100644 index 821ecb8..0000000 --- a/mop-blocks/src/objs.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod min_cstrs_rslts; -mod min_weighted_sum; - -pub use {min_cstrs_rslts::*, min_weighted_sum::*}; diff --git a/mop-common/Cargo.toml b/mop-common/Cargo.toml deleted file mode 100644 index d4263f0..0000000 --- a/mop-common/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[features] -default = [] -with-futures = [] - -[package] -authors = ["Caio Fernandes "] -description = "Common definitions for MOP crates." -edition = "2018" -keywords = ["mop"] -license = "Apache-2.0" -name = "mop-common" -readme = "README.md" -repository = "https://github.com/c410-f3r/mop" -version = "0.5.0" \ No newline at end of file diff --git a/mop-common/LICENSE b/mop-common/LICENSE deleted file mode 100644 index ae9ecd4..0000000 --- a/mop-common/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Caio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/mop-common/README.md b/mop-common/README.md deleted file mode 100644 index d58d6b4..0000000 --- a/mop-common/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# MOP - Common - -Common definitions for MOP crates. \ No newline at end of file diff --git a/mop-common/src/lib.rs b/mop-common/src/lib.rs deleted file mode 100644 index b3e4f57..0000000 --- a/mop-common/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! MOP - Commons - -#![no_std] - -extern crate alloc; - -mod solver; -mod trait_cfg; - -pub use crate::{solver::*, trait_cfg::*}; diff --git a/mop-common/src/solver.rs b/mop-common/src/solver.rs deleted file mode 100644 index d8fa159..0000000 --- a/mop-common/src/solver.rs +++ /dev/null @@ -1,30 +0,0 @@ -use alloc::boxed::Box; -use core::{future::Future, pin::Pin}; - -/// Result of a solver operation -#[cfg(not(feature = "with-futures"))] -pub type SolverFuture<'a, E> = Pin> + 'a>>; - -/// Result of a solver operation -#[cfg(feature = "with-futures")] -pub type SolverFuture<'a, E> = Pin> + Send + Sync + 'a>>; - -/// Solver -pub trait Solver

{ - /// Error - type Error; - - /// Do solving work after stoping criteria verification. - fn after_iter<'a>(&'a mut self, p: &'a mut P) -> SolverFuture<'a, Self::Error>; - - /// Do solving work before stoping criteria verification. - fn before_iter<'a>(&'a mut self, p: &'a mut P) -> SolverFuture<'a, Self::Error>; - - /// Verifies or modifies `P` when solving was completed - #[inline] - fn finished(&mut self, _: &mut P) {} - - /// Verifies or modifies `P` when solving is starting - #[inline] - fn init(&mut self, _: &mut P) {} -} diff --git a/mop-common/src/trait_cfg.rs b/mop-common/src/trait_cfg.rs deleted file mode 100644 index cb1205f..0000000 --- a/mop-common/src/trait_cfg.rs +++ /dev/null @@ -1,11 +0,0 @@ -/// Trait configuration -#[cfg(not(feature = "with-futures"))] -pub trait TraitCfg {} -#[cfg(not(feature = "with-futures"))] -impl TraitCfg for T {} - -/// Trait configuration -#[cfg(feature = "with-futures")] -pub trait TraitCfg: Send + Sync {} -#[cfg(feature = "with-futures")] -impl TraitCfg for T where T: Send + Sync {} diff --git a/mop-facades/Cargo.toml b/mop-facades/Cargo.toml deleted file mode 100644 index ccc87a2..0000000 --- a/mop-facades/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[dependencies] -cl-traits = { default-features = false, version = "6.0" } -mop-blocks = { default-features = false, features = ["with-rand"], path = "../mop-blocks", version = "0.5.0" } -mop-common = { default-features = false, path = "../mop-common", version = "0.5.0" } -num-traits = { default-features = false, features = ["libm"], version = "0.2" } - -[features] -default = [] -std = [] - -[package] -authors = ["Caio Fernandes "] -description = "Facades for MOP" -edition = "2018" -keywords = ["mop"] -license = "Apache-2.0" -name = "mop-facades" -readme = "README.md" -repository = "https://github.com/c410-f3r/mop" -version = "0.5.0" \ No newline at end of file diff --git a/mop-facades/LICENSE b/mop-facades/LICENSE deleted file mode 100644 index ae9ecd4..0000000 --- a/mop-facades/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Caio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/mop-facades/README.md b/mop-facades/README.md deleted file mode 100644 index a2609b2..0000000 --- a/mop-facades/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# MOP - Facades - -Defines common interfaces to link together several types of solvers. \ No newline at end of file diff --git a/mop-facades/src/lib.rs b/mop-facades/src/lib.rs deleted file mode 100644 index 36d3bc9..0000000 --- a/mop-facades/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -extern crate alloc; - -pub mod opt; diff --git a/mop-blocks-fuzz/Cargo.toml b/mop-fuzz/Cargo.toml similarity index 74% rename from mop-blocks-fuzz/Cargo.toml rename to mop-fuzz/Cargo.toml index 839efa1..b953a97 100644 --- a/mop-blocks-fuzz/Cargo.toml +++ b/mop-fuzz/Cargo.toml @@ -9,13 +9,13 @@ path = "gp.rs" [dependencies] arbitrary = { default-features = false, features = ["derive"], version = "1.0" } libfuzzer-sys = { default-features = false, version = "0.4" } -mop-blocks = { default-features = false, features = ["with-rand"], path = "../mop-blocks" } +mop = { default-features = false, features = ["rand"], path = "../mop" } [package] authors = ["Automatically generated"] -edition = "2018" +edition = "2021" license = "Apache-2.0" -name = "mop-blocks-fuzz" +name = "mop-fuzz" publish = false version = "0.0.0" diff --git a/mop-blocks-fuzz/dr_matrix.rs b/mop-fuzz/dr_matrix.rs similarity index 96% rename from mop-blocks-fuzz/dr_matrix.rs rename to mop-fuzz/dr_matrix.rs index d618cd6..8732def 100644 --- a/mop-blocks-fuzz/dr_matrix.rs +++ b/mop-fuzz/dr_matrix.rs @@ -1,7 +1,7 @@ #![no_main] use libfuzzer_sys::fuzz_target; -use mop_blocks::dr_matrix::DrMatrixVec; +use mop::dr_matrix::DrMatrixVec; #[derive(Debug, arbitrary::Arbitrary)] struct Data { diff --git a/mop-blocks-fuzz/gp.rs b/mop-fuzz/gp.rs similarity index 97% rename from mop-blocks-fuzz/gp.rs rename to mop-fuzz/gp.rs index a5155f5..7cca0c7 100644 --- a/mop-blocks-fuzz/gp.rs +++ b/mop-fuzz/gp.rs @@ -2,7 +2,7 @@ use core::ops::RangeInclusive; use libfuzzer_sys::fuzz_target; -use mop_blocks::{ +use mop::{ gp::{MpDefinitionsBuilderVec, MpVec}, ObjDirection, }; diff --git a/mop-problems/Cargo.lock b/mop-problems/Cargo.lock deleted file mode 100644 index 1e2e683..0000000 --- a/mop-problems/Cargo.lock +++ /dev/null @@ -1,491 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "bumpalo" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" - -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cl-traits" -version = "4.1.0" -source = "git+https://github.com/c410-f3r/cl-traits#3f042d57ae65f01ddb200d290969cef85588d5d3" -dependencies = [ - "arrayvec", -] - -[[package]] -name = "futures" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8e3078b7b2a8a671cb7a3d17b4760e4181ea243227776ba83fd043b4ca034e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a4d35f7401e948629c9c3d6638fb9bf94e0b2121e96c3b428cc4e631f3eb74" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d674eaa0056896d5ada519900dbf97ead2e46a7b6621e8160d79e2f2e1e2784b" - -[[package]] -name = "futures-io" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc94b64bb39543b4e432f1790b6bf18e3ee3b74653c5449f63310e9a74b123c" - -[[package]] -name = "futures-sink" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8764258ed64ebc5d9ed185cf86a95db5cac810269c5d20ececb32e0088abbd" - -[[package]] -name = "futures-task" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd26820a9f3637f1302da8bceba3ff33adbe53464b54ca24d4e2d4f1db30f94" - -[[package]] -name = "futures-util" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a894a0acddba51a2d49a6f4263b1e64b8c579ece8af50fa86503d52cd1eea34" -dependencies = [ - "futures-core", - "futures-sink", - "futures-task", - "pin-project", - "pin-utils", -] - -[[package]] -name = "getrandom" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "hermit-abi" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" - -[[package]] -name = "libm" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" - -[[package]] -name = "log" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "mop" -version = "0.5.0" -dependencies = [ - "mop-blocks", - "mop-facades", - "mop-solvers", -] - -[[package]] -name = "mop-blocks" -version = "0.5.0" -dependencies = [ - "arrayvec", - "cl-traits", - "futures", - "mop-common", - "ndsparse", - "num-traits", - "rand", -] - -[[package]] -name = "mop-common" -version = "0.5.0" - -[[package]] -name = "mop-facades" -version = "0.5.0" -dependencies = [ - "cl-traits", - "mop-blocks", - "mop-common", - "num-traits", - "rand", -] - -[[package]] -name = "mop-problems" -version = "0.0.0" -dependencies = [ - "arrayvec", - "cl-traits", - "mop", - "ndsparse", - "plotters", - "rand", - "tokio", -] - -[[package]] -name = "mop-solvers" -version = "0.5.0" -dependencies = [ - "cl-traits", - "mop-blocks", - "mop-common", - "num-integer", - "num-traits", - "rand", -] - -[[package]] -name = "ndsparse" -version = "0.7.3" -source = "git+https://github.com/c410-f3r/ndsparse#dc2b66c1f3becff131230dda9798c905c7870972" -dependencies = [ - "cl-traits", - "rand", -] - -[[package]] -name = "num-integer" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "pin-project" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e555d9e657502182ac97b539fb3dae8b79cda19e3e4f8ffb5e8de4f18df93c95" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "plotters" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" - -[[package]] -name = "plotters-svg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" - -[[package]] -name = "proc-macro2" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "syn" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "tokio" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" -dependencies = [ - "bytes", - "num_cpus", - "pin-project-lite", - "tokio-macros", -] - -[[package]] -name = "tokio-macros" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasm-bindgen" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" - -[[package]] -name = "web-sys" -version = "0.3.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d" -dependencies = [ - "js-sys", - "wasm-bindgen", -] diff --git a/mop-problems/Cargo.toml b/mop-problems/Cargo.toml deleted file mode 100644 index 50f35ea..0000000 --- a/mop-problems/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[[bin]] -name = "mop_problems" -path = "src/main.rs" - -[dependencies] -arrayvec = { default-features = false, version = "0.7" } -cl-traits = { default-features = false, version = "6.0" } -mop = { features = ["std", "with-futures", "with-mop-solvers", "with-ndsparse"], path = "../mop" } -ndsparse = { default-features = false, version = "0.8" } -plotters = { default-features = false, features = ["svg_backend"], optional = true, version = "0.3" } -rand = { default-features = false, features = ["getrandom"], version = "0.8" } -tokio = { default-features = false, features = ["rt-multi-thread"], version = "1.0" } - -[features] -binh-and-korn = [] -constr = [] -cvrp = [] -default = [] -rastrigin = [] -schaffer-function-2 = [] -test-function-4 = [] -with-plotters = ["plotters"] - -[lib] -name = "mop_problems" -path = "src/lib.rs" - -[package] -edition = "2018" -name = "mop-problems" -publish = false -version = "0.0.0" diff --git a/mop-problems/src/cvrp.rs b/mop-problems/src/cvrp.rs deleted file mode 100644 index 42aeba1..0000000 --- a/mop-problems/src/cvrp.rs +++ /dev/null @@ -1,216 +0,0 @@ -//! http://vrp.galgos.inf.puc-rio.br/index.php/en/plotted-instances?data=B-n31-k5 - -use crate::Problem; -use core::ops::{Range, RangeInclusive}; -use mop::blocks::{Cstr, Obj, ObjDirection}; - -pub type CslArrayVec = - ndsparse::csl::Csl< - arrayvec::ArrayVec, - arrayvec::ArrayVec, - arrayvec::ArrayVec, - D, - >; - -const DATA: Data = Data { - capacity: 100, - depot: Node { demand: 0, id: 1, x: 17.0, y: 76.0 }, - max_routes: 10, - max_stops: 10, - places: [ - Node { demand: 25, id: 2, x: 24.0, y: 6.0 }, - Node { demand: 3, id: 3, x: 96.0, y: 29.0 }, - Node { demand: 13, id: 4, x: 14.0, y: 19.0 }, - Node { demand: 17, id: 5, x: 14.0, y: 32.0 }, - Node { demand: 16, id: 6, x: 0.0, y: 34.0 }, - Node { demand: 9, id: 7, x: 16.0, y: 22.0 }, - Node { demand: 22, id: 8, x: 20.0, y: 26.0 }, - Node { demand: 10, id: 9, x: 22.0, y: 28.0 }, - Node { demand: 16, id: 10, x: 17.0, y: 23.0 }, - Node { demand: 8, id: 11, x: 98.0, y: 30.0 }, - Node { demand: 3, id: 12, x: 30.0, y: 8.0 }, - Node { demand: 16, id: 13, x: 23.0, y: 27.0 }, - Node { demand: 16, id: 14, x: 19.0, y: 23.0 }, - Node { demand: 10, id: 15, x: 34.0, y: 7.0 }, - Node { demand: 24, id: 16, x: 31.0, y: 7.0 }, - Node { demand: 16, id: 17, x: 0.0, y: 37.0 }, - Node { demand: 15, id: 18, x: 19.0, y: 23.0 }, - Node { demand: 14, id: 19, x: 0.0, y: 36.0 }, - Node { demand: 5, id: 20, x: 26.0, y: 7.0 }, - Node { demand: 12, id: 21, x: 98.0, y: 32.0 }, - Node { demand: 2, id: 22, x: 5.0, y: 40.0 }, - Node { demand: 18, id: 23, x: 17.0, y: 26.0 }, - Node { demand: 20, id: 24, x: 21.0, y: 26.0 }, - Node { demand: 15, id: 25, x: 28.0, y: 8.0 }, - Node { demand: 8, id: 26, x: 1.0, y: 35.0 }, - Node { demand: 22, id: 27, x: 27.0, y: 28.0 }, - Node { demand: 15, id: 28, x: 99.0, y: 30.0 }, - Node { demand: 10, id: 29, x: 26.0, y: 28.0 }, - Node { demand: 13, id: 30, x: 17.0, y: 29.0 }, - Node { demand: 19, id: 31, x: 20.0, y: 26.0 }, - ], -}; - -type Domain = [RangeInclusive; 30]; -// A 2-D sparse structure or a sparse matrix or a graph storage -type Solution = CslArrayVec; - -#[derive(Debug)] -pub struct Data { - capacity: usize, - depot: Node, - max_routes: usize, - max_stops: usize, - places: [Node; 30], -} - -#[derive(Debug)] -pub struct Node { - demand: usize, - id: usize, - x: f64, - y: f64, -} - -#[derive(Debug)] -pub struct RouteCapacityMustNotExceedTruckCapacity { - pub data: &'static Data, -} - -impl RouteCapacityMustNotExceedTruckCapacity { - fn func(&self, solution: &Solution, mut cb: F) - where - F: FnMut(usize, usize), - { - #[allow( - // Dimension is greater than 0 - clippy::unwrap_used - )] - for (route_idx, route) in solution.outermost_line_iter().unwrap().enumerate() { - let mut route_capacity = 0; - for place_idx in route.data().iter().copied() { - route_capacity += DATA.places[place_idx].demand; - } - if route_capacity > DATA.capacity { - cb(route_idx, route_capacity - DATA.capacity); - } - } - } -} - -impl Cstr for RouteCapacityMustNotExceedTruckCapacity { - #[inline] - fn reasons(&self, solution: &Solution) -> String { - let mut reasons = String::new(); - self.func(solution, |route_idx, surplus| { - reasons.push_str(&format!( - "Route #{} extrapolates truck capacity by {}\n", - route_idx + 1, - surplus - )); - }); - reasons - } - - #[inline] - fn violations(&self, solution: &Solution) -> usize { - let mut ret = 0; - self.func(solution, |_, _| ret += 1); - ret - } -} - -#[derive(Clone, Debug)] -pub struct MinCost { - pub data: &'static Data, -} - -impl MinCost { - fn euclidian_distance(x1: f64, y1: f64, x2: f64, y2: f64) -> f64 { - ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt() - } -} - -impl Obj for MinCost { - #[inline] - fn obj_direction(&self) -> ObjDirection { - ObjDirection::Min - } - - #[inline] - fn result(&self, solution: &Solution) -> f64 { - let mut cost = 0.0; - #[allow( - // Dimension is greater than 0 - clippy::unwrap_used - )] - for route in solution.outermost_line_iter().unwrap() { - let mut last_place = &DATA.depot; - for place_idx in route.data().iter().copied() { - let distance = Self::euclidian_distance( - last_place.x, - last_place.y, - DATA.places[place_idx].x, - DATA.places[place_idx].y, - ); - cost += distance; - last_place = &DATA.places[place_idx]; - } - } - cost - } -} - -#[derive(Debug)] -pub struct Cvrp; - -impl Problem for Cvrp { - const GRAPH_RANGES: [Range; 2] = [-3.0..13.0, -8.0..-4.0]; - const NAME: &'static str = "CVRP"; - - #[inline] - fn domain() -> Domain { - [ - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - 45..=45, - ] - } - - #[inline] - fn hcs<'a>() -> [&'a (dyn Cstr + Send + Sync); 1] { - [&RouteCapacityMustNotExceedTruckCapacity { data: &DATA }] - } - - #[inline] - fn objs<'a>() -> [&'a (dyn Obj + Send + Sync); 1] { - [&MinCost { data: &DATA }] - } -} diff --git a/mop-problems/src/lib.rs b/mop-problems/src/lib.rs deleted file mode 100644 index 177a2d1..0000000 --- a/mop-problems/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![allow( - // Function pointers - clippy::as_conversions, - trivial_casts -)] - -pub mod binh_and_korn; -pub mod constr; -pub mod cvrp; -pub mod rastrigin; -pub mod schaffer_function_2; -pub mod test_function_4; - -use core::ops::Range; -use mop::blocks::{Cstr, Obj}; - -pub trait Problem { - const GRAPH_RANGES: [Range; 2]; - const NAME: &'static str; - - fn domain() -> D; - fn hcs<'a>() -> [&'a (dyn Cstr + Send + Sync); H]; - fn objs<'a>() -> [&'a (dyn Obj + Send + Sync); O]; -} diff --git a/mop-problems/src/main.rs b/mop-problems/src/main.rs deleted file mode 100644 index 877b71e..0000000 --- a/mop-problems/src/main.rs +++ /dev/null @@ -1,133 +0,0 @@ -//! Run any problem by typing `cargo run --features "with-plotters,ANY_SUPPORTED_PROBLEM" --release` - -#[cfg(feature = "with-plotters")] -use plotters::prelude::*; - -#[cfg(feature = "with-plotters")] -pub fn manage_plotting<'a, A, B, I, T>( - x: A, - y: B, - name: &str, - iter: I, -) -> Result<(), Box> -where - A: plotters::coord::ranged1d::AsRangedCoord, - ::CoordDescType: - plotters::coord::ranged1d::ValueFormatter, - B: plotters::coord::ranged1d::AsRangedCoord, - ::CoordDescType: - plotters::coord::ranged1d::ValueFormatter, - I: Iterator + 'a, - T: core::fmt::Debug + 'static, -{ - let mut file = std::env::temp_dir(); - file.push("mop"); - std::fs::create_dir_all(&file)?; - file.push(name); - - let root_area = SVGBackend::new(&file, (800, 600)).into_drawing_area(); - root_area.fill(&WHITE)?; - - let mut ctx = ChartBuilder::on(&root_area) - .set_label_area_size(LabelAreaPosition::Left, 40) - .set_label_area_size(LabelAreaPosition::Bottom, 40) - .caption(name, ("sans-serif", 40)) - .build_cartesian_2d(x, y)?; - - ctx.configure_mesh().draw()?; - - let data = iter.map(|p| TriangleMarker::new(p, 5, &BLUE)); - let _ = ctx.draw_series(data)?; - Ok(()) -} - -macro_rules! exec { - ($($feature:literal, $problem:ty)+) => { - #[cfg(any($(feature = $feature),+))] - use { - mop::{ - blocks::{ - gp::{mp_defs_from_gp_defs, GpOperations, MpVec, MphDefinitionsBuilder, MphMpMph, MphVec}, - objs::MinCstrsRslts, - quality_comparator::ObjsAvg, - Pct, - }, - facades::opt::OptFacade, - solvers::genetic_algorithm::{ - operators::{ - crossover::MultiPoint, mating_selection::Tournament, mutation::RandomDomainAssignments, - }, - GeneticAlgorithmParamsBuilder, Spea2, - }, - }, - mop_problems::Problem, - }; - - #[cfg(any($(feature = $feature),+))] - const RSLTS_NUM: usize = 250; - - $( - #[cfg(feature = $feature)] - { - let mut mph = MphVec::with_capacity( - MphDefinitionsBuilder::default() - .domain(<$problem>::domain()) - .hard_cstrs(<$problem>::hcs().to_vec()) - .name(<$problem>::NAME) - .objs(<$problem>::objs().to_vec()) - .build()?, - RSLTS_NUM, - ); - let (mph_defs, mut mph_rslts) = mph.parts_mut(); - - let mcr = MinCstrsRslts::from_gp_hcs(mph_defs); - let mp_defs_ref = mp_defs_from_gp_defs(mph_defs)?.push_obj((&mcr).into())?.build()?; - let mut mp_ref = MpVec::with_random_solutions(mp_defs_ref, 100)?; - - let spea2 = Spea2::new( - Pct::from_percent(50), - GeneticAlgorithmParamsBuilder::default() - .crossover(MultiPoint::new(1, Pct::from_percent(70))) - .mating_selection(Tournament::new(5, ObjsAvg)) - .mutation(RandomDomainAssignments::new(1, Pct::from_percent(30))) - .build()?, - &mp_ref, - RSLTS_NUM, - )?; - let _facade = OptFacade::new(2000) - .set_quality_comparator(ObjsAvg) - .set_opt_hooks(()) - .set_stagnation(Pct::from_percent(1), 30)? - .solve_problem_with(&mut mp_ref, spea2) - .await?; - - MphMpMph::transfer(&mph_defs, &mut mph_rslts, &mp_ref).await?; - - #[cfg(feature = "with-plotters")] - if <$problem>::hcs().len() == 2 { - let [x, y] = <$problem>::GRAPH_RANGES; - manage_plotting( - x, - y, - &format!("{} - Objectives", mph_defs.name()), - mph_rslts.iter().map(|r| (r.obj_rslts()[0], r.obj_rslts()[1])), - ).map_err(|_| mop::blocks::Error::Other("Bad plotting"))?; - } - } - )+ - }; -} - -fn main() -> Result<(), Box> { - tokio::runtime::Builder::new_multi_thread().enable_all().build()?.block_on(async { - exec!( - "binh-and-korn", mop_problems::binh_and_korn::BinhAndKorn - "constr", mop_problems::constr::Constr - "cvrp", mop_problems::cvrp::Cvrp - "rastrigin", mop_problems::rastrigin::Rastrigin - "schaffer-function-2", mop_problems::schaffer_function_2::SchafferFunction2 - "test-function-4", mop_problems::test_function_4::TestFunction4 - ); - Ok(()) - }) -} diff --git a/mop-solvers/Cargo.toml b/mop-solvers/Cargo.toml deleted file mode 100644 index 7782d4e..0000000 --- a/mop-solvers/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[dependencies] -cl-traits = { default-features = false, version = "6.0" } -mop-blocks = { default-features = false, features = ["with-rand"], path = "../mop-blocks", version = "0.5.0" } -mop-common = { default-features = false, path = "../mop-common", version = "0.5.0" } -num-integer = { default-features = false, version = "0.1" } -num-traits = { default-features = false, features = ["libm"], version = "0.2" } -rand = { default-features = false, features = ["getrandom"], version = "0.8" } - -[features] -default = [] -std = [] - -[package] -authors = ["Caio Fernandes "] -description = "Solvers for MOP" -edition = "2018" -keywords = ["mop"] -license = "Apache-2.0" -name = "mop-solvers" -readme = "README.md" -repository = "https://github.com/c410-f3r/mop" -version = "0.5.0" \ No newline at end of file diff --git a/mop-solvers/LICENSE b/mop-solvers/LICENSE deleted file mode 100644 index ae9ecd4..0000000 --- a/mop-solvers/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Caio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/mop-solvers/README.md b/mop-solvers/README.md deleted file mode 100644 index cdebc3e..0000000 --- a/mop-solvers/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# MOP - Solvers - -Official built-in solvers. \ No newline at end of file diff --git a/mop-solvers/src/genetic_algorithm.rs b/mop-solvers/src/genetic_algorithm.rs deleted file mode 100755 index fc73e49..0000000 --- a/mop-solvers/src/genetic_algorithm.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod genetic_algorithm_params; -mod genetic_algorithm_params_builder; -pub mod operators; -mod spea2; - -pub use { - genetic_algorithm_params::GeneticAlgorithmParams, - genetic_algorithm_params_builder::GeneticAlgorithmParamsBuilder, spea2::*, -}; diff --git a/mop/Cargo.toml b/mop/Cargo.toml index ddcab4b..210cebb 100644 --- a/mop/Cargo.toml +++ b/mop/Cargo.toml @@ -1,24 +1,31 @@ [dependencies] -mop-blocks = { default-features = false, features = ["with-rand"], path = "../mop-blocks", version = "0.5.0" } -mop-facades = { default-features = false, path = "../mop-facades", version = "0.5" } -mop-solvers = { default-features = false, optional = true, path = "../mop-solvers", version = "0.5.0" } +arrayvec = { default-features = false, version = "0.7" } +cl-aux = { default-features = false, features = ["alloc", "arrayvec"], path = "../../regular-crates/cl-aux" } +js-sys = { default-features = false, optional = true, version = "0.3" } +ndstruct = { default-features = false, features = ["rand"], optional = true, path = "../../regular-crates/ndstruct" } +num-integer = { default-features = false, optional = true, version = "0.1" } +num-traits = { default-features = false, features = ["libm"], version = "0.2" } +rand = { default-features = false, features = ["getrandom"], optional = true, version = "0.8" } +rayon = { default-features = false, optional = true, version = "1.0" } +serde = { default-features = false, features = ["derive"], optional = true, version = "1.0" } +wasm-bindgen = { default-features = false, features = ["std", "spans"], optional = true, version = "0.2" } + +[dev-dependencies] +wasm-bindgen-test = { default-features = false, version = "0.3" } [features] default = [] -std = ["mop-blocks/std", "mop-facades/std", "mop-solvers/std"] -with-futures = ["mop-blocks/with-futures"] -with-mop-solvers = ["mop-solvers"] -with-ndsparse = ["mop-blocks/with-ndsparse"] -with-serde = ["mop-blocks/with-serde"] +solvers = ["dep:num-integer", "rand"] +std = ["cl-aux/std"] +wasm-bindgen = ["dep:js-sys", "solvers", "dep:wasm-bindgen"] [package] authors = ["Caio Fernandes "] -categories = ["algorithms", "concurrency"] -description = "Flexible and modular single or multi-objective framework for contiguous and discrete problems" -edition = "2018" -keywords = ["solver", "performance", "metaheuristic", "optimization"] +description = "Foundation blocks for MOP" +edition = "2021" +keywords = ["mop"] license = "Apache-2.0" name = "mop" readme = "README.md" repository = "https://github.com/c410-f3r/mop" -version = "0.5.0" \ No newline at end of file +version = "0.5.0" diff --git a/mop-bindings/LICENSE b/mop/LICENSE similarity index 100% rename from mop-bindings/LICENSE rename to mop/LICENSE diff --git a/mop/README.md b/mop/README.md deleted file mode 120000 index 32d46ee..0000000 --- a/mop/README.md +++ /dev/null @@ -1 +0,0 @@ -../README.md \ No newline at end of file diff --git a/mop/README.md b/mop/README.md new file mode 100644 index 0000000..df03c28 --- /dev/null +++ b/mop/README.md @@ -0,0 +1,3 @@ +# MOP - Blocks + +Generic foundation blocks intended to construct any type of solver. \ No newline at end of file diff --git a/mop-problems/src/binh_and_korn.rs b/mop/examples/binh_and_korn.rs similarity index 74% rename from mop-problems/src/binh_and_korn.rs rename to mop/examples/binh_and_korn.rs index b1605a0..e423953 100644 --- a/mop-problems/src/binh_and_korn.rs +++ b/mop/examples/binh_and_korn.rs @@ -1,13 +1,13 @@ //! Binh and U. Korn; MOBES: A multiobjective evolution strategy for constrained optimization problems -use crate::Problem; +mod common; + +use common::Problem; use core::{ cmp::Ordering, ops::{Range, RangeInclusive}, }; -use mop::blocks::{ - ObjDirection, {Cstr, Obj}, -}; +use mop::ObjDirection; type Domain = [RangeInclusive; 2]; type Solution = [f64; 2]; @@ -43,21 +43,26 @@ impl Problem for BinhAndKorn { const GRAPH_RANGES: [Range; 2] = [0.0..140.0, 0.0..50.0]; const NAME: &'static str = "Binh and Korn"; + type Hcs = fn(&[f64; 2]) -> usize; + type Objs = (ObjDirection, fn(&[f64; 2]) -> f64); + #[inline] fn domain() -> Domain { [0.0..=5.0, 0.0..=3.0] } #[inline] - fn hcs<'a>() -> [&'a (dyn Cstr + Send + Sync); 2] { - [&(g1 as fn(&Solution) -> usize), &(g2 as fn(&Solution) -> usize)] + fn hcs() -> [Self::Hcs; 2] { + [g1, g2] } #[inline] - fn objs<'a>() -> [&'a (dyn Obj + Send + Sync); 2] { - [ - &(ObjDirection::Min, f1 as fn(&Solution) -> f64), - &(ObjDirection::Min, f2 as fn(&Solution) -> f64), - ] + fn objs() -> [Self::Objs; 2] { + [(ObjDirection::Min, f1), (ObjDirection::Min, f2)] } } + +fn main() -> Result<(), Box> { + exec!("binh-and-korn", BinhAndKorn); + Ok(()) +} diff --git a/mop/examples/common/mod.rs b/mop/examples/common/mod.rs new file mode 100644 index 0000000..9bedc47 --- /dev/null +++ b/mop/examples/common/mod.rs @@ -0,0 +1,140 @@ +#![allow( + // Function pointers + clippy::as_conversions, + trivial_casts + )] + +use core::ops::Range; +use mop::{Cstr, Obj}; +#[cfg(feature = "plotters")] +use plotters::prelude::*; + +pub(crate) trait Problem { + const GRAPH_RANGES: [Range; 2]; + const NAME: &'static str; + + type Hcs: Cstr; + type Objs: Obj; + + fn domain() -> D; + fn hcs() -> [Self::Hcs; H]; + fn objs() -> [Self::Objs; O]; +} + +#[cfg(feature = "plotters")] +pub fn manage_plotting<'any, A, B, I, T>( + x: A, + y: B, + name: &str, + iter: I, +) -> Result<(), Box> +where + A: plotters::coord::ranged1d::AsRangedCoord, + ::CoordDescType: + plotters::coord::ranged1d::ValueFormatter, + B: plotters::coord::ranged1d::AsRangedCoord, + ::CoordDescType: + plotters::coord::ranged1d::ValueFormatter, + I: Iterator + 'any, + T: core::fmt::Debug + 'static, +{ + let mut file = std::env::temp_dir(); + file.push("mop"); + std::fs::create_dir_all(&file)?; + file.push(name); + + let root_area = SVGBackend::new(&file, (800, 600)).into_drawing_area(); + root_area.fill(&WHITE)?; + + let mut ctx = ChartBuilder::on(&root_area) + .set_label_area_size(LabelAreaPosition::Left, 40) + .set_label_area_size(LabelAreaPosition::Bottom, 40) + .caption(name, ("sans-serif", 40)) + .build_cartesian_2d(x, y)?; + + ctx.configure_mesh().draw()?; + + let data = iter.map(|p| TriangleMarker::new(p, 5, &BLUE)); + let _ = ctx.draw_series(data)?; + Ok(()) +} + +#[macro_export] +macro_rules! exec { + ($($feature:literal, $problem:ty)+) => { + #[cfg(any($(feature = $feature),+))] + use { + mop::{ + blocks::{ + gp::{mp_defs_from_gp_defs, GpOperations, MpVec, MphDefinitionsBuilder, MphMpMph, MphVec}, + objs::MinCstrsRslts, + quality_comparator::ObjsAvg, + Either, + Pct, + }, + facades::opt::OptFacade, + solvers::genetic_algorithm::{ + operators::{ + crossover::MultiPoint, mating_selection::Tournament, mutation::RandomDomainAssignments, + }, + GeneticAlgorithmParamsBuilder, Spea2, + }, + }, + mop_problems::Problem, + }; + + #[cfg(any($(feature = $feature),+))] + const RSLTS_NUM: usize = 250; + + $( + #[cfg(feature = $feature)] + { + let mut mph = MphVec::with_capacity( + MphDefinitionsBuilder::default() + .domain(<$problem>::domain()) + .hard_cstrs(<$problem>::hcs().to_vec()) + .name(<$problem>::NAME) + .objs(<$problem>::objs().to_vec()) + .build()?, + RSLTS_NUM, + ); + let (mph_defs, mut mph_rslts) = mph.parts_mut(); + + let mp_defs_ref = mp_defs_from_gp_defs(mph_defs)? + .push_obj(Either::Right(MinCstrsRslts::from_gp_hcs(mph_defs)))? + .build()?; + let mut mp_ref = MpVec::with_random_solutions(mp_defs_ref, 100)?; + + let spea2 = Spea2::new( + Pct::from_percent(50), + GeneticAlgorithmParamsBuilder::default() + .crossover(MultiPoint::new(1, Pct::from_percent(70))) + .mating_selection(Tournament::new(5, ObjsAvg)) + .mutation(RandomDomainAssignments::new(1, Pct::from_percent(30))) + .build()?, + &mp_ref, + RSLTS_NUM, + )?; + let _facade = OptFacade::new(2000) + .set_quality_comparator(ObjsAvg) + .set_opt_hooks(()) + .set_stagnation(Pct::from_percent(1), 30)? + .solve_problem_with(&mut mp_ref, spea2) + ?; + + MphMpMph::transfer(&mph_defs, &mut mph_rslts, &mp_ref)?; + + #[cfg(feature = "plotters")] + if <$problem>::hcs().len() == 2 { + let [x, y] = <$problem>::GRAPH_RANGES; + manage_plotting( + x, + y, + &format!("{} - Objectives", mph_defs.name()), + mph_rslts.iter().map(|r| (r.obj_rslts()[0], r.obj_rslts()[1])), + ).map_err(|_| mop::blocks::Error::Other("Bad plotting"))?; + } + } + )+ + }; + } diff --git a/mop-problems/src/constr.rs b/mop/examples/constr.rs similarity index 70% rename from mop-problems/src/constr.rs rename to mop/examples/constr.rs index 0876f4f..eda9736 100644 --- a/mop-problems/src/constr.rs +++ b/mop/examples/constr.rs @@ -1,13 +1,13 @@ //! Deb, Kalyanmoy (2002) Multiobjective optimization using evolutionary algorithms -use crate::Problem; +mod common; + +use common::Problem; use core::{ cmp::Ordering, ops::{Range, RangeInclusive}, }; -use mop::blocks::{ - ObjDirection, {Cstr, Obj}, -}; +use mop::ObjDirection; type Domain = [RangeInclusive; 2]; type Solution = [f64; 2]; @@ -43,21 +43,26 @@ impl Problem for Constr { const GRAPH_RANGES: [Range; 2] = [0.0..2.0, 0.0..12.0]; const NAME: &'static str = "Constr"; + type Hcs = fn(&[f64; 2]) -> usize; + type Objs = (ObjDirection, fn(&[f64; 2]) -> f64); + #[inline] fn domain() -> Domain { [0.1..=1.0, 0.0..=5.0] } #[inline] - fn hcs<'a>() -> [&'a (dyn Cstr + Send + Sync); 2] { - [&(g1 as fn(&Solution) -> usize), &(g2 as fn(&Solution) -> usize)] + fn hcs() -> [Self::Hcs; 2] { + [g1, g2] } #[inline] - fn objs<'a>() -> [&'a (dyn Obj + Send + Sync); 2] { - [ - &(ObjDirection::Min, f1 as fn(&Solution) -> f64), - &(ObjDirection::Min, f2 as fn(&Solution) -> f64), - ] + fn objs() -> [Self::Objs; 2] { + [(ObjDirection::Min, f1), (ObjDirection::Min, f2)] } } + +fn main() -> Result<(), Box> { + exec!("constr", Constr); + Ok(()) +} diff --git a/mop/examples/cvrp.rs b/mop/examples/cvrp.rs new file mode 100644 index 0000000..7396ed4 --- /dev/null +++ b/mop/examples/cvrp.rs @@ -0,0 +1,236 @@ +mod common; + +#[cfg(feature = "ndstruct")] +mod module { + //! http://vrp.galgos.inf.puc-rio.br/index.php/en/plotted-instances?data=B-n31-k5 + + use crate::common::Problem; + use core::ops::{Range, RangeInclusive}; + use mop::{Cstr, Obj, ObjDirection}; + + type CslArrayVec = ndstruct::csl::Csl< + arrayvec::ArrayVec, + arrayvec::ArrayVec, + arrayvec::ArrayVec, + D, + >; + + const DATA: Data = Data { + capacity: 100, + depot: Node { demand: 0, x: 17.0, y: 76.0 }, + places: [ + Node { demand: 25, x: 24.0, y: 6.0 }, + Node { demand: 3, x: 96.0, y: 29.0 }, + Node { demand: 13, x: 14.0, y: 19.0 }, + Node { demand: 17, x: 14.0, y: 32.0 }, + Node { demand: 16, x: 0.0, y: 34.0 }, + Node { demand: 9, x: 16.0, y: 22.0 }, + Node { demand: 22, x: 20.0, y: 26.0 }, + Node { demand: 10, x: 22.0, y: 28.0 }, + Node { demand: 16, x: 17.0, y: 23.0 }, + Node { demand: 8, x: 98.0, y: 30.0 }, + Node { demand: 3, x: 30.0, y: 8.0 }, + Node { demand: 16, x: 23.0, y: 27.0 }, + Node { demand: 16, x: 19.0, y: 23.0 }, + Node { demand: 10, x: 34.0, y: 7.0 }, + Node { demand: 24, x: 31.0, y: 7.0 }, + Node { demand: 16, x: 0.0, y: 37.0 }, + Node { demand: 15, x: 19.0, y: 23.0 }, + Node { demand: 14, x: 0.0, y: 36.0 }, + Node { demand: 5, x: 26.0, y: 7.0 }, + Node { demand: 12, x: 98.0, y: 32.0 }, + Node { demand: 2, x: 5.0, y: 40.0 }, + Node { demand: 18, x: 17.0, y: 26.0 }, + Node { demand: 20, x: 21.0, y: 26.0 }, + Node { demand: 15, x: 28.0, y: 8.0 }, + Node { demand: 8, x: 1.0, y: 35.0 }, + Node { demand: 22, x: 27.0, y: 28.0 }, + Node { demand: 15, x: 99.0, y: 30.0 }, + Node { demand: 10, x: 26.0, y: 28.0 }, + Node { demand: 13, x: 17.0, y: 29.0 }, + Node { demand: 19, x: 20.0, y: 26.0 }, + ], + }; + + type Domain = [RangeInclusive; 30]; + // A 2-D sparse structure or a sparse matrix or a graph storage + type Solution = CslArrayVec; + + #[derive(Debug)] + struct Data { + capacity: usize, + depot: Node, + places: [Node; 30], + } + + #[derive(Debug)] + struct Node { + demand: usize, + x: f64, + y: f64, + } + + #[allow(dead_code)] + #[derive(Clone, Debug)] + struct RouteCapacityMustNotExceedTruckCapacity { + data: &'static Data, + } + + impl RouteCapacityMustNotExceedTruckCapacity { + fn func(&self, solution: &Solution, mut cb: F) + where + F: FnMut(usize, usize), + { + #[allow( + // Dimension is greater than 0 + clippy::unwrap_used + )] + for (route_idx, route) in solution.outermost_line_iter().unwrap().enumerate() { + let mut route_capacity = 0; + for place_idx in route.data().iter().copied() { + route_capacity += DATA.places[place_idx].demand; + } + if route_capacity > DATA.capacity { + cb(route_idx, route_capacity - DATA.capacity); + } + } + } + } + + impl Cstr for RouteCapacityMustNotExceedTruckCapacity { + #[inline] + fn reasons(&self, solution: &Solution) -> String { + let mut reasons = String::new(); + self.func(solution, |route_idx, surplus| { + reasons.push_str(&format!( + "Route #{} extrapolates truck capacity by {}\n", + route_idx + 1, + surplus + )); + }); + reasons + } + + #[inline] + fn violations(&self, solution: &Solution) -> usize { + let mut ret = 0; + self.func(solution, |_, _| ret += 1); + ret + } + } + + #[derive(Clone, Debug)] + #[allow(dead_code)] + struct MinCost { + data: &'static Data, + } + + impl MinCost { + fn euclidian_distance(x1: f64, y1: f64, x2: f64, y2: f64) -> f64 { + ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt() + } + } + + impl Obj for MinCost { + #[inline] + fn obj_direction(&self) -> ObjDirection { + ObjDirection::Min + } + + #[inline] + fn result(&self, solution: &Solution) -> f64 { + let mut cost = 0.0; + #[allow( + // Dimension is greater than 0 + clippy::unwrap_used + )] + for route in solution.outermost_line_iter().unwrap() { + let mut last_place = &DATA.depot; + for place_idx in route.data().iter().copied() { + let distance = Self::euclidian_distance( + last_place.x, + last_place.y, + DATA.places[place_idx].x, + DATA.places[place_idx].y, + ); + cost += distance; + last_place = &DATA.places[place_idx]; + } + } + cost + } + } + + #[derive(Debug)] + struct Cvrp; + + impl Problem for Cvrp { + const GRAPH_RANGES: [Range; 2] = [-3.0..13.0, -8.0..-4.0]; + const NAME: &'static str = "CVRP"; + + type Hcs = RouteCapacityMustNotExceedTruckCapacity; + type Objs = MinCost; + + #[inline] + fn domain() -> Domain { + [ + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + 45..=45, + ] + } + + #[inline] + fn hcs() -> [Self::Hcs; 1] { + [RouteCapacityMustNotExceedTruckCapacity { data: &DATA }] + } + + #[inline] + fn objs() -> [Self::Objs; 1] { + [MinCost { data: &DATA }] + } + } + + pub(crate) fn main() -> Result<(), Box> { + crate::exec!("cvrp", Cvrp); + Ok(()) + } +} + +#[cfg(not(feature = "ndstruct"))] +mod module { + pub(crate) fn main() -> Result<(), Box> { + Ok(()) + } +} + +fn main() -> Result<(), Box> { + module::main() +} diff --git a/mop-problems/src/rastrigin.rs b/mop/examples/rastrigin.rs similarity index 69% rename from mop-problems/src/rastrigin.rs rename to mop/examples/rastrigin.rs index 638b1d0..8489cad 100644 --- a/mop-problems/src/rastrigin.rs +++ b/mop/examples/rastrigin.rs @@ -1,11 +1,13 @@ //! Rastrigin, L. A.; Systems of extremal control. -use crate::Problem; +mod common; + +use common::Problem; use core::{ f64::consts::PI, ops::{Range, RangeInclusive}, }; -use mop::blocks::{Cstr, Obj, ObjDirection}; +use mop::ObjDirection; const N_USIZE: usize = 2; const N_F64: f64 = 2.0; @@ -28,18 +30,26 @@ impl Problem for Rastrigin { const GRAPH_RANGES: [Range; 2] = [-6.0..6.0, -6.0..6.0]; const NAME: &'static str = "Rastrigin"; + type Hcs = fn(&[f64; 2]) -> usize; + type Objs = (ObjDirection, fn(&[f64; 2]) -> f64); + #[inline] fn domain() -> Domain { [-5.12..=5.12, -5.12..=5.12] } #[inline] - fn hcs<'a>() -> [&'a (dyn Cstr + Send + Sync); 0] { + fn hcs() -> [Self::Hcs; 0] { [] } #[inline] - fn objs<'a>() -> [&'a (dyn Obj + Send + Sync); 1] { - [&(ObjDirection::Min, f1 as fn(&Solution) -> f64)] + fn objs() -> [Self::Objs; 1] { + [(ObjDirection::Min, f1)] } } + +fn main() -> Result<(), Box> { + exec!("rastrigin", Rastrigin); + Ok(()) +} diff --git a/mop-problems/src/schaffer_function_2.rs b/mop/examples/schaffer_function_2.rs similarity index 70% rename from mop-problems/src/schaffer_function_2.rs rename to mop/examples/schaffer_function_2.rs index 405720b..941d5e5 100644 --- a/mop-problems/src/schaffer_function_2.rs +++ b/mop/examples/schaffer_function_2.rs @@ -1,9 +1,11 @@ //! Schaffer, J. David (1984). Some experiments in machine learning using vector evaluated genetic //! algorithms (artificial intelligence, optimization, adaptation, pattern recognition) -use crate::Problem; +mod common; + +use common::Problem; use core::ops::{Range, RangeInclusive}; -use mop::blocks::{Cstr, Obj, ObjDirection}; +use mop::ObjDirection; type Solution = [f64; 1]; type Domain = [RangeInclusive; 1]; @@ -31,21 +33,26 @@ impl Problem for SchafferFunction2 { const GRAPH_RANGES: [Range; 2] = [-2.0..10.0, 0.0..30.0]; const NAME: &'static str = "Schaffer function 2"; + type Hcs = fn(&[f64; 1]) -> usize; + type Objs = (ObjDirection, fn(&[f64; 1]) -> f64); + #[inline] fn domain() -> Domain { [-5.0..=10.0] } #[inline] - fn hcs<'a>() -> [&'a (dyn Cstr + Send + Sync); 0] { + fn hcs() -> [Self::Hcs; 0] { [] } #[inline] - fn objs<'a>() -> [&'a (dyn Obj + Send + Sync); 2] { - [ - &(ObjDirection::Min, f1 as fn(&Solution) -> f64), - &(ObjDirection::Min, f2 as fn(&Solution) -> f64), - ] + fn objs() -> [Self::Objs; 2] { + [(ObjDirection::Min, f1), (ObjDirection::Min, f2)] } } + +fn main() -> Result<(), Box> { + exec!("schaffer-function-2", SchafferFunction2); + Ok(()) +} diff --git a/mop-problems/src/test_function_4.rs b/mop/examples/test_function_4.rs similarity index 72% rename from mop-problems/src/test_function_4.rs rename to mop/examples/test_function_4.rs index 3b3c09a..3053b25 100644 --- a/mop-problems/src/test_function_4.rs +++ b/mop/examples/test_function_4.rs @@ -1,11 +1,13 @@ //! Binh; A multiobjective evolutionary algorithm. The study cases -use crate::Problem; +mod common; + +use common::Problem; use core::{ cmp::Ordering, ops::{Range, RangeInclusive}, }; -use mop::blocks::{Cstr, Obj, ObjDirection}; +use mop::ObjDirection; type Solution = [f64; 2]; type Domain = [RangeInclusive; 2]; @@ -49,25 +51,26 @@ impl Problem for TestFunction4 { const GRAPH_RANGES: [Range; 2] = [-3.0..13.0, -8.0..-4.0]; const NAME: &'static str = "Test Function 4"; + type Hcs = fn(&[f64; 2]) -> usize; + type Objs = (ObjDirection, fn(&[f64; 2]) -> f64); + #[inline] fn domain() -> Domain { [-7.0..=4.0, -7.0..=4.0] } #[inline] - fn hcs<'a>() -> [&'a (dyn Cstr + Send + Sync); 3] { - [ - &(g1 as fn(&Solution) -> usize), - &(g2 as fn(&Solution) -> usize), - &(g3 as fn(&Solution) -> usize), - ] + fn hcs() -> [Self::Hcs; 3] { + [g1, g2, g3] } #[inline] - fn objs<'a>() -> [&'a (dyn Obj + Send + Sync); 2] { - [ - &(ObjDirection::Min, f1 as fn(&Solution) -> f64), - &(ObjDirection::Min, f2 as fn(&Solution) -> f64), - ] + fn objs() -> [Self::Objs; 2] { + [(ObjDirection::Min, f1), (ObjDirection::Min, f2)] } } + +fn main() -> Result<(), Box> { + exec!("test-function-4", TestFunction4); + Ok(()) +} diff --git a/mop-blocks/src/criteria.rs b/mop/src/criteria.rs similarity index 100% rename from mop-blocks/src/criteria.rs rename to mop/src/criteria.rs diff --git a/mop-blocks/src/criteria/cstr.rs b/mop/src/criteria/cstr.rs similarity index 100% rename from mop-blocks/src/criteria/cstr.rs rename to mop/src/criteria/cstr.rs diff --git a/mop-blocks/src/criteria/obj.rs b/mop/src/criteria/obj.rs similarity index 94% rename from mop-blocks/src/criteria/obj.rs rename to mop/src/criteria/obj.rs index dbcdb7d..f5ff2f6 100644 --- a/mop-blocks/src/criteria/obj.rs +++ b/mop/src/criteria/obj.rs @@ -1,6 +1,5 @@ use crate::ObjDirection; use alloc::boxed::Box; -use mop_common::TraitCfg; /// Objective /// @@ -8,7 +7,7 @@ use mop_common::TraitCfg; /// /// * `OR`: Objective Result /// * `S`: Solution -pub trait Obj: TraitCfg { +pub trait Obj { fn obj_direction(&self) -> ObjDirection; fn result(&self, solution: &S) -> OR; diff --git a/mop-blocks/src/doc_tests.rs b/mop/src/doc_tests.rs similarity index 100% rename from mop-blocks/src/doc_tests.rs rename to mop/src/doc_tests.rs diff --git a/mop-blocks/src/domain.rs b/mop/src/domain.rs similarity index 73% rename from mop-blocks/src/domain.rs rename to mop/src/domain.rs index 0ec3f31..dc96975 100644 --- a/mop-blocks/src/domain.rs +++ b/mop/src/domain.rs @@ -1,8 +1,7 @@ -#[cfg(all(feature = "with-ndsparse", feature = "with-rand"))] -use cl_traits::{Push, Storage}; -#[cfg(feature = "with-rand")] +#[cfg(all(feature = "ndstruct", feature = "rand"))] +use cl_aux::{Push, SingleTypeStorage}; +#[cfg(feature = "rand")] use { - cl_traits::create_array, core::ops::RangeInclusive, rand::{ distributions::{uniform::SampleUniform, Distribution, Uniform}, @@ -20,18 +19,18 @@ pub trait Domain { fn len(&self) -> usize; - #[cfg(feature = "with-rand")] + #[cfg(feature = "rand")] fn new_random_solution(&self, rng: &mut R) -> Result where R: Rng; - #[cfg(feature = "with-rand")] + #[cfg(feature = "rand")] fn set_rnd_domain(&self, s: &mut S, idx: usize, rng: &mut R) where R: Rng; } -#[cfg(feature = "with-rand")] +#[cfg(feature = "rand")] impl Domain<[T; N]> for [RangeInclusive; N] where T: Copy + SampleUniform, @@ -48,7 +47,7 @@ where where R: Rng, { - Ok(create_array(|idx| Uniform::from(*self[idx].start()..=*self[idx].end()).sample(rng))) + Ok(core::array::from_fn(|idx| Uniform::from(*self[idx].start()..=*self[idx].end()).sample(rng))) } #[inline] @@ -62,7 +61,7 @@ where } } -#[cfg(feature = "with-rand")] +#[cfg(feature = "rand")] impl Domain> for arrayvec::ArrayVec, N> where @@ -81,7 +80,7 @@ where R: Rng, { let mut s = arrayvec::ArrayVec::new(); - for domain in self.iter() { + for domain in self { s.push(Uniform::from(*domain.start()..=*domain.end()).sample(rng)); } Ok(s) @@ -98,14 +97,18 @@ where } } -#[cfg(all(feature = "with-ndsparse", feature = "with-rand"))] -impl Domain> +#[cfg(all(feature = "ndstruct", feature = "rand"))] +impl Domain> for [RangeInclusive; N] where DATA: Copy + SampleUniform, - DS: AsMut<[DATA]> + AsRef<[DATA]> + Default + Push + Storage, - IS: AsMut<[usize]> + AsRef<[usize]> + Default + Push, - OS: AsMut<[usize]> + AsRef<[usize]> + Default + Push, + DS: AsMut<[DATA]> + + AsRef<[DATA]> + + Default + + Push + + SingleTypeStorage, + IS: AsMut<[usize]> + AsRef<[usize]> + Default + Push, + OS: AsMut<[usize]> + AsRef<[usize]> + Default + Push, rand::distributions::Standard: Distribution, { type Error = crate::Error; @@ -119,12 +122,12 @@ where fn new_random_solution( &self, rng: &mut R, - ) -> Result, Self::Error> + ) -> Result, Self::Error> where R: Rng, { let nnz = self.as_ref().len(); - let dims = cl_traits::default_array(); + let dims = [0; D]; let mut array: [usize; D] = dims; let iter = array.iter_mut(); match nnz { @@ -132,12 +135,12 @@ where 1 => iter.for_each(|dim| *dim = 1), _ => iter.for_each(|dim| *dim = rng.gen_range(1..nnz)), } - ndsparse::csl::Csl::new_controlled_random_rand(dims, nnz, rng, |g, _| g.gen()) + ndstruct::csl::Csl::new_controlled_random_rand(dims, nnz, rng, |g, _| g.gen()) .map_err(crate::Error::NdsparseError) } #[inline] - fn set_rnd_domain(&self, s: &mut ndsparse::csl::Csl, idx: usize, rng: &mut R) + fn set_rnd_domain(&self, s: &mut ndstruct::csl::Csl, idx: usize, rng: &mut R) where R: Rng, { diff --git a/mop-blocks/src/dr_matrix.rs b/mop/src/dr_matrix.rs similarity index 86% rename from mop-blocks/src/dr_matrix.rs rename to mop/src/dr_matrix.rs index 941e215..9c9a2bc 100644 --- a/mop-blocks/src/dr_matrix.rs +++ b/mop/src/dr_matrix.rs @@ -1,15 +1,19 @@ mod dr_matrix_error; mod dr_matrix_row_iter_impls; +#[cfg(feature = "rayon")] +mod dr_matrix_row_par_iter_impls; mod dr_matrix_rows_constructor; use alloc::vec::Vec; -use cl_traits::{Clear, Storage, Truncate, WithCapacity}; +use cl_aux::{Clear, SingleTypeStorage, Truncate, WithCapacity}; use core::cmp::Ordering; -pub use {dr_matrix_error::*, dr_matrix_row_iter_impls::*, dr_matrix_rows_constructor::*}; +pub use dr_matrix_error::*; +pub use dr_matrix_row_iter_impls::*; +pub use dr_matrix_rows_constructor::*; pub type DrMatrixArray = DrMatrix<[DATA; D]>; -pub type DrMatrixMut<'a, DATA, const D: usize> = DrMatrix<&'a mut [DATA]>; -pub type DrMatrixRef<'a, DATA> = DrMatrix<&'a [DATA]>; +pub type DrMatrixMut<'any, DATA, const D: usize> = DrMatrix<&'any mut [DATA]>; +pub type DrMatrixRef<'any, DATA> = DrMatrix<&'any [DATA]>; pub type DrMatrixVec = DrMatrix>; pub type Result = core::result::Result; @@ -22,8 +26,8 @@ pub type Result = core::result::Result; /// /// # Types /// -/// * `DS`: Data Storage -#[cfg_attr(feature = "with-serde", derive(serde::Deserialize, serde::Serialize))] +/// * `DS`: Data SingleTypeStorage +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)] pub struct DrMatrix { pub(crate) cols: usize, @@ -43,7 +47,7 @@ impl DrMatrix { /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_vec; + /// use mop::doc_tests::dr_matrix_vec; /// let mut dcca = dr_matrix_vec(); /// dcca.clear(); /// assert_eq!(dcca.cols(), 5); @@ -64,7 +68,7 @@ impl DrMatrix { /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_array; + /// use mop::doc_tests::dr_matrix_array; /// assert_eq!(dr_matrix_array().cols(), 5); /// ``` #[inline] @@ -77,7 +81,7 @@ impl DrMatrix { /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_array; + /// use mop::doc_tests::dr_matrix_array; /// assert_eq!(dr_matrix_array().rows(), 4); /// ``` #[inline] @@ -94,7 +98,7 @@ impl DrMatrix { /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_vec; + /// use mop::doc_tests::dr_matrix_vec; /// let mut ddma = dr_matrix_vec(); /// ddma.truncate(2); /// assert_eq!(ddma.cols(), 5); @@ -104,7 +108,7 @@ impl DrMatrix { #[inline] pub fn truncate(&mut self, rows: usize) where - DS: Truncate, + DS: Truncate, { if rows >= self.rows { return; @@ -145,7 +149,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::dr_matrix::DrMatrix; + /// use mop::dr_matrix::DrMatrix; /// let matrix = DrMatrix::>::with_capacity(2, 3); /// assert_eq!(matrix.cols(), 3); /// assert_eq!(matrix.rows(), 0); @@ -158,7 +162,7 @@ where impl DrMatrix where - DS: AsRef<[DATA]> + Storage, + DS: AsRef<[DATA]> + SingleTypeStorage, { /// Creates a new [`DrMatrix`](DrMatrix) from raw parameters. /// @@ -170,7 +174,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::dr_matrix::DrMatrixArray; + /// use mop::dr_matrix::DrMatrixArray; /// let _ = DrMatrixArray::new([2, 4], [1, 2, 3, 4, 5, 6, 7, 8]); /// ``` #[inline] @@ -186,7 +190,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::{doc_tests::dr_matrix_array, dr_matrix::DrMatrixRef}; + /// use mop::{doc_tests::dr_matrix_array, dr_matrix::DrMatrixRef}; /// assert_eq!( /// Ok(dr_matrix_array().as_ref()), /// DrMatrixRef::new( @@ -205,7 +209,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_vec; + /// use mop::doc_tests::dr_matrix_vec; /// assert_eq!( /// dr_matrix_vec().data(), /// &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] @@ -226,7 +230,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_array; + /// use mop::doc_tests::dr_matrix_array; /// let ddma = dr_matrix_array(); /// for row_idx in 0..4 { /// let starting_row_value = row_idx * 5 + 1; @@ -252,7 +256,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_array; + /// use mop::doc_tests::dr_matrix_array; /// let ddma = dr_matrix_array(); /// let mut ri = ddma.row_iter(); /// assert_eq!(ri.next(), Some(&[1, 2, 3, 4, 5][..])); @@ -266,13 +270,19 @@ where DrMatrixRowIter::new([self.rows, self.cols], self.data()) } + #[inline] + #[cfg(feature = "rayon")] + pub fn row_par_iter(&self) -> crate::ParallelIteratorWrapper> { + crate::ParallelIteratorWrapper(self.row_iter()) + } + /// Copies the internal data into a heap allocated `Vec` storage and /// returns it as owned value. /// /// # Example /// /// ```rust - /// use mop_blocks::{doc_tests::dr_matrix_array, dr_matrix::DrMatrixVec}; + /// use mop::{doc_tests::dr_matrix_array, dr_matrix::DrMatrixVec}; /// let ddma = dr_matrix_array(); /// assert_eq!( /// DrMatrixVec::new( @@ -301,7 +311,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_array; + /// use mop::doc_tests::dr_matrix_array; /// let ddma = dr_matrix_array(); /// for row_idx in 0..4 { /// let starting_row_value = row_idx * 5 + 1; @@ -319,7 +329,7 @@ where impl DrMatrix where - DS: AsMut<[DATA]> + Storage, + DS: AsMut<[DATA]> + SingleTypeStorage, { /// Mutable version of [`data`](#method.data). #[inline] @@ -336,7 +346,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_vec; + /// use mop::doc_tests::dr_matrix_vec; /// let mut ddma = dr_matrix_vec(); /// ddma.remove_row(2); /// assert_eq!(ddma.data(), &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 17, 18, 19, 20]); @@ -346,7 +356,7 @@ where #[must_use] pub fn remove_row(&mut self, idx: usize) -> bool where - DS: Truncate, + DS: Truncate, { if idx >= self.rows { return false; @@ -375,6 +385,14 @@ where DrMatrixRowIterMut::new([self.rows, self.cols], self.data.as_mut()) } + #[inline] + #[cfg(feature = "rayon")] + pub fn row_par_iter_mut( + &mut self, + ) -> crate::ParallelIteratorWrapper> { + crate::ParallelIteratorWrapper(self.row_iter_mut()) + } + /// Swaps a single value given the two provided indices. /// /// # Arguments @@ -385,7 +403,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_vec; + /// use mop::doc_tests::dr_matrix_vec; /// let mut ddma = dr_matrix_vec(); /// let _ = ddma.swap([0, 0], [3, 1]); /// assert_eq!(ddma.data(), &[17, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 18, 19, 20]); @@ -418,7 +436,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_array; + /// use mop::doc_tests::dr_matrix_array; /// let mut matrix = dr_matrix_array(); /// let original_0_row = matrix.row(0).unwrap().to_vec(); /// let original_3_row = matrix.row(3).unwrap().to_vec(); @@ -447,7 +465,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::doc_tests::dr_matrix_array; + /// use mop::doc_tests::dr_matrix_array; /// let mut matrix = dr_matrix_array(); /// let [a, b] = matrix.two_rows_mut(0, 1).unwrap(); /// a.iter_mut().for_each(|elem| *elem += 1); @@ -478,10 +496,10 @@ where } } -#[cfg(feature = "with-rand")] +#[cfg(feature = "rand")] impl DrMatrix where - DS: Default + Storage + cl_traits::Capacity + cl_traits::Push, + DS: Default + SingleTypeStorage + cl_aux::Capacity + cl_aux::Push, { /// Creates a new random and valid instance delimited by the passed arguments. /// @@ -499,6 +517,7 @@ where where F: FnMut(&mut R, [usize; 2]) -> DATA, R: rand::Rng, + crate::Error: From, { let mut data = DS::default(); if rows.saturating_mul(cols) != data.capacity() { @@ -506,7 +525,7 @@ where } for row in 0..rows { for col in 0..cols { - let _ = data.push(cb(rng, [row, col])); + data.push(cb(rng, [row, col]))?; } } Ok(DrMatrix { cols, data, rows }) diff --git a/mop-blocks/src/dr_matrix/dr_matrix_error.rs b/mop/src/dr_matrix/dr_matrix_error.rs similarity index 89% rename from mop-blocks/src/dr_matrix/dr_matrix_error.rs rename to mop/src/dr_matrix/dr_matrix_error.rs index 7b83734..5d1fb4c 100644 --- a/mop-blocks/src/dr_matrix/dr_matrix_error.rs +++ b/mop/src/dr_matrix/dr_matrix_error.rs @@ -7,7 +7,7 @@ pub enum DrMatrixError { /// The length of `data` isn't equal the number of rows times the number of columns. /// /// ```rust - /// use mop_blocks::dr_matrix::DrMatrixRef; + /// use mop::dr_matrix::DrMatrixRef; /// let _ = DrMatrixRef::new([2, 4], &[1, 2, 3][..]); /// ``` DataLenDiffColsTimesRows, @@ -15,7 +15,7 @@ pub enum DrMatrixError { /// The capacity of `data` isn't enough to store all desired elements. /// /// ```rust - /// use mop_blocks::dr_matrix::DrMatrixVec; + /// use mop::dr_matrix::DrMatrixVec; /// let _ = DrMatrixVec::new([999, 999], vec![1, 2, 3]); /// ``` NotEnoughCapacity, diff --git a/mop-blocks/src/dr_matrix/dr_matrix_row_iter_impls.rs b/mop/src/dr_matrix/dr_matrix_row_iter_impls.rs similarity index 83% rename from mop-blocks/src/dr_matrix/dr_matrix_row_iter_impls.rs rename to mop/src/dr_matrix/dr_matrix_row_iter_impls.rs index 0abe283..4eaab28 100644 --- a/mop-blocks/src/dr_matrix/dr_matrix_row_iter_impls.rs +++ b/mop/src/dr_matrix/dr_matrix_row_iter_impls.rs @@ -3,15 +3,15 @@ use core::{marker::PhantomData, mem}; macro_rules! impl_iter ( ($dr_matrix_iter:ident, $data_ptr:ty, $data_type:ty, $split_at:ident) => ( #[derive(Debug)] -pub struct $dr_matrix_iter<'a, T> { +pub struct $dr_matrix_iter<'any, T> { cols: usize, curr_row: usize, data: $data_type, - phantom: PhantomData<&'a T>, + phantom: PhantomData<&'any T>, rows: usize, } -impl<'a, T> $dr_matrix_iter<'a, T> { +impl<'any, T> $dr_matrix_iter<'any, T> { pub(crate) fn new( [rows, cols]: [usize; 2], data: $data_type, @@ -50,7 +50,7 @@ impl<'a, T> $dr_matrix_iter<'a, T> { } } -impl<'a, T> DoubleEndedIterator for $dr_matrix_iter<'a, T> { +impl DoubleEndedIterator for $dr_matrix_iter<'_, T> { #[inline] fn next_back(&mut self) -> Option { if self.curr_row >= self.rows { @@ -64,10 +64,10 @@ impl<'a, T> DoubleEndedIterator for $dr_matrix_iter<'a, T> { } } -impl<'a, T> ExactSizeIterator for $dr_matrix_iter<'a, T> { +impl ExactSizeIterator for $dr_matrix_iter<'_, T> { } -impl<'a, T> Iterator for $dr_matrix_iter<'a, T> { +impl<'any, T> Iterator for $dr_matrix_iter<'any, T> { type Item = $data_type; #[inline] @@ -91,5 +91,5 @@ impl<'a, T> Iterator for $dr_matrix_iter<'a, T> { ); ); -impl_iter!(DrMatrixRowIter, *const T, &'a [T], split_at); -impl_iter!(DrMatrixRowIterMut, *mut T, &'a mut [T], split_at_mut); +impl_iter!(DrMatrixRowIter, *const T, &'any [T], split_at); +impl_iter!(DrMatrixRowIterMut, *mut T, &'any mut [T], split_at_mut); diff --git a/mop/src/dr_matrix/dr_matrix_row_par_iter_impls.rs b/mop/src/dr_matrix/dr_matrix_row_par_iter_impls.rs new file mode 100644 index 0000000..a28a94a --- /dev/null +++ b/mop/src/dr_matrix/dr_matrix_row_par_iter_impls.rs @@ -0,0 +1,90 @@ +use crate::{ + dr_matrix::{DrMatrixRowIter, DrMatrixRowIterMut}, + ParallelIteratorWrapper, ParallelProducerWrapper, +}; +use rayon::iter::{ + plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer}, + IndexedParallelIterator, ParallelIterator, +}; + +macro_rules! impl_par_iter { + ($dr_matrix_row_iter:ident, $return_type:ty) => { + impl<'any, T> ParallelIterator for ParallelIteratorWrapper<$dr_matrix_row_iter<'any, T>> + where + T: Send + Sync, + { + type Item = $return_type; + + #[inline] + fn drive_unindexed(self, consumer: C) -> C::Result + where + C: UnindexedConsumer, + { + bridge(self, consumer) + } + + #[inline] + fn opt_len(&self) -> Option { + Some(self.0.len()) + } + } + + impl IndexedParallelIterator for ParallelIteratorWrapper<$dr_matrix_row_iter<'_, T>> + where + T: Send + Sync, + { + #[inline] + fn drive(self, consumer: C) -> C::Result + where + C: Consumer, + { + bridge(self, consumer) + } + + #[inline] + fn len(&self) -> usize { + ExactSizeIterator::len(&self.0) + } + + #[inline] + fn with_producer(self, callback: Cb) -> Cb::Output + where + Cb: ProducerCallback, + { + callback.callback(ParallelProducerWrapper(self.0)) + } + } + + impl<'any, T> IntoIterator for ParallelProducerWrapper<$dr_matrix_row_iter<'any, T>> { + type IntoIter = $dr_matrix_row_iter<'any, T>; + type Item = ::Item; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.0 + } + } + + impl<'any, T> Producer for ParallelProducerWrapper<$dr_matrix_row_iter<'any, T>> + where + T: Send + Sync, + { + type IntoIter = $dr_matrix_row_iter<'any, T>; + type Item = ::Item; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.0 + } + + #[inline] + fn split_at(self, i: usize) -> (Self, Self) { + let (a, b) = self.0.split_at(i); + (ParallelProducerWrapper(a), ParallelProducerWrapper(b)) + } + } + }; +} + +impl_par_iter!(DrMatrixRowIter, &'any [T]); +impl_par_iter!(DrMatrixRowIterMut, &'any mut [T]); diff --git a/mop-blocks/src/dr_matrix/dr_matrix_rows_constructor.rs b/mop/src/dr_matrix/dr_matrix_rows_constructor.rs similarity index 75% rename from mop-blocks/src/dr_matrix/dr_matrix_rows_constructor.rs rename to mop/src/dr_matrix/dr_matrix_rows_constructor.rs index 377791c..a06a73e 100644 --- a/mop-blocks/src/dr_matrix/dr_matrix_rows_constructor.rs +++ b/mop/src/dr_matrix/dr_matrix_rows_constructor.rs @@ -1,35 +1,36 @@ use crate::dr_matrix::DrMatrixRef; use alloc::vec::Vec; -use cl_traits::{Length, Push, Storage}; +use cl_aux::{Length, Push, SingleTypeStorage}; use core::iter::Extend; -pub type DrMatrixRowConstructorMut<'a, DATA> = DrMatrixRowsConstructor<'a, &'a mut [DATA]>; -pub type DrMatrixRowConstructorRef<'a, DATA> = DrMatrixRowsConstructor<'a, &'a [DATA]>; -pub type DrMatrixRowConstructorVec<'a, T> = DrMatrixRowsConstructor<'a, Vec>; +pub type DrMatrixRowConstructorMut<'any, DATA> = DrMatrixRowsConstructor<'any, &'any mut [DATA]>; +pub type DrMatrixRowConstructorRef<'any, DATA> = DrMatrixRowsConstructor<'any, &'any [DATA]>; +pub type DrMatrixRowConstructorVec<'any, T> = DrMatrixRowsConstructor<'any, Vec>; /// Constructs a new valid row in a easy and interactive manner. /// /// This struct may panic when out of scope. Please see the `Drop` documentation in /// the [`Trait Implementations`](#implementations) section for more information. #[derive(Debug, PartialEq)] -pub struct DrMatrixRowsConstructor<'a, DS> { - pub(crate) data: &'a mut DS, +pub struct DrMatrixRowsConstructor<'any, DS> { + pub(crate) data: &'any mut DS, pub(crate) cols: usize, - pub(crate) rows: &'a mut usize, + pub(crate) rows: &'any mut usize, } -impl<'a, DS> DrMatrixRowsConstructor<'a, DS> { +impl<'any, DS> DrMatrixRowsConstructor<'any, DS> { #[inline] - pub(crate) fn new(rows: &'a mut usize, cols: usize, data: &'a mut DS) -> Self { + pub(crate) fn new(rows: &'any mut usize, cols: usize, data: &'any mut DS) -> Self { DrMatrixRowsConstructor { data, cols, rows } } } -impl<'a, DATA, DS> DrMatrixRowsConstructor<'a, DS> +impl DrMatrixRowsConstructor<'_, DS> where - DS: Storage, + DS: SingleTypeStorage, { #[inline] + #[must_use] pub fn fill_row(self, elem: DATA) -> Self where DATA: Clone, @@ -41,6 +42,7 @@ where } #[inline] + #[must_use] pub fn fill_rows(self, rows: usize, elem: DATA) -> Self where DATA: Clone, @@ -68,7 +70,7 @@ where #[inline] pub fn row_cb(self, mut cb: F) -> crate::Result where - DS: Push, + DS: Push, F: FnMut(usize) -> DATA, { for idx in 0..self.cols { @@ -99,7 +101,7 @@ where /// # Example /// /// ```rust - /// use mop_blocks::{doc_tests::capacited_dr_matrix_vec, dr_matrix::DrMatrixRef}; + /// use mop::{doc_tests::capacited_dr_matrix_vec, dr_matrix::DrMatrixRef}; /// let mut a = capacited_dr_matrix_vec(); /// a.constructor().row_slice(&[1, 2, 3, 4, 5]); /// assert_eq!(Ok(a.as_ref()), DrMatrixRef::new([1, 5], &[1, 2, 3, 4, 5][..])); diff --git a/mop/src/either.rs b/mop/src/either.rs new file mode 100644 index 0000000..baa7ca0 --- /dev/null +++ b/mop/src/either.rs @@ -0,0 +1,32 @@ +use num_traits::{Bounded, NumCast}; + +use crate::{Obj, ObjDirection}; + +#[derive(Debug)] +pub enum Either { + Left(L), + Right(R), +} + +impl Obj for Either +where + O: Obj, + OO: Obj, + OR: Bounded + NumCast, +{ + #[inline] + fn obj_direction(&self) -> ObjDirection { + match self { + Either::Left(elem) => elem.obj_direction(), + Either::Right(elem) => elem.obj_direction(), + } + } + + #[inline] + fn result(&self, s: &S) -> OR { + match self { + Either::Left(elem) => elem.result(s), + Either::Right(elem) => elem.result(s), + } + } +} diff --git a/mop-blocks/src/error.rs b/mop/src/error.rs similarity index 78% rename from mop-blocks/src/error.rs rename to mop/src/error.rs index 87dbe43..5cd6d7e 100644 --- a/mop-blocks/src/error.rs +++ b/mop/src/error.rs @@ -15,9 +15,9 @@ pub enum Error { InsufficientCapacity, /// GpDefinitionsBuilder error Gdbe(GpDefinitionsBuilderError), - /// Error from external ndsparse dependency - #[cfg(feature = "with-ndsparse")] - NdsparseError(ndsparse::Error), + /// Error from external ndstruct dependency + #[cfg(feature = "ndstruct")] + NdsparseError(ndstruct::Error), /// An unspecified error occurred Other(&'static str), /// Unsupported conversion @@ -70,10 +70,10 @@ impl From for Error { } } -#[cfg(feature = "with-ndsparse")] -impl From for Error { +#[cfg(feature = "ndstruct")] +impl From for Error { #[inline] - fn from(from: ndsparse::Error) -> Self { + fn from(from: ndstruct::Error) -> Self { Self::NdsparseError(from) } } @@ -84,15 +84,15 @@ impl std::error::Error for Error {} impl fmt::Display for Error { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { + match self { Self::BadCast => write!(f, "BadCast"), - Self::DrMatrixError(ref x) => write!(f, "DrMatrixError({})", x), + Self::DrMatrixError(x) => write!(f, "DrMatrixError({x})"), Self::EmptyElement => write!(f, "EmptyElement"), Self::InsufficientCapacity => write!(f, "Insufficient capacity"), - Self::Gdbe(ref x) => write!(f, "GDBE({})", x), - #[cfg(feature = "with-ndsparse")] - Self::NdsparseError(ref x) => write!(f, "NdsparseError({})", x), - Self::Other(ref x) => write!(f, "Other({})", x), + Self::Gdbe(x) => write!(f, "GDBE({x})"), + #[cfg(feature = "ndstruct")] + Self::NdsparseError(x) => write!(f, "NdsparseError({x})"), + Self::Other(x) => write!(f, "Other({x})"), Self::UnsupportedConversion => write!(f, "Unsupported conversion"), } } diff --git a/mop-blocks/src/gp.rs b/mop/src/gp.rs similarity index 83% rename from mop-blocks/src/gp.rs rename to mop/src/gp.rs index f5e6e17..1396f8a 100644 --- a/mop-blocks/src/gp.rs +++ b/mop/src/gp.rs @@ -11,18 +11,16 @@ mod gp_ors_evaluators; use crate::Obj; use alloc::vec::Vec; use arrayvec::ArrayVec; -use cl_traits::{Push, Storage, WithCapacity}; -#[cfg(feature = "with-rand")] +use cl_aux::{Push, SingleTypeStorage, WithCapacity}; +pub use gp_definitions::*; +pub use gp_definitions_builder::*; +pub use gp_operations::{mph_mp_mph::*, mphs_mp_mphs::*, *}; +pub use gp_or::*; +pub use gp_ors::*; +pub use gp_ors_constructor::*; +pub use gp_ors_evaluators::*; +#[cfg(feature = "rand")] use rand::rngs::OsRng; -pub use { - gp_definitions::*, - gp_definitions_builder::*, - gp_operations::{mph_mp_mph::*, mphs_mp_mphs::*, *}, - gp_or::*, - gp_ors::*, - gp_ors_constructor::*, - gp_ors_evaluators::*, -}; /// Marker for unconstrained problems pub type NoCstr = ArrayVec<(), 0>; @@ -103,14 +101,14 @@ impl Gp Gp where - HCRS: Extend + Storage + WithCapacity, - HCS: AsRef<[HC]> + Storage, - ORS: Extend + Storage + WithCapacity, + HCRS: Extend + SingleTypeStorage + WithCapacity, + HCS: AsRef<[HC]> + SingleTypeStorage, + ORS: Extend + SingleTypeStorage + WithCapacity, O: Obj, - OS: AsRef<[O]> + Storage, - SCRS: Extend + Storage + WithCapacity, - SCS: AsRef<[SC]> + Storage, - SS: Push + Storage + WithCapacity, + OS: AsRef<[O]> + SingleTypeStorage, + SCRS: Extend + SingleTypeStorage + WithCapacity, + SCS: AsRef<[SC]> + SingleTypeStorage, + SS: Push + SingleTypeStorage + WithCapacity, { #[inline] pub fn with_capacity(defs: GpDefinitions, rslts_num: usize) -> Self { @@ -118,7 +116,7 @@ where Self { defs, ors } } - #[cfg(feature = "with-rand")] + #[cfg(feature = "rand")] #[inline] pub fn with_random_solutions( defs: GpDefinitions, diff --git a/mop-blocks/src/gp/gp_definitions.rs b/mop/src/gp/gp_definitions.rs similarity index 90% rename from mop-blocks/src/gp/gp_definitions.rs rename to mop/src/gp/gp_definitions.rs index a79aec3..0531ffa 100644 --- a/mop-blocks/src/gp/gp_definitions.rs +++ b/mop/src/gp/gp_definitions.rs @@ -1,6 +1,6 @@ use crate::gp::{GpDefinitionsBuilder, NoCstr, OneObj}; use alloc::vec::Vec; -use cl_traits::Storage; +use cl_aux::SingleTypeStorage; pub type MpDefinitions = GpDefinitions; pub type MphDefinitions = GpDefinitions; @@ -58,7 +58,7 @@ impl GpDefinitions { impl GpDefinitions where - HCS: AsRef<[HC]> + Storage, + HCS: AsRef<[HC]> + SingleTypeStorage, { /// Hard constraints #[inline] @@ -77,7 +77,7 @@ impl GpDefinitions { impl GpDefinitions where - OS: AsRef<[O]> + Storage, + OS: AsRef<[O]> + SingleTypeStorage, { /// Objectives #[inline] @@ -88,7 +88,7 @@ where impl GpDefinitions where - SCS: AsRef<[SC]> + Storage, + SCS: AsRef<[SC]> + SingleTypeStorage, { /// Soft constraints #[inline] @@ -108,10 +108,10 @@ where fn default() -> Self { Self { domain: D::default(), - hard_cstrs: Default::default(), - name: Default::default(), + hard_cstrs: <_>::default(), + name: <_>::default(), objs: OS::default(), - soft_cstrs: Default::default(), + soft_cstrs: <_>::default(), } } } diff --git a/mop-blocks/src/gp/gp_definitions_builder.rs b/mop/src/gp/gp_definitions_builder.rs similarity index 87% rename from mop-blocks/src/gp/gp_definitions_builder.rs rename to mop/src/gp/gp_definitions_builder.rs index 0c00bcd..4f5d1e2 100644 --- a/mop-blocks/src/gp/gp_definitions_builder.rs +++ b/mop/src/gp/gp_definitions_builder.rs @@ -1,6 +1,6 @@ use crate::gp::{GpDefinitions, NoCstr, OneObj}; use alloc::vec::Vec; -use cl_traits::{Push, Storage}; +use cl_aux::{Push, SingleTypeStorage}; use core::fmt; pub type MpDefinitionsBuilder = GpDefinitionsBuilder; @@ -42,14 +42,10 @@ impl GpDefinitionsBuilder { HCS: Default, SCS: Default, { - let domain = if let Some(r) = self.domain { - r - } else { + let Some(domain) = self.domain else { return Err(GpDefinitionsBuilderError::NoDomainForDefinitionsBuilder.into()); }; - let objs = if let Some(r) = self.objs { - r - } else { + let Some(objs) = self.objs else { return Err(GpDefinitionsBuilderError::NoObjForDefinitionsBuilder.into()); }; Ok(GpDefinitions { @@ -62,12 +58,14 @@ impl GpDefinitionsBuilder { } #[inline] + #[must_use] pub fn domain(mut self, domain: D) -> Self { self.domain = Some(domain); self } #[inline] + #[must_use] pub fn name(mut self, name: &'static str) -> Self { self.name = name; self @@ -77,6 +75,7 @@ impl GpDefinitionsBuilder { impl GpDefinitionsBuilder { /// Hard constraints #[inline] + #[must_use] pub fn hard_cstrs(mut self, hard_cstrs: HCS) -> Self { self.hard_cstrs = Some(hard_cstrs); self @@ -85,13 +84,13 @@ impl GpDefinitionsBuilder { impl GpDefinitionsBuilder where - HCS: Storage, + HCS: SingleTypeStorage, { /// Push hard constraint #[inline] pub fn push_hard_cstr(mut self, hard_cstr: HC) -> crate::Result where - HCS: Default + Push, + HCS: Default + Push, { if let Some(hcs) = self.hard_cstrs.as_mut() { let _ = hcs.push(hard_cstr).map_err(|_e| crate::Error::InsufficientCapacity)?; @@ -108,15 +107,16 @@ where pub fn push_hard_cstrs(self, hard_cstrs: CI) -> crate::Result where CI: IntoIterator, - HCS: Default + Push, + HCS: Default + Push, { - hard_cstrs.into_iter().try_fold(self, |this, c| this.push_hard_cstr(c)) + hard_cstrs.into_iter().try_fold(self, GpDefinitionsBuilder::push_hard_cstr) } } impl GpDefinitionsBuilder { /// Objective #[inline] + #[must_use] pub fn obj(mut self, obj: O) -> Self { self.objs = Some([obj]); self @@ -125,10 +125,11 @@ impl GpDefinitionsBuilder { impl GpDefinitionsBuilder where - OS: Storage, + OS: SingleTypeStorage, { /// Objectives #[inline] + #[must_use] pub fn objs(mut self, objs: OS) -> Self { self.objs = Some(objs); self @@ -138,7 +139,7 @@ where #[inline] pub fn push_obj(mut self, obj: O) -> crate::Result where - OS: Default + Push, + OS: Default + Push, { if let Some(objs) = self.objs.as_mut() { let _ = objs.push(obj).map_err(|_e| crate::Error::InsufficientCapacity)?; @@ -155,15 +156,16 @@ where pub fn push_objs(self, objs: OI) -> crate::Result where OI: IntoIterator, - OS: Default + Push, + OS: Default + Push, { - objs.into_iter().try_fold(self, |this, o| this.push_obj(o)) + objs.into_iter().try_fold(self, GpDefinitionsBuilder::push_obj) } } impl GpDefinitionsBuilder { /// Soft constraints #[inline] + #[must_use] pub fn soft_cstrs(mut self, soft_cstrs: SCS) -> Self { self.soft_cstrs = Some(soft_cstrs); self @@ -172,13 +174,13 @@ impl GpDefinitionsBuilder { impl GpDefinitionsBuilder where - SCS: Storage, + SCS: SingleTypeStorage, { /// Push soft constraint #[inline] pub fn push_soft_cstr(mut self, soft_cstr: SC) -> crate::Result where - SCS: Default + Push, + SCS: Default + Push, { if let Some(hcs) = self.soft_cstrs.as_mut() { let _ = hcs.push(soft_cstr).map_err(|_e| crate::Error::InsufficientCapacity)?; @@ -195,9 +197,9 @@ where pub fn push_soft_cstrs(self, soft_cstrs: CI) -> crate::Result where CI: IntoIterator, - SCS: Default + Push, + SCS: Default + Push, { - soft_cstrs.into_iter().try_fold(self, |this, c| this.push_soft_cstr(c)) + soft_cstrs.into_iter().try_fold(self, GpDefinitionsBuilder::push_soft_cstr) } } @@ -227,6 +229,6 @@ impl fmt::Display for GpDefinitionsBuilderError { Self::NoDomainForDefinitionsBuilder => "NoDomainForDefinitionsBuilder", Self::NoObjForDefinitionsBuilder => "NoObjForDefinitionsBuilder", }; - write!(f, "{}", s) + write!(f, "{s}") } } diff --git a/mop/src/gp/gp_operations.rs b/mop/src/gp/gp_operations.rs new file mode 100644 index 0000000..bb11eea --- /dev/null +++ b/mop/src/gp/gp_operations.rs @@ -0,0 +1,43 @@ +pub(crate) mod mph_mp_mph; +pub(crate) mod mphs_mp_mphs; + +use crate::{ + gp::{GpDefinitions, MpDefinitionsBuilder}, + Either, Obj, +}; +use cl_aux::{Push, SingleTypeStorage}; + +pub trait GpOperations { + type Error; + + fn convert(a: &AD) -> Result; + + fn transfer(a_defs: &AD, a_rslts: &mut AR, b: &B) -> Result<(), Self::Error>; +} + +#[inline] +pub fn mp_defs_from_gp_defs<'any, D, HCS, NOS, O, OO, OR, OS, S, SCS>( + defs: &'any GpDefinitions, +) -> crate::Result> +where + D: Clone, + NOS: Default + Push, Output = ()>, + O: Obj + 'any, + OR: 'any, + OS: AsRef<[O]> + SingleTypeStorage, + S: 'any, +{ + Ok(MpDefinitionsBuilder { + domain: Some(defs.domain.clone()), + hard_cstrs: Some(<_>::default()), + soft_cstrs: Some(<_>::default()), + name: defs.name, + objs: { + let mut objs: NOS = <_>::default(); + for obj in defs.objs() { + let _ = objs.push(Either::Left(obj)).map_err(|_e| crate::Error::InsufficientCapacity)?; + } + Some(objs) + }, + }) +} diff --git a/mop/src/gp/gp_operations/mph_mp_mph.rs b/mop/src/gp/gp_operations/mph_mp_mph.rs new file mode 100644 index 0000000..958da1e --- /dev/null +++ b/mop/src/gp/gp_operations/mph_mp_mph.rs @@ -0,0 +1,49 @@ +use crate::{ + gp::{GpOperations, GpOrsEvaluators, Mp, MphDefinitions, MphOrs}, + Cstr, ParBounds, +}; +use cl_aux::{Length, Push, SingleTypeStorage}; + +/// Mph -> Mp -> Mph +#[derive(Debug)] +pub struct MphMpMph; + +impl + GpOperations, MphOrs, Mp> + for MphMpMph +where + AOS: ParBounds, + AORS: AsMut<[OR]> + Extend + Length + ParBounds + SingleTypeStorage, + ASS: AsMut<[S]> + ParBounds + Push + SingleTypeStorage, + BORS: AsRef<[OR]> + Length + SingleTypeStorage, + D: ParBounds, + HC: Cstr + ParBounds, + HCRS: AsMut<[usize]> + Extend + Length + ParBounds + SingleTypeStorage, + HCS: AsRef<[HC]> + ParBounds + SingleTypeStorage, + OR: Clone + Default + ParBounds, + S: Clone + ParBounds, + SS: AsRef<[S]> + SingleTypeStorage, +{ + type Error = crate::Error; + + #[inline] + fn convert(_: &MphDefinitions) -> Result, Self::Error> { + Err(Self::Error::UnsupportedConversion) + } + + #[inline] + fn transfer( + a_defs: &MphDefinitions, + a_rslts: &mut MphOrs, + b: &Mp, + ) -> Result<(), Self::Error> { + let mut c = a_rslts.constructor(); + for rslt in b.rslts().iter() { + let ori = rslt.obj_rslts().iter().cloned().rev().skip(1).rev(); + let s = (*rslt.solution()).clone(); + let _ = c.or_os_iter(ori, s); + } + GpOrsEvaluators::eval_hard_cstrs_violations(a_defs, a_rslts); + Ok(()) + } +} diff --git a/mop/src/gp/gp_operations/mphs_mp_mphs.rs b/mop/src/gp/gp_operations/mphs_mp_mphs.rs new file mode 100644 index 0000000..eb67070 --- /dev/null +++ b/mop/src/gp/gp_operations/mphs_mp_mphs.rs @@ -0,0 +1,55 @@ +use crate::{ + gp::{GpOperations, GpOrsEvaluators, Mp, MphsDefinitions, MphsOrs}, + Cstr, ParBounds, +}; +use cl_aux::{Length, Push, SingleTypeStorage}; + +/// Mphs -> Mp -> Mphs +#[derive(Debug)] +pub struct MphsMpMphs; + +impl + GpOperations< + MphsDefinitions, + MphsOrs, + Mp, + > for MphsMpMphs +where + AORS: AsMut<[OR]> + Extend + Length + ParBounds + SingleTypeStorage, + AOS: ParBounds, + ASS: AsMut<[S]> + ParBounds + Push + SingleTypeStorage, + BORS: AsRef<[OR]> + Length + SingleTypeStorage, + D: ParBounds, + HC: Cstr + ParBounds, + HCRS: AsMut<[usize]> + Extend + Length + ParBounds + SingleTypeStorage, + HCS: AsRef<[HC]> + ParBounds + SingleTypeStorage, + OR: Clone + Default + ParBounds, + S: Clone + ParBounds, + SCRS: AsMut<[usize]> + Extend + Length + ParBounds + SingleTypeStorage, + SCS: AsRef<[HC]> + ParBounds + SingleTypeStorage, + SS: AsRef<[S]> + SingleTypeStorage, +{ + type Error = crate::Error; + + #[inline] + fn convert(_: &MphsDefinitions) -> Result, Self::Error> { + Err(Self::Error::UnsupportedConversion) + } + + #[inline] + fn transfer( + a_defs: &MphsDefinitions, + a_rslts: &mut MphsOrs, + b: &Mp, + ) -> Result<(), Self::Error> { + let mut c = a_rslts.constructor(); + for rslt in b.rslts().iter() { + let ori = rslt.obj_rslts().iter().cloned().rev().skip(1).rev(); + let s = (*rslt.solution()).clone(); + let _ = c.or_os_iter(ori, s); + } + GpOrsEvaluators::eval_hard_cstrs_violations(a_defs, a_rslts); + GpOrsEvaluators::eval_soft_cstrs_violations(a_defs, a_rslts); + Ok(()) + } +} diff --git a/mop-blocks/src/gp/gp_or.rs b/mop/src/gp/gp_or.rs similarity index 74% rename from mop-blocks/src/gp/gp_or.rs rename to mop/src/gp/gp_or.rs index 880fc8f..a62fbfe 100644 --- a/mop-blocks/src/gp/gp_or.rs +++ b/mop/src/gp/gp_or.rs @@ -1,29 +1,30 @@ use crate::gp::{NoCstrRslts, OneObj}; use alloc::vec::Vec; -use cl_traits::Storage; +use cl_aux::SingleTypeStorage; -pub type GpOrMut<'a, HCR, OR, S, SCR> = GpOr<&'a mut [HCR], &'a mut [OR], &'a mut S, &'a mut [SCR]>; -pub type GpOrRef<'a, HCR, OR, S, SCR> = GpOr<&'a [HCR], &'a [OR], &'a S, &'a [SCR]>; +pub type GpOrMut<'any, HCR, OR, S, SCR> = + GpOr<&'any mut [HCR], &'any mut [OR], &'any mut S, &'any mut [SCR]>; +pub type GpOrRef<'any, HCR, OR, S, SCR> = GpOr<&'any [HCR], &'any [OR], &'any S, &'any [SCR]>; pub type GpOrVec = GpOr, Vec, S, Vec>; pub type MpOr = GpOr; -pub type MpOrMut<'a, OR, S> = GpOrMut<'a, (), OR, S, ()>; -pub type MpOrRef<'a, OR, S> = GpOrRef<'a, (), OR, S, ()>; +pub type MpOrMut<'any, OR, S> = GpOrMut<'any, (), OR, S, ()>; +pub type MpOrRef<'any, OR, S> = GpOrRef<'any, (), OR, S, ()>; pub type MpOrVec = MpOr, S>; pub type MphOr = GpOr; -pub type MphOrMut<'a, OR, S> = GpOrMut<'a, usize, OR, S, ()>; -pub type MphOrRef<'a, OR, S> = GpOrRef<'a, usize, OR, S, ()>; +pub type MphOrMut<'any, OR, S> = GpOrMut<'any, usize, OR, S, ()>; +pub type MphOrRef<'any, OR, S> = GpOrRef<'any, usize, OR, S, ()>; pub type MphOrVec = MphOr, Vec, S>; pub type MphsOr = GpOr; -pub type MphsOrMut<'a, OR, S> = GpOrMut<'a, usize, OR, S, usize>; -pub type MphsOrRef<'a, OR, S> = GpOrRef<'a, usize, OR, S, usize>; +pub type MphsOrMut<'any, OR, S> = GpOrMut<'any, usize, OR, S, usize>; +pub type MphsOrRef<'any, OR, S> = GpOrRef<'any, usize, OR, S, usize>; pub type MphsOrVec = MphsOr, Vec, S, Vec>; pub type SpOr = GpOr, S, NoCstrRslts>; -pub type SpOrMut<'a, OR, S> = GpOrMut<'a, (), OR, S, ()>; -pub type SpOrRef<'a, OR, S> = GpOrRef<'a, (), OR, S, ()>; +pub type SpOrMut<'any, OR, S> = GpOrMut<'any, (), OR, S, ()>; +pub type SpOrRef<'any, OR, S> = GpOrRef<'any, (), OR, S, ()>; /// GP-OR (Generic Problem - Optimization Result) /// @@ -34,7 +35,7 @@ pub type SpOrRef<'a, OR, S> = GpOrRef<'a, (), OR, S, ()>; /// * `CRS`: Constraint Results Storage /// * `ORS`: Objective Results Storage /// * `S`: Solution -#[cfg_attr(feature = "with-serde", derive(serde::Deserialize, serde::Serialize))] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[derive(Clone, Debug, PartialEq)] pub struct GpOr { pub(crate) hard_cstr_rslts: HCRS, @@ -79,7 +80,7 @@ impl GpOr { impl GpOr where - ORS: AsRef<[OR]> + Storage, + ORS: AsRef<[OR]> + SingleTypeStorage, { #[inline] pub fn obj_rslts(&self) -> &[OR] { @@ -107,7 +108,7 @@ where GpOr { hard_cstr_rslts: self.hard_cstr_rslts.to_vec(), obj_rslts: self.obj_rslts.to_vec(), - soft_cstr_rslts: Default::default(), + soft_cstr_rslts: <_>::default(), solution: self.solution.clone(), } } diff --git a/mop-blocks/src/gp/gp_ors.rs b/mop/src/gp/gp_ors.rs similarity index 61% rename from mop-blocks/src/gp/gp_ors.rs rename to mop/src/gp/gp_ors.rs index f1cf896..a5ddcb0 100644 --- a/mop-blocks/src/gp/gp_ors.rs +++ b/mop/src/gp/gp_ors.rs @@ -5,30 +5,32 @@ use crate::{ gp::{GpDefinitions, GpOrMut, GpOrRef, GpOrsConstructor, NoCstrRslts}, }; use alloc::vec::Vec; -use cl_traits::{Clear, Remove, Storage, Truncate, WithCapacity}; +use cl_aux::{Clear, Remove, SingleTypeStorage, Truncate, WithCapacity}; +#[cfg(feature = "rayon")] +use rayon::prelude::*; -pub type GpOrsMut<'a, HCR, OR, S, SCR> = - GpOrs<&'a mut [HCR], &'a mut [OR], &'a mut [SCR], &'a mut [S]>; -pub type GpOrsRef<'a, HCR, OR, S, SCR> = GpOrs<&'a [HCR], &'a [OR], &'a [SCR], &'a [S]>; +pub type GpOrsMut<'any, HCR, OR, S, SCR> = + GpOrs<&'any mut [HCR], &'any mut [OR], &'any mut [SCR], &'any mut [S]>; +pub type GpOrsRef<'any, HCR, OR, S, SCR> = GpOrs<&'any [HCR], &'any [OR], &'any [SCR], &'any [S]>; pub type MpOrs = GpOrs; -pub type MpOrsMut<'a, OR, S> = GpOrsMut<'a, (), OR, S, ()>; -pub type MpOrsRef<'a, OR, S> = GpOrsRef<'a, (), OR, S, ()>; +pub type MpOrsMut<'any, OR, S> = GpOrsMut<'any, (), OR, S, ()>; +pub type MpOrsRef<'any, OR, S> = GpOrsRef<'any, (), OR, S, ()>; pub type MpOrsVec = MpOrs, Vec>; pub type MphOrs = GpOrs; -pub type MphOrsMut<'a, OR, S> = GpOrsMut<'a, usize, OR, S, ()>; -pub type MphOrsRef<'a, OR, S> = GpOrsRef<'a, usize, OR, S, ()>; +pub type MphOrsMut<'any, OR, S> = GpOrsMut<'any, usize, OR, S, ()>; +pub type MphOrsRef<'any, OR, S> = GpOrsRef<'any, usize, OR, S, ()>; pub type MphOrsVec = MphOrs, Vec, Vec>; pub type MphsOrs = GpOrs; -pub type MphsOrsMut<'a, OR, S> = GpOrsMut<'a, usize, OR, S, ()>; -pub type MphsOrsRef<'a, OR, S> = GpOrsRef<'a, usize, OR, S, ()>; +pub type MphsOrsMut<'any, OR, S> = GpOrsMut<'any, usize, OR, S, ()>; +pub type MphsOrsRef<'any, OR, S> = GpOrsRef<'any, usize, OR, S, ()>; pub type MphsOrsVec = MphsOrs, Vec, Vec, Vec>; pub type SpOrs = GpOrs; -pub type SpOrsMut<'a, OR, S> = GpOrsRef<'a, (), OR, S, ()>; -pub type SpOrsRef<'a, OR, S> = GpOrsMut<'a, (), OR, S, ()>; +pub type SpOrsMut<'any, OR, S> = GpOrsRef<'any, (), OR, S, ()>; +pub type SpOrsRef<'any, OR, S> = GpOrsMut<'any, (), OR, S, ()>; pub type SpOrsVec = SpOrs, Vec>; /// MPH-ORS (Multi-objective Problem with Hard constraint - Optimization ResultS) @@ -67,10 +69,10 @@ impl GpOrs { #[inline] pub fn truncate(&mut self, until_idx: usize) where - HCRS: Truncate, - ORS: Truncate, - SCRS: Truncate, - SS: Truncate, + HCRS: Truncate, + ORS: Truncate, + SCRS: Truncate, + SS: Truncate, { self.hard_cstr_rslts.truncate(until_idx); self.obj_rslts.truncate(until_idx); @@ -86,10 +88,10 @@ impl GpOrs { impl GpOrs where - HCRS: Storage, - ORS: Storage, - SCRS: Storage, - SS: Storage, + HCRS: SingleTypeStorage, + ORS: SingleTypeStorage, + SCRS: SingleTypeStorage, + SS: SingleTypeStorage, { #[inline] pub fn constructor(&mut self) -> GpOrsConstructor<'_, HCRS, ORS, SCRS, SS> { @@ -104,10 +106,10 @@ where impl GpOrs where - HCRS: AsMut<[HCR]> + Storage, - ORS: AsMut<[OR]> + Storage, - SCRS: AsMut<[SCR]> + Storage, - SS: AsMut<[S]> + Storage, + HCRS: AsMut<[HCR]> + SingleTypeStorage, + ORS: AsMut<[OR]> + SingleTypeStorage, + SCRS: AsMut<[SCR]> + SingleTypeStorage, + SS: AsMut<[S]> + SingleTypeStorage, { #[inline] pub fn get_mut(&mut self, idx: usize) -> Option> { @@ -145,12 +147,12 @@ where } #[inline] - pub fn iter_mut<'a>(&'a mut self) -> impl Iterator> + pub fn iter_mut<'any>(&'any mut self) -> impl Iterator> where - HCR: 'a, - OR: 'a, - S: 'a, - SCR: 'a, + HCR: 'any, + OR: 'any, + S: 'any, + SCR: 'any, { self .hard_cstr_rslts @@ -169,14 +171,39 @@ where }) } + #[inline] + #[cfg(feature = "rayon")] + pub fn par_iter_mut<'any>( + &'any mut self, + ) -> impl IndexedParallelIterator> + where + HCR: Send + Sync + 'any, + OR: Send + Sync + 'any, + S: Send + Sync + 'any, + SCR: Send + Sync + 'any, + { + self + .hard_cstr_rslts + .row_par_iter_mut() + .zip_eq(self.obj_rslts.row_par_iter_mut().zip_eq( + self.soft_cstr_rslts.row_par_iter_mut().zip(self.solutions.as_mut().par_iter_mut()), + )) + .map(|(hard_cstr_rslts, (obj_rslts, (soft_cstr_rslts, solution)))| GpOrMut { + hard_cstr_rslts, + obj_rslts, + soft_cstr_rslts, + solution, + }) + } + #[inline] #[must_use] pub fn remove(&mut self, idx: usize) -> bool where - HCRS: Truncate, - SCRS: Truncate, - ORS: Truncate, - SS: Remove, + HCRS: Truncate, + SCRS: Truncate, + ORS: Truncate, + SS: Remove, { if idx >= self.rslts_num() { return false; @@ -184,7 +211,7 @@ where let _ = self.hard_cstr_rslts.remove_row(idx); let _ = self.obj_rslts.remove_row(idx); let _ = self.soft_cstr_rslts.remove_row(idx); - let _ = self.solutions.remove(idx); + let _rslt = self.solutions.remove(idx); true } @@ -204,10 +231,10 @@ where impl GpOrs where - HCRS: AsRef<[HCR]> + Storage, - ORS: AsRef<[OR]> + Storage, - SCRS: AsRef<[SCR]> + Storage, - SS: AsRef<[S]> + Storage, + HCRS: AsRef<[HCR]> + SingleTypeStorage, + ORS: AsRef<[OR]> + SingleTypeStorage, + SCRS: AsRef<[SCR]> + SingleTypeStorage, + SS: AsRef<[S]> + SingleTypeStorage, { #[inline] pub fn as_ref(&self) -> GpOrsRef<'_, HCR, OR, S, SCR> { @@ -230,12 +257,12 @@ where } #[inline] - pub fn iter<'a>(&'a self) -> impl Iterator> + pub fn iter<'any>(&'any self) -> impl Iterator> where - HCR: 'a, - OR: 'a, - S: 'a, - SCR: 'a, + HCR: 'any, + OR: 'any, + S: 'any, + SCR: 'any, { self .hard_cstr_rslts @@ -253,14 +280,42 @@ where solution, }) } + + #[inline] + #[cfg(feature = "rayon")] + pub fn par_iter<'any>( + &'any self, + ) -> impl IndexedParallelIterator> + where + HCR: Send + Sync + 'any, + OR: Send + Sync + 'any, + S: Send + Sync + 'any, + SCR: Send + Sync + 'any, + { + self + .hard_cstr_rslts + .row_par_iter() + .zip_eq( + self + .obj_rslts + .row_par_iter() + .zip_eq(self.soft_cstr_rslts.row_par_iter().zip(self.solutions.as_ref().par_iter())), + ) + .map(|(hard_cstr_rslts, (obj_rslts, (soft_cstr_rslts, solution)))| GpOrRef { + hard_cstr_rslts, + obj_rslts, + soft_cstr_rslts, + solution, + }) + } } impl GpOrs where - HCRS: Storage + WithCapacity, - ORS: Storage + WithCapacity, - SCRS: Storage + WithCapacity, - SS: Storage + WithCapacity, + HCRS: SingleTypeStorage + WithCapacity, + ORS: SingleTypeStorage + WithCapacity, + SCRS: SingleTypeStorage + WithCapacity, + SS: SingleTypeStorage + WithCapacity, { #[inline] pub fn with_capacity( @@ -268,9 +323,9 @@ where rslts_num: usize, ) -> Self where - HCS: AsRef<[HC]> + Storage, - OS: AsRef<[O]> + Storage, - SCS: AsRef<[SC]> + Storage, + HCS: AsRef<[HC]> + SingleTypeStorage, + OS: AsRef<[O]> + SingleTypeStorage, + SCS: AsRef<[SC]> + SingleTypeStorage, { let hard_cstr_rslts = DrMatrix::with_capacity(rslts_num, defs.hard_cstrs().len()); let obj_rslts = DrMatrix::with_capacity(rslts_num, defs.objs().len()); diff --git a/mop-blocks/src/gp/gp_ors_constructor.rs b/mop/src/gp/gp_ors_constructor.rs similarity index 54% rename from mop-blocks/src/gp/gp_ors_constructor.rs rename to mop/src/gp/gp_ors_constructor.rs index cd81255..67a1a17 100644 --- a/mop-blocks/src/gp/gp_ors_constructor.rs +++ b/mop/src/gp/gp_ors_constructor.rs @@ -2,13 +2,17 @@ use crate::{ dr_matrix::DrMatrixRowsConstructor, gp::{GpOrRef, GpOrsRef, NoCstrRslts}, }; -use cl_traits::{Length, Push, Storage}; +use cl_aux::{Length, Push, SingleTypeStorage}; use core::iter::Extend; -pub type MpOrsConstructor<'a, ORS, SS> = GpOrsConstructor<'a, NoCstrRslts, ORS, NoCstrRslts, SS>; -pub type MphOrsConstructor<'a, HCRS, ORS, SS> = GpOrsConstructor<'a, HCRS, ORS, NoCstrRslts, SS>; -pub type MphsOrsConstructor<'a, HCRS, ORS, SCRS, SS> = GpOrsConstructor<'a, HCRS, ORS, SCRS, SS>; -pub type SpOrsConstructor<'a, ORS, SS> = GpOrsConstructor<'a, NoCstrRslts, ORS, NoCstrRslts, SS>; +pub type MpOrsConstructor<'any, ORS, SS> = + GpOrsConstructor<'any, NoCstrRslts, ORS, NoCstrRslts, SS>; +pub type MphOrsConstructor<'any, HCRS, ORS, SS> = + GpOrsConstructor<'any, HCRS, ORS, NoCstrRslts, SS>; +pub type MphsOrsConstructor<'any, HCRS, ORS, SCRS, SS> = + GpOrsConstructor<'any, HCRS, ORS, SCRS, SS>; +pub type SpOrsConstructor<'any, ORS, SS> = + GpOrsConstructor<'any, NoCstrRslts, ORS, NoCstrRslts, SS>; /// Constructor for MPH-OR /// @@ -17,38 +21,38 @@ pub type SpOrsConstructor<'a, ORS, SS> = GpOrsConstructor<'a, NoCstrRslts, ORS, /// * `ORS`: Objective Results Storage /// * `S`: Solution #[derive(Debug, PartialEq)] -pub struct GpOrsConstructor<'a, HCRS, ORS, SCRS, SS> { - pub(crate) hard_cstr_rslts: DrMatrixRowsConstructor<'a, HCRS>, - pub(crate) obj_rslts: DrMatrixRowsConstructor<'a, ORS>, - pub(crate) soft_cstr_rslts: DrMatrixRowsConstructor<'a, SCRS>, - pub(crate) solutions: &'a mut SS, +pub struct GpOrsConstructor<'any, HCRS, ORS, SCRS, SS> { + pub(crate) hard_cstr_rslts: DrMatrixRowsConstructor<'any, HCRS>, + pub(crate) obj_rslts: DrMatrixRowsConstructor<'any, ORS>, + pub(crate) soft_cstr_rslts: DrMatrixRowsConstructor<'any, SCRS>, + pub(crate) solutions: &'any mut SS, } -impl<'a, HCR, HCRS, OR, ORS, S, SCR, SCRS, SS> GpOrsConstructor<'a, HCRS, ORS, SCRS, SS> +impl GpOrsConstructor<'_, HCRS, ORS, SCRS, SS> where HCR: Clone, - HCRS: Extend + Storage, + HCRS: Extend + SingleTypeStorage, OR: Clone, - ORS: Extend + Storage, + ORS: Extend + SingleTypeStorage, SCR: Clone, - SCRS: Extend + Storage, - SS: Storage, + SCRS: Extend + SingleTypeStorage, + SS: SingleTypeStorage, { #[inline] - pub fn or_ref(mut self, from: GpOrRef<'_, HCR, OR, S, SCR>) -> Option + pub fn or_ref(mut self, from: &GpOrRef<'_, HCR, OR, S, SCR>) -> Option where S: Clone, - SS: Push, + SS: Push, { self.hard_cstr_rslts = self.hard_cstr_rslts.row_slice(from.hard_cstr_rslts)?; self.obj_rslts = self.obj_rslts.row_slice(from.obj_rslts)?; self.soft_cstr_rslts = self.soft_cstr_rslts.row_slice(from.soft_cstr_rslts)?; - let _ = self.solutions.push(from.solution.clone()); + self.solutions.push(from.solution.clone()).ok()?; Some(self) } #[inline] - pub fn ors_ref(mut self, other: GpOrsRef<'_, HCR, OR, S, SCR>) -> Option + pub fn ors_ref(mut self, other: &GpOrsRef<'_, HCR, OR, S, SCR>) -> Option where S: Clone, SS: Extend, @@ -67,27 +71,27 @@ where OR: Default, SCR: Default, SI: Iterator>, - SS: Push, + SS: Push, { for solution in si { self.hard_cstr_rslts = self.hard_cstr_rslts.fill_row(HCR::default()); self.obj_rslts = self.obj_rslts.fill_row(OR::default()); self.soft_cstr_rslts = self.soft_cstr_rslts.fill_row(SCR::default()); - let _ = self.solutions.push(solution.ok()?); + let _ = self.solutions.push(solution.ok()?).ok()?; } Some(self) } } -impl<'a, HCR, HCRS, OR, ORS, S, SCR, SCRS, SS> GpOrsConstructor<'a, HCRS, ORS, SCRS, SS> +impl GpOrsConstructor<'_, HCRS, ORS, SCRS, SS> where OR: Default, - ORS: Extend + Length + Storage, - SS: Push + Storage, + ORS: Extend + Length + SingleTypeStorage, + SS: Push + SingleTypeStorage, HCR: Default, - HCRS: Extend + Length + Storage, + HCRS: Extend + Length + SingleTypeStorage, SCR: Default, - SCRS: Extend + Length + Storage, + SCRS: Extend + Length + SingleTypeStorage, { #[inline] pub fn or_hcos_iter(&mut self, hcri: HCRI, ori: ORI, solution: S) -> &mut Self @@ -95,7 +99,7 @@ where HCRI: Iterator, ORI: Iterator, { - let scri = (0..self.soft_cstr_rslts.cols).map(|_| Default::default()); + let scri = (0..self.soft_cstr_rslts.cols).map(|_| <_>::default()); self.or_hcossc_iter(hcri, ori, solution, scri) } @@ -115,7 +119,7 @@ where let _ = self.hard_cstr_rslts.row_iter(hcri); let _ = self.obj_rslts.row_iter(ori); let _ = self.soft_cstr_rslts.row_iter(scri); - let _ = self.solutions.push(s); + let _rslt = self.solutions.push(s); self } @@ -124,8 +128,8 @@ where where ORI: Iterator, { - let hcri = (0..self.hard_cstr_rslts.cols).map(|_| Default::default()); - let scri = (0..self.soft_cstr_rslts.cols).map(|_| Default::default()); + let hcri = (0..self.hard_cstr_rslts.cols).map(|_| <_>::default()); + let scri = (0..self.soft_cstr_rslts.cols).map(|_| <_>::default()); self.or_hcossc_iter(hcri, ori, solution, scri) } } diff --git a/mop/src/gp/gp_ors_evaluators.rs b/mop/src/gp/gp_ors_evaluators.rs new file mode 100644 index 0000000..dbd4add --- /dev/null +++ b/mop/src/gp/gp_ors_evaluators.rs @@ -0,0 +1,190 @@ +use crate::{ + dr_matrix::DrMatrixVec, + gp::{GpDefinitions, GpOrMut, GpOrRef, GpOrs}, + Cstr, Obj, ParBounds, +}; +use alloc::string::String; +use cl_aux::SingleTypeStorage; +use core::{fmt::Debug, marker::PhantomData}; +#[cfg(feature = "rayon")] +use rayon::prelude::*; + +#[derive(Debug)] +pub struct GpOrsEvaluators { + phantom: PhantomData<(D, HCRS, HCS, ORS, OS, SCRS, SCS, SS)>, +} + +impl + GpOrsEvaluators +where + D: ParBounds, + HCRS: ParBounds, + HCS: ParBounds, + OR: ParBounds, + ORS: AsMut<[OR]> + ParBounds + SingleTypeStorage, + OS: ParBounds, + S: ParBounds, + SCRS: ParBounds, + SCS: ParBounds, + SS: AsMut<[S]> + ParBounds + SingleTypeStorage, +{ + #[inline] + pub fn eval_hard_cstrs_violations( + defs: &GpDefinitions, + rslts: &mut GpOrs, + ) where + HC: Cstr + ParBounds, + HCRS: AsMut<[usize]> + SingleTypeStorage, + HCS: AsRef<[HC]> + SingleTypeStorage, + SCR: ParBounds, + SCRS: AsMut<[SCR]> + SingleTypeStorage, + { + let hard_cstrs = defs.hard_cstrs(); + Self::eval_cstrs_rslts(hard_cstrs, rslts, |rslt| (rslt.hard_cstr_rslts, rslt.solution)); + } + + #[inline] + pub fn eval_soft_cstrs_violations( + defs: &GpDefinitions, + rslts: &mut GpOrs, + ) where + HCR: ParBounds, + HCRS: AsMut<[HCR]> + SingleTypeStorage, + SC: Cstr, + SCRS: AsMut<[usize]> + SingleTypeStorage, + SC: ParBounds, + SCS: AsRef<[SC]> + SingleTypeStorage, + { + let soft_cstrs = defs.soft_cstrs(); + Self::eval_cstrs_rslts(soft_cstrs, rslts, |rslt| (rslt.soft_cstr_rslts, rslt.solution)); + } + + #[inline] + fn eval_cstrs_rslts(cstrs: &[C], rslts: &mut GpOrs, cb: F) + where + C: Cstr + ParBounds, + F: Fn(GpOrMut<'_, HCR, OR, S, SCR>) -> (&mut [usize], &S) + ParBounds, + HCR: ParBounds, + HCRS: AsMut<[HCR]> + SingleTypeStorage, + SCR: ParBounds, + SCRS: AsMut<[SCR]> + SingleTypeStorage, + { + let func = |rslt| { + let (hard_cstr_rslts, solution) = cb(rslt); + for (hard_cstr, hard_cstr_rslt) in cstrs.iter().zip(hard_cstr_rslts.iter_mut()) { + *hard_cstr_rslt = hard_cstr.violations(solution); + } + }; + #[cfg(not(feature = "rayon"))] + rslts.iter_mut().for_each(func); + #[cfg(feature = "rayon")] + rslts.par_iter_mut().for_each(func); + } +} + +impl + GpOrsEvaluators +where + D: ParBounds, + HCR: ParBounds, + HCRS: AsRef<[HCR]> + ParBounds + SingleTypeStorage, + HCS: ParBounds, + OR: ParBounds, + ORS: AsRef<[OR]> + ParBounds + SingleTypeStorage, + OS: ParBounds, + S: ParBounds, + SCR: ParBounds, + SCRS: AsRef<[SCR]> + ParBounds + SingleTypeStorage, + SCS: ParBounds, + SS: AsRef<[S]> + ParBounds + SingleTypeStorage, +{ + #[inline] + pub fn eval_hard_cstrs_reasons( + defs: &GpDefinitions, + rslts: &mut GpOrs, + ) -> DrMatrixVec + where + HC: Cstr + ParBounds, + HCS: AsRef<[HC]> + SingleTypeStorage, + { + let cols = rslts.hard_cstr_rslts.cols(); + let rows = rslts.hard_cstr_rslts.rows(); + Self::eval_cstrs_reasons([rows, cols], defs.hard_cstrs(), rslts) + } + + #[inline] + pub fn eval_soft_cstrs_reasons( + defs: &GpDefinitions, + rslts: &mut GpOrs, + ) -> DrMatrixVec + where + SC: Cstr + ParBounds, + SCS: AsRef<[SC]> + SingleTypeStorage, + { + let cols = rslts.soft_cstr_rslts.cols(); + let rows = rslts.soft_cstr_rslts.rows(); + Self::eval_cstrs_reasons([rows, cols], defs.soft_cstrs(), rslts) + } + + #[inline] + fn eval_cstrs_reasons( + [rows, cols]: [usize; 2], + cstrs: &[C], + rslts: &mut GpOrs, + ) -> DrMatrixVec + where + C: Cstr + ParBounds, + { + let mut reasons = DrMatrixVec::with_capacity(rows, cols); + let _ = reasons.constructor().fill_rows(rows, String::with_capacity(256)); + let func = |(strings, rslt): (&mut [String], GpOrRef<'_, _, _, _, _>)| { + for (c, r) in cstrs.iter().zip(strings.iter_mut()) { + *r = c.reasons(rslt.solution); + } + }; + #[cfg(feature = "rayon")] + reasons.row_par_iter_mut().zip_eq(rslts.par_iter()).for_each(func); + #[cfg(not(feature = "rayon"))] + reasons.row_iter_mut().zip(rslts.iter()).for_each(func); + reasons + } +} + +impl + GpOrsEvaluators +where + D: ParBounds, + HCR: ParBounds, + HCRS: AsMut<[HCR]> + ParBounds + SingleTypeStorage, + HCS: ParBounds, + O: Obj + ParBounds, + OR: ParBounds, + ORS: AsMut<[OR]> + ParBounds + SingleTypeStorage, + OS: AsRef<[O]> + ParBounds + SingleTypeStorage, + S: ParBounds, + SCR: ParBounds, + SCRS: AsMut<[SCR]> + ParBounds + SingleTypeStorage, + SCS: ParBounds, + SS: AsMut<[S]> + ParBounds + SingleTypeStorage, +{ + #[inline] + pub fn eval_objs(defs: &GpDefinitions, rslts: &mut GpOrs) { + let func = |mut r| Self::eval_objs_for_solution(defs.objs(), &mut r); + #[cfg(feature = "rayon")] + rslts.par_iter_mut().for_each(func); + #[cfg(not(feature = "rayon"))] + rslts.iter_mut().for_each(func); + } + + #[inline] + fn eval_objs_for_solution(objs: &[O], rslt: &mut GpOrMut<'_, HCR, OR, S, SCR>) { + let func = |(obj, obj_rslts): (&O, &mut OR)| { + let or = obj.result(rslt.solution); + *obj_rslts = or; + }; + #[cfg(feature = "rayon")] + objs.par_iter().zip_eq(rslt.obj_rslts.par_iter_mut()).for_each(func); + #[cfg(not(feature = "rayon"))] + objs.iter().zip(rslt.obj_rslts.iter_mut()).for_each(func); + } +} diff --git a/mop/src/lib.rs b/mop/src/lib.rs index c11b705..997df39 100644 --- a/mop/src/lib.rs +++ b/mop/src/lib.rs @@ -1,8 +1,48 @@ -//! MOP (*M*any *OP*timizations) +//! Mop (Many Optimizations) #![cfg_attr(not(feature = "std"), no_std)] -pub extern crate mop_blocks as blocks; -pub extern crate mop_facades as facades; -#[cfg(feature = "with-mop-solvers")] -pub extern crate mop_solvers as solvers; +extern crate alloc; + +mod criteria; +pub mod doc_tests; +mod domain; +pub mod dr_matrix; +mod either; +mod error; +#[cfg(all(not(feature = "rayon"), feature = "wasm-bindgen"))] +pub mod wasm_bindgen; + +pub mod gp; +mod obj_direction; +pub mod objs; +pub mod opt; +mod par_bounds; +mod pct; +pub mod quality_comparator; +mod solution; +mod solver; +#[cfg(feature = "solvers")] +pub mod solvers; +pub mod utils; + +pub use criteria::{cstr::*, obj::*}; +pub use domain::*; +pub use either::Either; +pub use error::*; +pub use obj_direction::*; +pub use par_bounds::ParBounds; +pub use pct::*; +pub use solution::*; +pub use solver::Solver; + +pub type Result = core::result::Result; + +#[cfg(feature = "rayon")] +#[derive(Debug)] +pub struct ParallelIteratorWrapper(pub(crate) I); + +#[cfg(feature = "rayon")] +/// Parallel producer for Rayon implementation. This is mostly an internal detail. +#[derive(Debug)] +pub struct ParallelProducerWrapper(pub(crate) I); diff --git a/mop-blocks/src/obj_direction.rs b/mop/src/obj_direction.rs similarity index 100% rename from mop-blocks/src/obj_direction.rs rename to mop/src/obj_direction.rs diff --git a/mop/src/objs.rs b/mop/src/objs.rs new file mode 100644 index 0000000..f010fbf --- /dev/null +++ b/mop/src/objs.rs @@ -0,0 +1,5 @@ +mod min_cstrs_rslts; +mod min_weighted_sum; + +pub use min_cstrs_rslts::*; +pub use min_weighted_sum::*; diff --git a/mop-blocks/src/objs/min_cstrs_rslts.rs b/mop/src/objs/min_cstrs_rslts.rs similarity index 62% rename from mop-blocks/src/objs/min_cstrs_rslts.rs rename to mop/src/objs/min_cstrs_rslts.rs index cebed6b..68ac68c 100644 --- a/mop-blocks/src/objs/min_cstrs_rslts.rs +++ b/mop/src/objs/min_cstrs_rslts.rs @@ -1,6 +1,5 @@ use crate::{gp::GpDefinitions, Cstr, Obj, ObjDirection}; use core::{fmt::Debug, iter::Chain, slice::Iter}; -use mop_common::TraitCfg; use num_traits::{Bounded, NumCast}; #[derive(Debug)] @@ -15,9 +14,9 @@ impl MinCstrsRslts { } } -impl<'a, C> MinCstrsRslts> { +impl<'any, C> MinCstrsRslts> { #[inline] - pub fn from_gp_hcs(defs: &'a GpDefinitions) -> Self + pub fn from_gp_hcs(defs: &'any GpDefinitions) -> Self where HCS: AsRef<[C]>, { @@ -25,9 +24,9 @@ impl<'a, C> MinCstrsRslts> { } } -impl<'a, C> MinCstrsRslts, Iter<'a, C>>> { +impl<'any, C> MinCstrsRslts, Iter<'any, C>>> { #[inline] - pub fn from_gp_hcs_and_scs(defs: &'a GpDefinitions) -> Self + pub fn from_gp_hcs_and_scs(defs: &'any GpDefinitions) -> Self where HCS: AsRef<[C]>, SCS: AsRef<[C]>, @@ -41,7 +40,7 @@ impl<'a, C> MinCstrsRslts, Iter<'a, C>>> { impl Obj for MinCstrsRslts where C: Cstr, - CI: Clone + Iterator + TraitCfg, + CI: Clone + Iterator, OR: Bounded + NumCast, { #[inline] @@ -55,15 +54,3 @@ where OR::from(sum).unwrap_or_else(OR::max_value) } } - -impl<'a, C, CI, OR, S> From<&'a MinCstrsRslts> for &'a dyn Obj -where - C: Cstr, - CI: Clone + Iterator + TraitCfg, - OR: Bounded + NumCast, -{ - #[inline] - fn from(f: &'a MinCstrsRslts) -> Self { - f - } -} diff --git a/mop-blocks/src/objs/min_weighted_sum.rs b/mop/src/objs/min_weighted_sum.rs similarity index 64% rename from mop-blocks/src/objs/min_weighted_sum.rs rename to mop/src/objs/min_weighted_sum.rs index 19b900d..e71a4dc 100644 --- a/mop-blocks/src/objs/min_weighted_sum.rs +++ b/mop/src/objs/min_weighted_sum.rs @@ -1,11 +1,10 @@ use crate::{gp::Gp, Obj, ObjDirection}; -use cl_traits::Storage; +use cl_aux::SingleTypeStorage; use core::{ iter::Sum, ops::{Add, Div}, slice::Iter, }; -use mop_common::TraitCfg; use num_traits::One; #[derive(Debug)] @@ -21,14 +20,14 @@ impl MinWeightedSum { } } -impl<'a, O, WI> MinWeightedSum, WI> { +impl<'any, O, WI> MinWeightedSum, WI> { #[inline] pub fn from_gp( - mp: &'a Gp, + mp: &'any Gp, weights: WI, ) -> Self where - OS: AsRef<[O]> + Storage, + OS: AsRef<[O]> + SingleTypeStorage, { Self { objs: mp.defs().objs().as_ref().iter(), weights } } @@ -38,8 +37,8 @@ impl Obj for MinWeightedSum where O: Obj, OR: Add + Div + One + Sum, - OI: Clone + Iterator + TraitCfg, - WI: Clone + Iterator + TraitCfg, + OI: Clone + Iterator, + WI: Clone + Iterator, { #[inline] fn obj_direction(&self) -> ObjDirection { @@ -63,16 +62,3 @@ where .sum() } } - -impl<'a, O, OR, OI, S, WI> From<&'a MinWeightedSum> for &'a dyn Obj -where - O: Obj, - OR: Add + Div + One + Sum, - OI: Clone + Iterator + TraitCfg, - WI: Clone + Iterator + TraitCfg, -{ - #[inline] - fn from(f: &'a MinWeightedSum) -> Self { - f - } -} diff --git a/mop-facades/src/opt.rs b/mop/src/opt.rs similarity index 100% rename from mop-facades/src/opt.rs rename to mop/src/opt.rs diff --git a/mop-facades/src/opt/opt_facade.rs b/mop/src/opt/opt_facade.rs similarity index 88% rename from mop-facades/src/opt/opt_facade.rs rename to mop/src/opt/opt_facade.rs index badee8c..20779f6 100644 --- a/mop-facades/src/opt/opt_facade.rs +++ b/mop/src/opt/opt_facade.rs @@ -1,18 +1,17 @@ -use crate::opt::OptHooks; +use crate::{ + gp::{Gp, GpOrRef}, + opt::OptHooks, + quality_comparator::QualityComparator, + Domain, Obj, ObjDirection, Pct, Solution, Solver, +}; use alloc::vec::Vec; -use cl_traits::{Length, Storage}; +use cl_aux::{Length, SingleTypeStorage}; use core::{ fmt::Debug, iter::Sum, marker::PhantomData, ops::{Div, Sub}, }; -use mop_blocks::{ - gp::{Gp, GpOrRef}, - quality_comparator::QualityComparator, - Domain, Obj, ObjDirection, Pct, Solution, -}; -use mop_common::Solver; use num_traits::{NumCast, One, Zero}; #[cfg(feature = "std")] use {core::time::Duration, std::time::Instant}; @@ -34,7 +33,7 @@ pub struct OptFacade { impl OptFacade where - HCRS: AsMut<[HCR]> + AsRef<[HCR]> + Storage, + HCRS: AsMut<[HCR]> + AsRef<[HCR]> + SingleTypeStorage, D: Domain, O: Obj, OH: OptHooks>, @@ -46,12 +45,12 @@ where + Sub + Zero + Sum, - SCRS: AsMut<[SCR]> + AsRef<[SCR]> + Storage, - ORS: AsMut<[OR]> + AsRef<[OR]> + Storage, - OS: AsMut<[O]> + AsRef<[O]> + Storage, - QC: for<'a> QualityComparator<[O], GpOrRef<'a, HCR, OR, S, SCR>>, + SCRS: AsMut<[SCR]> + AsRef<[SCR]> + SingleTypeStorage, + ORS: AsMut<[OR]> + AsRef<[OR]> + SingleTypeStorage, + OS: AsMut<[O]> + AsRef<[O]> + SingleTypeStorage, + QC: for<'any> QualityComparator<[O], GpOrRef<'any, HCR, OR, S, SCR>>, S: Solution, - SS: AsMut<[S]> + AsRef<[S]> + Length + Storage, + SS: AsMut<[S]> + AsRef<[S]> + Length + SingleTypeStorage, { #[inline] pub fn new(max_iterations: usize) -> Self { @@ -107,6 +106,7 @@ where #[cfg(feature = "std")] #[inline] + #[must_use] pub fn set_max_duration(mut self, max_duration: Duration) -> Self { self.time_opt = Some(Time { current_duration: Instant::now(), max_duration }); self @@ -114,18 +114,21 @@ where /// The maximum number of times the solver will process the solution #[inline] + #[must_use] pub fn set_max_iterations(mut self, max_iterations: usize) -> Self { self.max_iterations = max_iterations; self } #[inline] + #[must_use] pub fn set_objs_goals(mut self, objs_goals: Vec) -> Self { self.objs_goals = objs_goals; self } #[inline] + #[must_use] pub fn set_opt_hooks(mut self, opt_hooks: OH) -> Self { self.opt_hooks_opt = Some(opt_hooks); self @@ -133,6 +136,7 @@ where /// The maximum number of times the solver will process the solution #[inline] + #[must_use] pub fn set_quality_comparator(mut self, quality_comparator: QC) -> Self { self.quality_comparator_opt = Some(quality_comparator); self @@ -147,12 +151,8 @@ where /// * `threshold`: Will stop processing if the solution is not converging for a certain /// number of times #[inline] - pub fn set_stagnation( - mut self, - percentage: Pct, - threshold: usize, - ) -> Result { - let casted_threshold = mop_blocks::Error::cast_rslt(*percentage)?; + pub fn set_stagnation(mut self, percentage: Pct, threshold: usize) -> Result { + let casted_threshold = crate::Error::cast_rslt(*percentage)?; self.stagnation_opt = Some(Stagnation { last_fitness: OR::zero(), lower_bound: OR::one() - casted_threshold, @@ -165,14 +165,14 @@ where } #[inline] - pub async fn solve_problem_with( + pub fn solve_problem_with( mut self, problem: &mut Gp, mut solver: SOLVER, ) -> Result where SOLVER: Solver>, - SOLVER::Error: From, + SOLVER::Error: From, { self.reset_aux_params(); solver.init(problem); @@ -183,12 +183,12 @@ where if let Some(oh) = self.opt_hooks_opt.as_mut() { oh.before_iter(problem); } - solver.before_iter(problem).await?; + solver.before_iter(problem)?; // Ignore if best result couldn't be found let _ = self.manage_best_result(problem); let should_stop_partial = self.iterations_number_has_extrapolated() - || mop_blocks::Error::opt_rslt(self.objs_are_not_converging(problem))? - || mop_blocks::Error::opt_rslt(self.were_all_specified_goals_achieved(problem))?; + || crate::Error::opt_rslt(self.objs_are_not_converging(problem))? + || crate::Error::opt_rslt(self.were_all_specified_goals_achieved(problem))?; #[cfg(feature = "std")] let should_stop = self.time_has_expired() || should_stop_partial; #[cfg(not(feature = "std"))] @@ -199,7 +199,7 @@ where if let Some(oh) = self.opt_hooks_opt.as_mut() { oh.after_iter(problem); } - solver.after_iter(problem).await?; + solver.after_iter(problem)?; } solver.finished(problem); if let Some(oh) = self.opt_hooks_opt.as_mut() { diff --git a/mop-facades/src/opt/opt_hooks.rs b/mop/src/opt/opt_hooks.rs similarity index 100% rename from mop-facades/src/opt/opt_hooks.rs rename to mop/src/opt/opt_hooks.rs diff --git a/mop-facades/src/opt/opt_hooks_fn_builder.rs b/mop/src/opt/opt_hooks_fn_builder.rs similarity index 86% rename from mop-facades/src/opt/opt_hooks_fn_builder.rs rename to mop/src/opt/opt_hooks_fn_builder.rs index cdd3785..86b74fd 100644 --- a/mop-facades/src/opt/opt_hooks_fn_builder.rs +++ b/mop/src/opt/opt_hooks_fn_builder.rs @@ -16,30 +16,34 @@ impl

OptHooksFnBuilder

{ ( self.after_opt_move.unwrap_or_default().0, self.before_opt_move.unwrap_or_default().0, - self.finished.unwrap_or_else(|| || {}), - self.init.unwrap_or_else(|| || {}), + self.finished.unwrap_or(|| {}), + self.init.unwrap_or(|| {}), ) } #[inline] + #[must_use] pub fn after_iter(mut self, after_opt_move: fn(&mut P)) -> Self { self.after_opt_move = Some(FnWrapper(after_opt_move)); self } #[inline] + #[must_use] pub fn before_iter(mut self, before_opt_move: fn(&mut P)) -> Self { self.before_opt_move = Some(FnWrapper(before_opt_move)); self } #[inline] + #[must_use] pub fn finished(mut self, finished: fn()) -> Self { self.finished = Some(finished); self } #[inline] + #[must_use] pub fn init(mut self, init: fn()) -> Self { self.init = Some(init); self @@ -57,11 +61,8 @@ struct FnWrapper

(fn(&mut P)); impl

fmt::Debug for FnWrapper

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[allow( - // Harmless conversion - clippy::as_conversions - )] - fmt::Pointer::fmt(&(self.0 as *const fn(&mut P)), f) + let pointer: *const fn(&mut P) = &self.0; + fmt::Pointer::fmt(&pointer, f) } } diff --git a/mop/src/par_bounds.rs b/mop/src/par_bounds.rs new file mode 100644 index 0000000..f8b7c2e --- /dev/null +++ b/mop/src/par_bounds.rs @@ -0,0 +1,13 @@ +/// Marker that imposes different bounds depending on the selected feature. +#[cfg(not(feature = "rayon"))] +pub trait ParBounds {} + +#[cfg(not(feature = "rayon"))] +impl ParBounds for T where T: ?Sized {} + +/// Marker that imposes different bounds depending on the selected feature. +#[cfg(feature = "rayon")] +pub trait ParBounds: Send + Sync {} + +#[cfg(feature = "rayon")] +impl ParBounds for T where T: Send + Sync + ?Sized {} diff --git a/mop-blocks/src/pct.rs b/mop/src/pct.rs similarity index 87% rename from mop-blocks/src/pct.rs rename to mop/src/pct.rs index 17a8c45..32e98db 100644 --- a/mop-blocks/src/pct.rs +++ b/mop/src/pct.rs @@ -15,7 +15,7 @@ impl Pct { /// # Example /// /// ```rust - /// use mop_blocks::Pct; + /// use mop::Pct; /// assert_eq!(*Pct::from_percent(40), 40); /// ``` #[inline] @@ -24,7 +24,7 @@ impl Pct { } /// Is In Random Probability? - #[cfg(feature = "with-rand")] + #[cfg(feature = "rand")] #[inline] pub fn is_in_rnd_pbty(self, rng: &mut R) -> bool where @@ -35,12 +35,12 @@ impl Pct { } #[inline] - pub fn saturating_mul(self, rhs: T) -> T + pub fn saturating_mul(self, rhs: &T) -> T where T: Div + From + SaturatingMul, { let t: T = self.0.into(); - t.saturating_mul(&rhs).div(100.into()) + t.saturating_mul(rhs).div(100.into()) } } diff --git a/mop-blocks/src/quality_comparator.rs b/mop/src/quality_comparator.rs similarity index 100% rename from mop-blocks/src/quality_comparator.rs rename to mop/src/quality_comparator.rs diff --git a/mop-blocks/src/quality_comparator/nsga2.rs b/mop/src/quality_comparator/nsga2.rs similarity index 78% rename from mop-blocks/src/quality_comparator/nsga2.rs rename to mop/src/quality_comparator/nsga2.rs index 90ef548..6d06b66 100644 --- a/mop-blocks/src/quality_comparator/nsga2.rs +++ b/mop/src/quality_comparator/nsga2.rs @@ -44,8 +44,8 @@ where { #[inline] fn is_better(&self, objs: &[O], a: &MphOrRef<'_, OR, S>, b: &MphOrRef<'_, OR, S>) -> bool { - Self::do_is_best(a, b, |a, b| { - verify_pareto_dominance(objs, a.obj_rslts(), b.obj_rslts()) == Ordering::Greater + Self::do_is_best(a, b, |first, second| { + verify_pareto_dominance(objs, first.obj_rslts(), second.obj_rslts()) == Ordering::Greater }) } } @@ -63,8 +63,8 @@ mod tests { let (defs, a) = problem.parts_mut(); let _ = a .constructor() - .or_hcos_iter([0, 0].iter().cloned(), [0.0, 0.0].iter().cloned(), [10.0, 20.0]) - .or_hcos_iter([0, 1].iter().cloned(), [0.0, 0.0].iter().cloned(), [10.0, 20.0]); + .or_hcos_iter([0, 0].into_iter(), [0.0, 0.0].into_iter(), [10.0, 20.0]) + .or_hcos_iter([0, 1].into_iter(), [0.0, 0.0].into_iter(), [10.0, 20.0]); assert_eq!(Nsga2.is_better(defs.objs(), &a.get(0).unwrap(), &a.get(1).unwrap()), true); } @@ -74,8 +74,8 @@ mod tests { let (defs, a) = problem.parts_mut(); let _ = a .constructor() - .or_hcos_iter([1, 1].iter().cloned(), [0.0, 0.0].iter().cloned(), [10.0, 20.0]) - .or_hcos_iter([2, 2].iter().cloned(), [0.0, 0.0].iter().cloned(), [10.0, 20.0]); + .or_hcos_iter([1, 1].into_iter(), [0.0, 0.0].into_iter(), [10.0, 20.0]) + .or_hcos_iter([2, 2].into_iter(), [0.0, 0.0].into_iter(), [10.0, 20.0]); assert_eq!(Nsga2.is_better(defs.objs(), &a.get(0).unwrap(), &a.get(1).unwrap()), true); } @@ -85,8 +85,8 @@ mod tests { let (defs, a) = problem.parts_mut(); let _ = a .constructor() - .or_hcos_iter([0, 0].iter().cloned(), [0.0, 0.0].iter().cloned(), [10.0, 20.0]) - .or_hcos_iter([0, 0].iter().cloned(), [0.0, 2.0].iter().cloned(), [10.0, 20.0]); + .or_hcos_iter([0, 0].into_iter(), [0.0, 0.0].into_iter(), [10.0, 20.0]) + .or_hcos_iter([0, 0].into_iter(), [0.0, 2.0].into_iter(), [10.0, 20.0]); assert_eq!(Nsga2.is_better(defs.objs(), &a.get(0).unwrap(), &a.get(1).unwrap()), true); } } diff --git a/mop-blocks/src/quality_comparator/objs_avg.rs b/mop/src/quality_comparator/objs_avg.rs similarity index 87% rename from mop-blocks/src/quality_comparator/objs_avg.rs rename to mop/src/quality_comparator/objs_avg.rs index 585ad77..f06b02b 100644 --- a/mop-blocks/src/quality_comparator/objs_avg.rs +++ b/mop/src/quality_comparator/objs_avg.rs @@ -35,8 +35,8 @@ mod tests { fn objs_avg() { let mut problem = dummy_mp(); let (defs, a) = problem.parts_mut(); - let _ = a.constructor().or_os_iter([0.0, 2.0].iter().cloned(), [10.0, 20.0]); - let _ = a.constructor().or_os_iter([2.0, 2.0].iter().cloned(), [10.0, 20.0]); + let _ = a.constructor().or_os_iter([0.0, 2.0].into_iter(), [10.0, 20.0]); + let _ = a.constructor().or_os_iter([2.0, 2.0].into_iter(), [10.0, 20.0]); assert_eq!(ObjsAvg.is_better(defs.objs(), &a.get(0).unwrap(), &a.get(1).unwrap()), true); } } diff --git a/mop-blocks/src/solution.rs b/mop/src/solution.rs similarity index 91% rename from mop-blocks/src/solution.rs rename to mop/src/solution.rs index 30467d3..9f9745f 100644 --- a/mop-blocks/src/solution.rs +++ b/mop/src/solution.rs @@ -68,10 +68,10 @@ impl Solution for arrayvec::ArrayVec { } } -#[cfg(feature = "with-ndsparse")] -impl Solution for ndsparse::csl::Csl +#[cfg(feature = "ndstruct")] +impl Solution for ndstruct::csl::Csl where - DS: AsMut<[DATA]> + AsRef<[DATA]> + cl_traits::Storage, + DS: AsMut<[DATA]> + AsRef<[DATA]> + cl_aux::SingleTypeStorage, IS: AsRef<[usize]>, OS: AsRef<[usize]>, { diff --git a/mop/src/solver.rs b/mop/src/solver.rs new file mode 100644 index 0000000..22e5af6 --- /dev/null +++ b/mop/src/solver.rs @@ -0,0 +1,19 @@ +/// Solver +pub trait Solver

{ + /// Error + type Error; + + /// Do solving work after stoping criteria verification. + fn after_iter(&mut self, p: &mut P) -> Result<(), Self::Error>; + + /// Do solving work before stoping criteria verification. + fn before_iter(&mut self, p: &mut P) -> Result<(), Self::Error>; + + /// Verifies or modifies `P` when solving was completed + #[inline] + fn finished(&mut self, _: &mut P) {} + + /// Verifies or modifies `P` when solving is starting + #[inline] + fn init(&mut self, _: &mut P) {} +} diff --git a/mop-solvers/src/lib.rs b/mop/src/solvers.rs old mode 100755 new mode 100644 similarity index 64% rename from mop-solvers/src/lib.rs rename to mop/src/solvers.rs index 4f3155e..65d833e --- a/mop-solvers/src/lib.rs +++ b/mop/src/solvers.rs @@ -1,4 +1,2 @@ -extern crate alloc; - pub mod genetic_algorithm; mod utils; diff --git a/mop/src/solvers/genetic_algorithm.rs b/mop/src/solvers/genetic_algorithm.rs new file mode 100755 index 0000000..0daf87f --- /dev/null +++ b/mop/src/solvers/genetic_algorithm.rs @@ -0,0 +1,8 @@ +mod genetic_algorithm_params; +mod genetic_algorithm_params_builder; +pub mod operators; +mod spea2; + +pub use genetic_algorithm_params::GeneticAlgorithmParams; +pub use genetic_algorithm_params_builder::GeneticAlgorithmParamsBuilder; +pub use spea2::*; diff --git a/mop-solvers/src/genetic_algorithm/genetic_algorithm_params.rs b/mop/src/solvers/genetic_algorithm/genetic_algorithm_params.rs similarity index 100% rename from mop-solvers/src/genetic_algorithm/genetic_algorithm_params.rs rename to mop/src/solvers/genetic_algorithm/genetic_algorithm_params.rs diff --git a/mop-solvers/src/genetic_algorithm/genetic_algorithm_params_builder.rs b/mop/src/solvers/genetic_algorithm/genetic_algorithm_params_builder.rs similarity index 76% rename from mop-solvers/src/genetic_algorithm/genetic_algorithm_params_builder.rs rename to mop/src/solvers/genetic_algorithm/genetic_algorithm_params_builder.rs index b6b2d28..4d20c69 100755 --- a/mop-solvers/src/genetic_algorithm/genetic_algorithm_params_builder.rs +++ b/mop/src/solvers/genetic_algorithm/genetic_algorithm_params_builder.rs @@ -1,4 +1,4 @@ -use crate::genetic_algorithm::GeneticAlgorithmParams; +use crate::solvers::genetic_algorithm::GeneticAlgorithmParams; #[derive(Debug)] pub struct GeneticAlgorithmParamsBuilder { @@ -9,11 +9,11 @@ pub struct GeneticAlgorithmParamsBuilder { impl GeneticAlgorithmParamsBuilder { #[inline] - pub fn build(self) -> Result, mop_blocks::Error> { + pub fn build(self) -> Result, crate::Error> { Ok(GeneticAlgorithmParams { - crossover: mop_blocks::Error::opt_rslt(self.crossover)?, - mating_selection: mop_blocks::Error::opt_rslt(self.mating_selection)?, - mutation: mop_blocks::Error::opt_rslt(self.mutation)?, + crossover: crate::Error::opt_rslt(self.crossover)?, + mating_selection: crate::Error::opt_rslt(self.mating_selection)?, + mutation: crate::Error::opt_rslt(self.mutation)?, }) } diff --git a/mop-solvers/src/genetic_algorithm/operators.rs b/mop/src/solvers/genetic_algorithm/operators.rs similarity index 100% rename from mop-solvers/src/genetic_algorithm/operators.rs rename to mop/src/solvers/genetic_algorithm/operators.rs diff --git a/mop-solvers/src/genetic_algorithm/operators/crossover.rs b/mop/src/solvers/genetic_algorithm/operators/crossover.rs similarity index 100% rename from mop-solvers/src/genetic_algorithm/operators/crossover.rs rename to mop/src/solvers/genetic_algorithm/operators/crossover.rs diff --git a/mop-solvers/src/genetic_algorithm/operators/crossover/multi_point.rs b/mop/src/solvers/genetic_algorithm/operators/crossover/multi_point.rs similarity index 67% rename from mop-solvers/src/genetic_algorithm/operators/crossover/multi_point.rs rename to mop/src/solvers/genetic_algorithm/operators/crossover/multi_point.rs index 964c46f..62c2167 100755 --- a/mop-solvers/src/genetic_algorithm/operators/crossover/multi_point.rs +++ b/mop/src/solvers/genetic_algorithm/operators/crossover/multi_point.rs @@ -1,7 +1,10 @@ -use crate::{genetic_algorithm::operators::crossover::Crossover, utils::two_asc_rnd_num}; -use cl_traits::{Clear, Push, Storage, Truncate}; +use crate::{ + gp::MpOrs, + solvers::{genetic_algorithm::operators::crossover::Crossover, utils::two_asc_rnd_num}, + Pct, Solution, +}; +use cl_aux::{Clear, Push, SingleTypeStorage, Truncate}; use core::ops::Div; -use mop_blocks::{gp::MpOrs, Pct, Solution}; use rand::rngs::OsRng; #[derive(Clone, Debug)] @@ -34,13 +37,21 @@ impl MultiPoint { impl Crossover> for MultiPoint where OR: Copy, - ORS: - AsRef<[OR]> + AsMut<[OR]> + Clear + Extend + Storage + Truncate, + ORS: AsRef<[OR]> + + AsMut<[OR]> + + Clear + + Extend + + SingleTypeStorage + + Truncate, S: Clone + Solution, - SS: - AsRef<[S]> + AsMut<[S]> + Clear + Push + Storage + Truncate, + SS: AsRef<[S]> + + AsMut<[S]> + + Clear + + Push + + SingleTypeStorage + + Truncate, { - type Error = mop_blocks::Error; + type Error = crate::Error; #[inline] fn crossover( @@ -53,14 +64,14 @@ where let mut rng = OsRng; while destination.rslts_num() < filling_num { let [a, b] = two_asc_rnd_num(&mut rng, 0..source.rslts_num()); - let first = mop_blocks::Error::opt_rslt(source.get(a))?; - let second = mop_blocks::Error::opt_rslt(source.get(b))?; - let _ = destination.constructor().or_ref(first); - let _ = destination.constructor().or_ref(second); + let first = crate::Error::opt_rslt(source.get(a))?; + let second = crate::Error::opt_rslt(source.get(b))?; + let _ = destination.constructor().or_ref(&first); + let _ = destination.constructor().or_ref(&second); if self.probability.is_in_rnd_pbty(&mut rng) { let a = destination.rslts_num() - 2; let b = destination.rslts_num() - 1; - let [mut first, mut second] = mop_blocks::Error::opt_rslt(destination.get_two_mut(a, b))?; + let [mut first, mut second] = crate::Error::opt_rslt(destination.get_two_mut(a, b))?; self.swap_data_of_indvs(*first.solution_mut(), *second.solution_mut()); } } @@ -71,8 +82,12 @@ where #[cfg(test)] mod tests { - use crate::genetic_algorithm::operators::crossover::{Crossover, MultiPoint}; - use mop_blocks::{gp::MpOrRef, utils::dummy_mp, Pct}; + use crate::{ + gp::MpOrRef, + solvers::genetic_algorithm::operators::crossover::{Crossover, MultiPoint}, + utils::dummy_mp, + Pct, + }; #[test] fn multi_point() { diff --git a/mop-solvers/src/genetic_algorithm/operators/mating_selection.rs b/mop/src/solvers/genetic_algorithm/operators/mating_selection.rs similarity index 100% rename from mop-solvers/src/genetic_algorithm/operators/mating_selection.rs rename to mop/src/solvers/genetic_algorithm/operators/mating_selection.rs diff --git a/mop-solvers/src/genetic_algorithm/operators/mating_selection/tournament.rs b/mop/src/solvers/genetic_algorithm/operators/mating_selection/tournament.rs similarity index 68% rename from mop-solvers/src/genetic_algorithm/operators/mating_selection/tournament.rs rename to mop/src/solvers/genetic_algorithm/operators/mating_selection/tournament.rs index c2c234b..5d072ac 100644 --- a/mop-solvers/src/genetic_algorithm/operators/mating_selection/tournament.rs +++ b/mop/src/solvers/genetic_algorithm/operators/mating_selection/tournament.rs @@ -1,9 +1,9 @@ -use crate::genetic_algorithm::operators::mating_selection::MatingSelection; -use cl_traits::{Clear, Push, Storage, Truncate}; -use mop_blocks::{ +use crate::{ gp::{MpOrRef, MpOrs}, quality_comparator::QualityComparator, + solvers::genetic_algorithm::operators::mating_selection::MatingSelection, }; +use cl_aux::{Clear, Push, SingleTypeStorage, Truncate}; use rand::{rngs::OsRng, Rng}; #[derive(Clone, Debug, Default)] @@ -22,12 +22,20 @@ impl Tournament { impl MatingSelection<[O], MpOrs> for Tournament where OR: Copy, - ORS: AsRef<[OR]> + Clear + Extend + Storage + Truncate, + ORS: AsRef<[OR]> + + Clear + + Extend + + SingleTypeStorage + + Truncate, QC: for<'a> QualityComparator<[O], MpOrRef<'a, OR, S>>, S: Clone, - SS: AsRef<[S]> + Clear + Push + Storage + Truncate, + SS: AsRef<[S]> + + Clear + + Push + + SingleTypeStorage + + Truncate, { - type Error = mop_blocks::Error; + type Error = crate::Error; #[inline] fn mating_selection( @@ -41,15 +49,15 @@ where let mut rng = OsRng; while destination.rslts_num() < filling_num { let winner_opt = source.get(rng.gen_range(0..source.rslts_num())); - let mut winner = mop_blocks::Error::opt_rslt(winner_opt)?; + let mut winner = crate::Error::opt_rslt(winner_opt)?; for _ in 0..self.n { let current_opt = source.get(rng.gen_range(0..source.rslts_num())); - let current = mop_blocks::Error::opt_rslt(current_opt)?; + let current = crate::Error::opt_rslt(current_opt)?; if self.quality_comparator.is_better(objs, ¤t, &winner) { winner = current; } } - let _ = destination.constructor().or_ref(winner); + let _ = destination.constructor().or_ref(&winner); } Ok(()) } @@ -57,8 +65,11 @@ where #[cfg(test)] mod tests { - use crate::genetic_algorithm::operators::mating_selection::{MatingSelection, Tournament}; - use mop_blocks::{quality_comparator::ObjsAvg, utils::dummy_mp}; + use crate::{ + quality_comparator::ObjsAvg, + solvers::genetic_algorithm::operators::mating_selection::{MatingSelection, Tournament}, + utils::dummy_mp, + }; #[test] fn tournament() { diff --git a/mop-solvers/src/genetic_algorithm/operators/mutation.rs b/mop/src/solvers/genetic_algorithm/operators/mutation.rs similarity index 80% rename from mop-solvers/src/genetic_algorithm/operators/mutation.rs rename to mop/src/solvers/genetic_algorithm/operators/mutation.rs index cdfc7bb..e2798ef 100755 --- a/mop-solvers/src/genetic_algorithm/operators/mutation.rs +++ b/mop/src/solvers/genetic_algorithm/operators/mutation.rs @@ -1,7 +1,8 @@ mod random_domain_assignments; mod swap; -pub use {random_domain_assignments::RandomDomainAssignments, swap::Swap}; +pub use random_domain_assignments::RandomDomainAssignments; +pub use swap::Swap; pub trait Mutation { type Error; diff --git a/mop-solvers/src/genetic_algorithm/operators/mutation/random_domain_assignments.rs b/mop/src/solvers/genetic_algorithm/operators/mutation/random_domain_assignments.rs similarity index 78% rename from mop-solvers/src/genetic_algorithm/operators/mutation/random_domain_assignments.rs rename to mop/src/solvers/genetic_algorithm/operators/mutation/random_domain_assignments.rs index b2c9d74..4b679cc 100644 --- a/mop-solvers/src/genetic_algorithm/operators/mutation/random_domain_assignments.rs +++ b/mop/src/solvers/genetic_algorithm/operators/mutation/random_domain_assignments.rs @@ -1,6 +1,7 @@ -use crate::genetic_algorithm::operators::mutation::Mutation; -use cl_traits::Storage; -use mop_blocks::{gp::MpOrs, Domain, Pct, Solution}; +use crate::{ + gp::MpOrs, solvers::genetic_algorithm::operators::mutation::Mutation, Domain, Pct, Solution, +}; +use cl_aux::SingleTypeStorage; use rand::{rngs::OsRng, Rng}; #[derive(Clone, Debug)] @@ -20,8 +21,8 @@ where D: Domain, S: Solution, - ORS: AsMut<[OR]> + Storage, - SS: AsMut<[S]> + Storage, + ORS: AsMut<[OR]> + SingleTypeStorage, + SS: AsMut<[S]> + SingleTypeStorage, { type Error = core::convert::Infallible; @@ -42,8 +43,11 @@ where #[cfg(test)] mod tests { - use crate::genetic_algorithm::operators::mutation::{Mutation, RandomDomainAssignments}; - use mop_blocks::{utils::dummy_mp, Pct}; + use crate::{ + solvers::genetic_algorithm::operators::mutation::{Mutation, RandomDomainAssignments}, + utils::dummy_mp, + Pct, + }; #[test] fn random_domain_assignment() { diff --git a/mop-solvers/src/genetic_algorithm/operators/mutation/swap.rs b/mop/src/solvers/genetic_algorithm/operators/mutation/swap.rs similarity index 77% rename from mop-solvers/src/genetic_algorithm/operators/mutation/swap.rs rename to mop/src/solvers/genetic_algorithm/operators/mutation/swap.rs index 02f0eff..d4b7929 100755 --- a/mop-solvers/src/genetic_algorithm/operators/mutation/swap.rs +++ b/mop/src/solvers/genetic_algorithm/operators/mutation/swap.rs @@ -1,6 +1,9 @@ -use crate::{genetic_algorithm::operators::mutation::Mutation, utils::two_dist_rnd_num}; -use cl_traits::Storage; -use mop_blocks::{gp::MpOrs, Pct, Solution}; +use crate::{ + gp::MpOrs, + solvers::{genetic_algorithm::operators::mutation::Mutation, utils::two_dist_rnd_num}, + Pct, Solution, +}; +use cl_aux::SingleTypeStorage; use rand::rngs::OsRng; #[derive(Clone, Debug)] @@ -18,8 +21,8 @@ impl Swap { impl Mutation> for Swap where - ORS: AsMut<[OR]> + Storage, - SS: AsMut<[S]> + Storage, + ORS: AsMut<[OR]> + SingleTypeStorage, + SS: AsMut<[S]> + SingleTypeStorage, S: Solution, { type Error = core::convert::Infallible; @@ -42,8 +45,11 @@ where #[cfg(test)] mod tests { - use crate::genetic_algorithm::operators::mutation::{Mutation, Swap}; - use mop_blocks::{utils::dummy_mp, Pct}; + use crate::{ + solvers::genetic_algorithm::operators::mutation::{Mutation, Swap}, + utils::dummy_mp, + Pct, + }; #[test] fn swap() { diff --git a/mop-solvers/src/genetic_algorithm/spea2.rs b/mop/src/solvers/genetic_algorithm/spea2.rs similarity index 78% rename from mop-solvers/src/genetic_algorithm/spea2.rs rename to mop/src/solvers/genetic_algorithm/spea2.rs index 57ec31c..fc563f5 100755 --- a/mop-solvers/src/genetic_algorithm/spea2.rs +++ b/mop/src/solvers/genetic_algorithm/spea2.rs @@ -1,19 +1,23 @@ //! Zitzler and Thiele; SPEA2: Improving the Strength Pareto Evolutionary Algorithm -use cl_traits::{Clear, Push, Storage, WithCapacity}; - mod arch_union_popul; mod environment_selection_truncation_result; use crate::{ - genetic_algorithm::{ - operators::{crossover::Crossover, mating_selection::MatingSelection, mutation::Mutation}, - GeneticAlgorithmParams, + gp::{GpOrsEvaluators, Mp, MpOrs}, + solvers::{ + genetic_algorithm::{ + operators::{crossover::Crossover, mating_selection::MatingSelection, mutation::Mutation}, + GeneticAlgorithmParams, + }, + utils::euclidean_distance, }, - utils::euclidean_distance, + utils::verify_pareto_dominance, + Obj, ParBounds, Pct, Solution, Solver, }; -use alloc::{boxed::Box, vec::Vec}; +use alloc::vec::Vec; use arch_union_popul::{ArchUnionPopul, Properties}; +use cl_aux::{Clear, Push, SingleTypeStorage, WithCapacity}; use core::{ cmp::Ordering, fmt::Debug, @@ -22,12 +26,6 @@ use core::{ ops::{AddAssign, Div, Mul, Sub}, }; use environment_selection_truncation_result::EnvironmentSelectionTruncationResult; -use mop_blocks::{ - gp::{GpOrsEvaluators, Mp, MpOrs}, - utils::verify_pareto_dominance, - Obj, Pct, Solution, -}; -use mop_common::{Solver, SolverFuture, TraitCfg}; use num_traits::{NumCast, One, Pow, Zero}; use rand::distributions::uniform::SampleUniform; @@ -68,14 +66,15 @@ where + Pow + Sub + Zero, - ORS: AsRef<[OR]> + Clear + Extend + Storage + WithCapacity, - OS: AsRef<[O]> + Storage, + ORS: + AsRef<[OR]> + Clear + Extend + SingleTypeStorage + WithCapacity, + OS: AsRef<[O]> + SingleTypeStorage, S: Clone + Solution, SS: AsRef<[S]> + Clear + Extend - + Push - + Storage + + Push + + SingleTypeStorage + WithCapacity, { #[inline] @@ -84,9 +83,9 @@ where gap: GeneticAlgorithmParams, problem: &Mp, population_size: usize, - ) -> Result { + ) -> Result { let defs = problem.defs(); - let archive_size = archive_size_pct.saturating_mul(population_size); + let archive_size = archive_size_pct.saturating_mul(&population_size); let arch_u_popul_len = archive_size.saturating_add(population_size); Ok(Spea2 { arch_rslts: MpOrs::with_capacity(defs, archive_size), @@ -103,7 +102,7 @@ where k: num_integer::sqrt(arch_u_popul_len), mating_pool: MpOrs::with_capacity(defs, population_size), population_size, - two: mop_blocks::Error::cast_rslt(2)?, + two: crate::Error::cast_rslt(2)?, }) } @@ -111,7 +110,7 @@ where self.arch_rslts.clear(); let (aup, ar) = (&self.arch_u_popul, &mut self.arch_rslts); for (r, _) in aup.rslts.iter().zip(&aup.props).filter(|&(_, prop)| prop.fitness < OR::one()) { - let _ = ar.constructor().or_ref(r); + let _ = ar.constructor().or_ref(&r); } } @@ -129,7 +128,7 @@ where .take(self.archive_size - ar.rslts_num()) { let r = aup.rslts.get(prop.result_idx)?; - let _ = ar.constructor().or_ref(r); + let _ = ar.constructor().or_ref(&r); } } } @@ -157,7 +156,7 @@ where self.intermediary_arch_rslts.clear(); for archive_idx in self.estr.iter().map(|estr| estr.archive_idx) { let r = ar.get(archive_idx)?; - let _ = self.intermediary_arch_rslts.constructor().or_ref(r); + let _ = self.intermediary_arch_rslts.constructor().or_ref(&r); } swap(&mut self.intermediary_arch_rslts, ar); Some(()) @@ -165,8 +164,8 @@ where fn fill_arch_u_popul(&mut self, p: &Mp) { self.arch_u_popul.rslts.clear(); - let _ = self.arch_u_popul.rslts.constructor().ors_ref(self.arch_rslts.as_ref()); - let _ = self.arch_u_popul.rslts.constructor().ors_ref(p.rslts().as_ref()); + let _ = self.arch_u_popul.rslts.constructor().ors_ref(&self.arch_rslts.as_ref()); + let _ = self.arch_u_popul.rslts.constructor().ors_ref(&p.rslts().as_ref()); self.arch_u_popul.props.clear(); self.arch_u_popul.props.extend( (0..self.arch_u_popul.rslts.rslts_num()).map(|idx| Properties { @@ -239,11 +238,11 @@ where impl Solver> for Spea2 where - D: TraitCfg, - CO: Crossover> + TraitCfg, - M: Mutation> + TraitCfg, - MS: MatingSelection<[O], MpOrs> + TraitCfg, - O: Obj + TraitCfg, + D: ParBounds, + CO: Crossover> + ParBounds, + M: Mutation> + ParBounds, + MS: MatingSelection<[O], MpOrs> + ParBounds, + O: Obj + ParBounds, OR: AddAssign + Copy + Debug @@ -251,69 +250,65 @@ where + Mul + NumCast + One + + ParBounds + PartialOrd + Pow + SampleUniform + Sub - + TraitCfg + Zero, ORS: AsMut<[OR]> + AsRef<[OR]> + Clear + Extend - + Storage - + TraitCfg + + ParBounds + + SingleTypeStorage + WithCapacity, - OS: AsRef<[O]> + Storage + TraitCfg, - S: Clone + Solution + TraitCfg, + OS: AsRef<[O]> + SingleTypeStorage + ParBounds, + S: Clone + Solution + ParBounds, SS: AsMut<[S]> + AsRef<[S]> + Clear + Extend - + Push - + Storage - + TraitCfg + + ParBounds + + Push + + SingleTypeStorage + WithCapacity, - mop_blocks::Error: From + From + From, + crate::Error: From + From + From, { - type Error = mop_blocks::Error; + type Error = crate::Error; #[inline] - fn after_iter<'a>(&'a mut self, p: &'a mut Mp) -> SolverFuture<'a, Self::Error> { - Box::pin(async move { - let filling_num = self.population_size; - self.gap.mating_selection.mating_selection( - p.defs().objs(), - &mut self.arch_rslts, - &mut self.mating_pool, - filling_num, - )?; - self.gap.crossover.crossover(&mut self.mating_pool, p.rslts_mut(), filling_num)?; - - let (defs, rslts) = p.parts_mut(); - self.gap.mutation.mutation(defs.domain(), rslts)?; - - Ok(()) - }) + fn after_iter<'a>(&'a mut self, p: &'a mut Mp) -> Result<(), Self::Error> { + let filling_num = self.population_size; + self.gap.mating_selection.mating_selection( + p.defs().objs(), + &mut self.arch_rslts, + &mut self.mating_pool, + filling_num, + )?; + self.gap.crossover.crossover(&mut self.mating_pool, p.rslts_mut(), filling_num)?; + + let (defs, rslts) = p.parts_mut(); + self.gap.mutation.mutation(defs.domain(), rslts)?; + + Ok(()) } #[inline] - fn before_iter<'a>(&'a mut self, p: &'a mut Mp) -> SolverFuture<'a, Self::Error> { - Box::pin(async move { - let (defs, rslts) = p.parts_mut(); - let ar = &mut self.arch_rslts; - GpOrsEvaluators::eval_objs(defs, ar).await; - GpOrsEvaluators::eval_objs(defs, rslts).await; - - self.fill_arch_u_popul(p); - self.set_strength(p); - self.set_raw_fitness(p); - mop_blocks::Error::opt_rslt(self.set_density())?; - - self.copy_less_than_one_to_archive(); - mop_blocks::Error::opt_rslt(self.manage_environment_selection_diff())?; - Ok(()) - }) + fn before_iter<'a>(&'a mut self, p: &'a mut Mp) -> Result<(), Self::Error> { + let (defs, rslts) = p.parts_mut(); + let ar = &mut self.arch_rslts; + GpOrsEvaluators::eval_objs(defs, ar); + GpOrsEvaluators::eval_objs(defs, rslts); + + self.fill_arch_u_popul(p); + self.set_strength(p); + self.set_raw_fitness(p); + crate::Error::opt_rslt(self.set_density())?; + + self.copy_less_than_one_to_archive(); + crate::Error::opt_rslt(self.manage_environment_selection_diff())?; + Ok(()) } } @@ -330,13 +325,17 @@ where #[cfg(test)] mod tests { - use crate::genetic_algorithm::{ - operators::{ - crossover::MultiPoint, mating_selection::Tournament, mutation::RandomDomainAssignments, + use crate::{ + quality_comparator::ObjsAvg, + solvers::genetic_algorithm::{ + operators::{ + crossover::MultiPoint, mating_selection::Tournament, mutation::RandomDomainAssignments, + }, + GeneticAlgorithmParamsBuilder, Spea2, }, - GeneticAlgorithmParamsBuilder, Spea2, + utils::dummy_mp_with_solutions, + Pct, }; - use mop_blocks::{quality_comparator::ObjsAvg, utils::dummy_mp_with_solutions, Pct}; #[test] fn spea2() { diff --git a/mop-solvers/src/genetic_algorithm/spea2/arch_union_popul.rs b/mop/src/solvers/genetic_algorithm/spea2/arch_union_popul.rs similarity index 92% rename from mop-solvers/src/genetic_algorithm/spea2/arch_union_popul.rs rename to mop/src/solvers/genetic_algorithm/spea2/arch_union_popul.rs index 788eade..4b77301 100644 --- a/mop-solvers/src/genetic_algorithm/spea2/arch_union_popul.rs +++ b/mop/src/solvers/genetic_algorithm/spea2/arch_union_popul.rs @@ -1,5 +1,5 @@ +use crate::gp::MpOrs; use alloc::vec::Vec; -use mop_blocks::gp::MpOrs; #[derive(Clone, Debug)] pub(crate) struct ArchUnionPopul { diff --git a/mop-solvers/src/genetic_algorithm/spea2/environment_selection_truncation_result.rs b/mop/src/solvers/genetic_algorithm/spea2/environment_selection_truncation_result.rs similarity index 100% rename from mop-solvers/src/genetic_algorithm/spea2/environment_selection_truncation_result.rs rename to mop/src/solvers/genetic_algorithm/spea2/environment_selection_truncation_result.rs diff --git a/mop-solvers/src/utils.rs b/mop/src/solvers/utils.rs similarity index 100% rename from mop-solvers/src/utils.rs rename to mop/src/solvers/utils.rs diff --git a/mop-blocks/src/utils.rs b/mop/src/utils.rs similarity index 73% rename from mop-blocks/src/utils.rs rename to mop/src/utils.rs index 09f7723..9ebff30 100644 --- a/mop-blocks/src/utils.rs +++ b/mop/src/utils.rs @@ -52,10 +52,10 @@ pub fn dummy_mp() -> DummyMpTy { MpVec::with_capacity( MpDefinitions { domain: [0.0..=0.0, 0.0..=0.0], - hard_cstrs: Default::default(), - name: Default::default(), + hard_cstrs: <_>::default(), + name: <_>::default(), objs: alloc::vec![(ObjDirection::Min, obj), (ObjDirection::Min, obj),], - soft_cstrs: Default::default(), + soft_cstrs: <_>::default(), }, 4, ) @@ -67,10 +67,10 @@ pub fn dummy_mp_with_solutions() -> DummyMpTy { let _ = problem .rslts_mut() .constructor() - .or_os_iter([4.0, 8.0].iter().cloned(), [2.0, 2.0]) - .or_os_iter([8.0, 8.0].iter().cloned(), [3.0, 3.0]) - .or_os_iter([8.0, 12.0].iter().cloned(), [4.0, 4.0]) - .or_os_iter([12.0, 12.0].iter().cloned(), [5.0, 5.0]); + .or_os_iter([4.0, 8.0].into_iter(), [2.0, 2.0]) + .or_os_iter([8.0, 8.0].into_iter(), [3.0, 3.0]) + .or_os_iter([8.0, 12.0].into_iter(), [4.0, 4.0]) + .or_os_iter([12.0, 12.0].into_iter(), [5.0, 5.0]); problem } @@ -80,9 +80,9 @@ pub fn dummy_mph() -> DummyMphTy { MphDefinitions { domain: [0.0..=0.0, 0.0..=0.0], hard_cstrs: alloc::vec![hc, hc], - name: Default::default(), + name: <_>::default(), objs: alloc::vec![(ObjDirection::Min, obj), (ObjDirection::Min, obj)], - soft_cstrs: Default::default(), + soft_cstrs: <_>::default(), }, 4, ) @@ -94,10 +94,10 @@ pub fn dummy_mph_with_solutions() -> DummyMphTy { let _ = problem .rslts_mut() .constructor() - .or_hcos_iter([1, 2].iter().cloned(), [4.0, 8.0].iter().cloned(), [2.0, 2.0]) - .or_hcos_iter([1, 2].iter().cloned(), [8.0, 8.0].iter().cloned(), [3.0, 3.0]) - .or_hcos_iter([1, 2].iter().cloned(), [8.0, 12.0].iter().cloned(), [4.0, 4.0]) - .or_hcos_iter([1, 2].iter().cloned(), [12.0, 12.0].iter().cloned(), [5.0, 5.0]); + .or_hcos_iter([1, 2].into_iter(), [4.0, 8.0].into_iter(), [2.0, 2.0]) + .or_hcos_iter([1, 2].into_iter(), [8.0, 8.0].into_iter(), [3.0, 3.0]) + .or_hcos_iter([1, 2].into_iter(), [8.0, 12.0].into_iter(), [4.0, 4.0]) + .or_hcos_iter([1, 2].into_iter(), [12.0, 12.0].into_iter(), [5.0, 5.0]); problem } diff --git a/mop-bindings/src/wasm_bindgen.rs b/mop/src/wasm_bindgen.rs similarity index 86% rename from mop-bindings/src/wasm_bindgen.rs rename to mop/src/wasm_bindgen.rs index 2ad5378..c15f8f9 100644 --- a/mop-bindings/src/wasm_bindgen.rs +++ b/mop/src/wasm_bindgen.rs @@ -1,29 +1,25 @@ -use arrayvec::ArrayVec; -use core::ops::RangeInclusive; -use mop::{ - blocks::{ - self, - gp::{ - mp_defs_from_gp_defs, GpOperations, MpVec, MphDefinitionsBuilderVec, MphDefinitionsVec, - MphMpMph, MphOrVec, MphOrsVec, MphVec, NoCstr, NoCstrRslts, - }, - objs::MinCstrsRslts, - quality_comparator::ObjsAvg, - Cstr, +use crate::{ + gp::{ + mp_defs_from_gp_defs, GpOperations, MpVec, MphDefinitionsBuilderVec, MphDefinitionsVec, + MphMpMph, MphOrVec, MphOrsVec, MphVec, NoCstr, NoCstrRslts, }, - facades::opt, + objs::MinCstrsRslts, + opt, + quality_comparator::ObjsAvg, solvers::genetic_algorithm::{ operators::{ crossover::MultiPoint, mating_selection::Tournament, mutation::RandomDomainAssignments, }, GeneticAlgorithmParamsBuilder, Spea2, }, + Cstr, Either, }; +use alloc::{format, vec::Vec}; +use arrayvec::ArrayVec; +use core::ops::RangeInclusive; +use js_sys::{Array, Function}; use rand::Rng; -use { - js_sys::{Array, Function}, - wasm_bindgen::prelude::*, -}; +use wasm_bindgen::prelude::*; // HardCstr @@ -78,8 +74,8 @@ impl Obj { } } -impl blocks::Obj for Obj { - fn obj_direction(&self) -> blocks::ObjDirection { +impl crate::Obj for Obj { + fn obj_direction(&self) -> crate::ObjDirection { self.0.to_original() } @@ -113,10 +109,10 @@ pub enum ObjDirection { } impl ObjDirection { - fn to_original(&self) -> blocks::ObjDirection { + fn to_original(&self) -> crate::ObjDirection { match *self { - ObjDirection::Max => blocks::ObjDirection::Max, - ObjDirection::Min => blocks::ObjDirection::Min, + ObjDirection::Max => crate::ObjDirection::Max, + ObjDirection::Min => crate::ObjDirection::Min, } } } @@ -157,24 +153,23 @@ impl OptFacade { Ok(OptFacade(this)) } - pub async fn solve(self, mut orig: OptProblem, rslts_num: usize) -> Result { + pub fn solve(self, mut orig: OptProblem, rslts_num: usize) -> Result { let (mph_defs, mut mph_rslts) = orig.0.parts_mut(); - let mcr = MinCstrsRslts::from_gp_hcs(mph_defs); let mp_defs_ref = js_err({ let mut mdfgd = js_err(mp_defs_from_gp_defs(mph_defs))?; - mdfgd = js_err(mdfgd.push_obj((&mcr).into()))?; + mdfgd = js_err(mdfgd.push_obj(Either::Right(MinCstrsRslts::from_gp_hcs(mph_defs))))?; mdfgd.build() })?; let mut mp_ref = js_err(MpVec::with_random_solutions(mp_defs_ref, 100))?; let spea2 = js_err(Spea2::new( - blocks::Pct::from_percent(50), + crate::Pct::from_percent(50), js_err( GeneticAlgorithmParamsBuilder::default() - .crossover(MultiPoint::new(1, blocks::Pct::from_percent(70))) + .crossover(MultiPoint::new(1, crate::Pct::from_percent(70))) .mating_selection(Tournament::new(2, ObjsAvg)) - .mutation(RandomDomainAssignments::new(1, blocks::Pct::from_percent(30))) + .mutation(RandomDomainAssignments::new(1, crate::Pct::from_percent(30))) .build(), )?, &mp_ref, @@ -188,9 +183,8 @@ impl OptFacade { } else { facade }; - let _ = js_err(facade.solve_problem_with(&mut mp_ref, spea2).await)?; - - let _ = js_err(MphMpMph::transfer(&mph_defs, &mut mph_rslts, &mp_ref).await)?; + let _this = js_err(facade.solve_problem_with(&mut mp_ref, spea2))?; + js_err(MphMpMph::transfer(&mph_defs, &mut mph_rslts, &mp_ref))?; Ok(orig) } @@ -299,12 +293,12 @@ impl OptProblemResult { #[wasm_bindgen] #[derive(Clone, Debug)] -pub struct Pct(blocks::Pct); +pub struct Pct(crate::Pct); #[wasm_bindgen] impl Pct { pub fn from_percent(pct: u16) -> Self { - Pct(blocks::Pct::from_percent(pct)) + Pct(crate::Pct::from_percent(pct)) } } @@ -321,7 +315,7 @@ impl Solution { } } -impl blocks::Solution for Solution { +impl crate::Solution for Solution { const MAX_LEN: usize = 16; fn has_var(&self, idx: usize) -> bool { @@ -375,14 +369,14 @@ impl Domain { } } -impl blocks::Domain for Domain { - type Error = mop::blocks::Error; +impl crate::Domain for Domain { + type Error = crate::Error; fn len(&self) -> usize { self.0.len() } - fn new_random_solution(&self, rng: &mut R) -> Result + fn new_random_solution(&self, rng: &mut R) -> Result where R: Rng, { @@ -407,6 +401,7 @@ where #[cfg(test)] mod tests { use crate::wasm_bindgen::*; + use alloc::vec; use wasm_bindgen_test::*; #[wasm_bindgen_test] @@ -445,9 +440,6 @@ mod tests { let problem = OptProblem::with_capacity(opdb.build().unwrap(), 100); let facade = OptFacade::new(50).set_stagnation(Pct::from_percent(1), 10).unwrap(); - - wasm_bindgen_futures::spawn_local(async { - let _ = facade.solve(problem, 100).await; - }); + let _opt_problem = facade.solve(problem, 100).unwrap(); } } diff --git a/rustfmt.toml b/rustfmt.toml index acf899b..224e3a0 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,7 @@ -edition = "2018" -tab_spaces = 2 -use_field_init_shorthand = true -use_small_heuristics = "Max" \ No newline at end of file +edition="2021" +imports_granularity = "Crate" +newline_style = "Unix" +reorder_imports = true +tab_spaces=2 +use_field_init_shorthand=true +use_small_heuristics="Max" diff --git a/scripts/publish.sh b/scripts/publish.sh deleted file mode 100755 index 583b0df..0000000 --- a/scripts/publish.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -set -eux - -PACKAGES=( - mop-common - mop-blocks - mop-solvers - mop-facades - mop -) - -for package in "${PACKAGES[@]}"; do - pushd "${package}" - /bin/echo -e "\e[0;33m***** Publishing ${package} *****\e[0m\n" - cargo publish - sleep 25 - popd -done \ No newline at end of file diff --git a/scripts/tests.sh b/scripts/tests.sh deleted file mode 100755 index d791754..0000000 --- a/scripts/tests.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -cargo install --git https://github.com/c410-f3r/rust-tools --force - -rt='rust-tools --template you-rust' - -export CARGO_TARGET_DIR="$($rt target-dir)" -export RUST_BACKTRACE=1 -export RUSTFLAGS="$($rt rust-flags '' -Dmissing_docs,-Dunused_crate_dependencies,-Dvariant_size_differences)" - -$rt rustfmt -$rt clippy -Aclippy::float_arithmetic,-Aclippy::indexing_slicing,-Aclippy::integer_arithmetic,-Aclippy::let_underscore_must_use,-Aclippy::panic,-Aclippy::type_complexity,-Aclippy::default_numeric_fallback - -$rt test-generic mop-bindings -$rt test-with-features mop-bindings with-futures -$rt test-with-features mop-bindings with-wasm_bindgen - -$rt test-generic mop-blocks -$rt test-with-features mop-blocks std -$rt test-with-features mop-blocks with-futures -$rt test-with-features mop-blocks with-ndsparse -$rt test-with-features mop-blocks with-rand -$rt test-with-features mop-blocks with-serde - -$rt test-generic mop-common -$rt test-with-features mop-common with-futures - -$rt test-generic mop-facades - -$rt test-generic mop-solvers - -$rt check-with-features mop-problems binh-and-korn -$rt check-with-features mop-problems constr -$rt check-with-features mop-problems cvrp -$rt check-with-features mop-problems rastrigin -$rt check-with-features mop-problems schaffer-function-2 -$rt check-with-features mop-problems test-function-4