{"id":16771090,"url":"https://github.com/c410-f3r/mop","last_synced_at":"2025-08-08T14:24:31.562Z","repository":{"id":57640257,"uuid":"250080955","full_name":"c410-f3r/mop","owner":"c410-f3r","description":"Flexible and modular framework for different NP-Problems with different solvers","archived":false,"fork":false,"pushed_at":"2025-02-20T11:53:29.000Z","size":273,"stargazers_count":22,"open_issues_count":5,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-11T04:54:37.610Z","etag":null,"topics":["ai","framework","heuristics","metaheuristics","np-problem","rust","solver"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/c410-f3r.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-25T20:11:49.000Z","updated_at":"2025-05-13T15:00:54.000Z","dependencies_parsed_at":"2022-09-07T13:22:04.726Z","dependency_job_id":"3af41c0c-58c9-4178-a308-f11e009afe3f","html_url":"https://github.com/c410-f3r/mop","commit_stats":{"total_commits":70,"total_committers":2,"mean_commits":35.0,"dds":"0.37142857142857144","last_synced_commit":"426f034359e4bb818a7b16239817b6f346da166c"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/c410-f3r/mop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c410-f3r%2Fmop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c410-f3r%2Fmop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c410-f3r%2Fmop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c410-f3r%2Fmop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/c410-f3r","download_url":"https://codeload.github.com/c410-f3r/mop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c410-f3r%2Fmop/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263296492,"owners_count":23444495,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","framework","heuristics","metaheuristics","np-problem","rust","solver"],"created_at":"2024-10-13T06:26:45.856Z","updated_at":"2025-07-03T09:07:50.062Z","avatar_url":"https://github.com/c410-f3r.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MOP (Many OPtimizations)\n\n[![CI](https://github.com/c410-f3r/mop/workflows/CI/badge.svg)](https://github.com/c410-f3r/mop/actions?query=workflow%3ACI)\n[![crates.io](https://img.shields.io/crates/v/mop.svg)](https://crates.io/crates/mop)\n[![Documentation](https://docs.rs/mop/badge.svg)](https://docs.rs/mop)\n[![License](https://img.shields.io/badge/license-APACHE2-blue.svg)](./LICENSE)\n[![Rustc](https://img.shields.io/badge/rustc-1.42-lightgray\")](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html)\n\nMOP 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.\n\nSee [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/).\n\n## Example\n\nThe definitions and results of `Binh and Korn`, a multi-objective problem with two hard constraints and two objectives.\n\n![Binh and Korn](https://imgur.com/VDB0oBM.jpg)\n\n###### Picture taken from https://en.wikipedia.org/wiki/Test_functions_for_optimization#Test_functions_for_multi-objective_optimization.\n\n```rust\n// Binh T. and Korn U. (1997) MOBES: A Multiobjective Evolution Strategy for Constrained Optimization Problems\n\nuse core::cmp::Ordering;\nuse mop::{\n  blocks::{\n    gp::{\n      mp_defs_from_gp_defs, GpOperations, MpVec, MphDefinitionsBuilder, MphMpMph, MphOrRef, MphVec,\n    },\n    objs::MinCstrsRslts,\n    quality_comparator::ObjsAvg,\n    ObjDirection, Pct,\n  },\n  facades::opt::OptFacade,\n  solvers::genetic_algorithm::{\n    operators::{\n      crossover::MultiPoint, mating_selection::Tournament, mutation::RandomDomainAssignments,\n    },\n    GeneticAlgorithmParamsBuilder, Spea2,\n  },\n};\n\nconst RSLTS_NUM: usize = 200;\n\ntype Solution = [f64; 2];\n\nfn f1(s: \u0026Solution) -\u003e f64 {\n  4.0 * s[0].powi(2) + 4.0 * s[1].powi(2)\n}\n\nfn f2(s: \u0026Solution) -\u003e f64 {\n  (s[0].powi(2) - 10.0 * s[0] + 25.0) + (s[1].powi(2) - 10.0 * s[1] + 25.0)\n}\n\nfn g1(s: \u0026Solution) -\u003e usize {\n  let lhs = (s[0].powi(2) - 10.0 * s[0] + 25.0) + s[1].powi(2);\n  match lhs.partial_cmp(\u002625.0) {\n    Some(Ordering::Equal) | Some(Ordering::Less) =\u003e 0,\n    _ =\u003e 1,\n  }\n}\n\nfn g2(s: \u0026Solution) -\u003e usize {\n  let lhs = (s[0].powi(2) - 16.0 * s[0] + 64.0) + (s[1].powi(2) + 6.0 * s[1] + 9.0);\n  match lhs.partial_cmp(\u00267.7) {\n    Some(Ordering::Equal) | Some(Ordering::Greater) =\u003e 0,\n    _ =\u003e 1,\n  }\n}\n\nfn print_result(result: MphOrRef\u003cf64, Solution\u003e) {\n  let solution = result.solution();\n  let objs = result.obj_rslts();\n  let hcs = result.hard_cstr_rslts();\n  println!(\"x0: {}, x1: {}\", solution[0], solution[1]);\n  println!(\"f1: {}, f2: {}\", objs[0], objs[1]);\n  println!(\"g1: {}, g2: {}\", hcs[0], hcs[1]);\n  println!();\n}\n\nfn main() -\u003e Result\u003c(), mop::blocks::Error\u003e {\n  // Problem definitions and results\n  let mut mph = MphVec::with_capacity(\n    MphDefinitionsBuilder::default()\n      .domain([0.0..=5.0, 0.0..=3.0])\n      .name(\"Binh and Korn\")\n      .push_hard_cstr(g1 as fn(\u0026Solution) -\u003e usize)\n      .push_hard_cstr(g2 as fn(\u0026Solution) -\u003e usize)\n      .push_obj((ObjDirection::Min, f1 as fn(\u0026Solution) -\u003e f64))\n      .push_obj((ObjDirection::Min, f2 as fn(\u0026Solution) -\u003e f64))\n      .build()?,\n    RSLTS_NUM,\n  );\n  let (mph_defs, mut mph_rslts) = mph.parts_mut();\n\n  // SPEA2 is an unconstrained solver but Binh and Korn is a constrained problem. To workaround\n  // this incompatibility, our `mph` problem is converted to a `mp` problem by adding an objective\n  // that minimizes all constraints violations.\n  //\n  // It is possible to define your own converstion procedure with any desired set of objectives.\n  let mcr = MinCstrsRslts::from_gp_hcs(mph_defs);\n  let mp_defs_ref = mp_defs_from_gp_defs(mph_defs).push_obj((\u0026mcr).into()).build()?;\n  let mut mp_ref = MpVec::with_random_solutions(mp_defs_ref, 100)?;\n\n  // SPEA2 and overall genetic algorithm parameters are specified here.\n  let spea2 = Spea2::new(\n    Pct::from_percent(50),\n    GeneticAlgorithmParamsBuilder::default()\n      .crossover(MultiPoint::new(1, Pct::from_percent(70)))\n      .mating_selection(Tournament::new(10, ObjsAvg))\n      .mutation(RandomDomainAssignments::new(1, Pct::from_percent(30)))\n      .build()?,\n    \u0026mp_ref,\n    RSLTS_NUM,\n  )?;\n\n  // Generic criterias to inspect or stop the solving process.\n  let of = OptFacade::new(50)\n    .set_opt_hooks(())\n    .set_quality_comparator(ObjsAvg)\n    .set_stagnation(Pct::from_percent(2), 10)?\n    .solve_problem_with(\u0026mut mp_ref, spea2)\n    ?;\n\n  // Transfers all solutions and objectives results of `mp` to `mph`.\n  MphMpMph::transfer(\u0026mph_defs, \u0026mut mph_rslts, \u0026mp_ref)?;\n\n  for (result_idx, result) in mph_rslts.iter().enumerate() {\n    println!(\"***** Result #{} *****\", result_idx + 1);\n    print_result(result);\n  }\n\n  if let Some(best_idx) = of.curr_best_idx() {\n    if let Some(result) = mph.rslts().get(best_idx) {\n      println!(\"***** Best result *****\");\n      print_result(result);\n    }\n  }\n\n  Ok(())\n}\n```\n\n![Binh and Korn - Objectives](https://imgur.com/VwmLLzP.jpg)\n\n## Solvers\n\n* `SPEA2` (Zitzler and Thiele; SPEA2: Improving the Strength Pareto Evolutionary Algorithm)\n\n## Features\n\n- `no_std` by default\n- Different storages (Array, Vec, Slice and more!)\n- Fuzz testing\n- No `unsafe`\n\n## Optional features\n\n- `std`\n- Bindings (wasm-bindgen)\n- Parallel evaluation (rayon)\n- Deserialization/Serialization (serde)\n- Multidimensional storage (ndstruct)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fc410-f3r%2Fmop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fc410-f3r%2Fmop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fc410-f3r%2Fmop/lists"}