### Add LAPJV and ndarray to Project Source: https://context7.com/antti/lapjv-rust/llms.txt Add the lapjv and ndarray crates to your Cargo.toml file to include them in your project. ```toml [dependencies] lapjv = "0.3.0" ndarray = "0.16" ``` -------------------------------- ### Solve LAP with Cancellation Support using LapJV struct Source: https://context7.com/antti/lapjv-rust/llms.txt Utilize the `LapJV` struct for solving the Linear Assignment Problem with cooperative cancellation. Obtain a `Cancellation` token to share with another thread, allowing external cancellation of the solve operation. ```rust use lapjv::{LapJV, Matrix, ErrorKind}; use std::thread; use std::time::Duration; fn main() { let m = Matrix::from_shape_vec( (4, 4), vec![ 10.0, 20.0, 30.0, 40.0, 15.0, 25.0, 35.0, 45.0, 12.0, 22.0, 32.0, 42.0, 18.0, 28.0, 38.0, 48.0, ], ) .unwrap(); let solver = LapJV::new(&m); // Obtain a cancellation token to share with another thread let cancel_token = solver.cancellation(); // Spawn a thread that cancels the solve after 1ms (useful for very large matrices) thread::spawn(move || { thread::sleep(Duration::from_millis(1)); cancel_token.cancel(); }); match solver.solve() { Ok((row_sol, col_sol)) => { println!("Solved: {:?}", row_sol); println!("Col solution: {:?}", col_sol); } Err(e) => match e.kind() { ErrorKind::Cancelled => println!("Solve was cancelled by external signal"), ErrorKind::Msg(msg) => eprintln!("Solver error: {}", msg), }, } } ``` -------------------------------- ### Thread-Safe Cancellation Token in Rust Source: https://context7.com/antti/lapjv-rust/llms.txt Demonstrates how to use the cancellation token to signal and check for cancellation during a solve operation. Multiple clones of the token share the same atomic flag. ```rust use lapjv::{LapJV, Matrix}; fn main() { let m = Matrix::from_shape_vec( (3, 3), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], ) .unwrap(); let solver = LapJV::new(&m); let token_a = solver.cancellation(); let token_b = token_a.clone(); // Both share the same atomic flag println!("Cancelled before: {}", token_a.is_cancelled()); // false token_b.cancel(); println!("Cancelled after: {}", token_a.is_cancelled()); // true // solve() will now immediately return Err with ErrorKind::Cancelled let result = solver.solve(); assert!(result.is_err()); } ``` -------------------------------- ### LapJV struct — Solver with Cancellation Support Source: https://context7.com/antti/lapjv-rust/llms.txt The `LapJV` struct offers a builder pattern for solving the Linear Assignment Problem and supports cooperative cancellation from other threads. ```APIDOC ## LapJV struct — Solver with Cancellation Support ### Description The `LapJV` struct provides a builder-style interface via `LapJV::new()` and `.solve()`. Before calling `.solve()`, you can obtain a `Cancellation` token via `.cancellation()` and share it with another thread. Calling `cancellation.cancel()` from any thread will cause `.solve()` to return `Err(LapJVError { kind: ErrorKind::Cancelled })` at the next checkpoint. ### Methods - **`new(matrix: &Matrix)`**: Creates a new `LapJV` solver instance with the given cost matrix. - **`cancellation()`**: Returns a `Cancellation` token that can be used to cancel the solve operation. - **`solve()`**: Executes the LAPJV algorithm and returns the assignment. ### Parameters #### `new()` - **matrix** (`&Matrix`) - The cost matrix to solve. #### `solve()` None ### Request Example ```rust use lapjv::{LapJV, Matrix, ErrorKind}; use std::thread; use std::time::Duration; fn main() { let m = Matrix::from_shape_vec( (4, 4), vec![ 10.0, 20.0, 30.0, 40.0, 15.0, 25.0, 35.0, 45.0, 12.0, 22.0, 32.0, 42.0, 18.0, 28.0, 38.0, 48.0, ], ) .unwrap(); let solver = LapJV::new(&m); // Obtain a cancellation token to share with another thread let cancel_token = solver.cancellation(); // Spawn a thread that cancels the solve after 1ms (useful for very large matrices) thread::spawn(move || { thread::sleep(Duration::from_millis(1)); cancel_token.cancel(); }); match solver.solve() { Ok((row_sol, col_sol)) => { println!("Solved: {:?}", row_sol); println!("Col solution: {:?}", col_sol); } Err(e) => match e.kind() { ErrorKind::Cancelled => println!("Solve was cancelled by external signal"), ErrorKind::Msg(msg) => eprintln!("Solver error: {}", msg), }, } } ``` ### Response #### Success Response (Ok) - **row_solution** (Vec) - A vector where `row_solution[i]` is the column assigned to row `i`. - **col_solution** (Vec) - A vector where `col_solution[j]` is the row assigned to column `j`. #### Error Response (Err) - **LapJVError** - An error indicating why the assignment could not be computed. This can be `ErrorKind::Cancelled` if the operation was cancelled, or `ErrorKind::Msg` with a specific error message. ### Response Example ```json // On success: // Solved: [3, 2, 1, 0] // Col solution: [3, 2, 1, 0] // On cancellation: // Solve was cancelled by external signal ``` ``` -------------------------------- ### Solve Linear Assignment Problem with lapjv() Source: https://context7.com/antti/lapjv-rust/llms.txt Use the `lapjv()` function to find the optimal assignment for a given cost matrix. It returns the row and column solutions on success or a `LapJVError` if the matrix is not square. ```rust use lapjv::{lapjv, Matrix}; fn main() { // 3x3 cost matrix: rows = workers, columns = jobs let costs = Matrix::from_shape_vec( (3, 3), vec![ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, ], ) .unwrap(); match lapjv(&costs) { Ok((row_sol, col_sol)) => { // row_sol[i] = column assigned to row i // col_sol[j] = row assigned to column j println!("Row solution: {:?}", row_sol); // [2, 0, 1] println!("Col solution: {:?}", col_sol); // [1, 2, 0] } Err(e) => eprintln!("Error: {}", e), } } ``` -------------------------------- ### Generic Floating-Point Costs with LapJVCost in Rust Source: https://context7.com/antti/lapjv-rust/llms.txt Shows how the `LapJVCost` trait enables the `lapjv` function to work seamlessly with both `f32` and `f64` cost matrices without additional configuration. ```rust use lapjv::{lapjv, Matrix}; fn main() { // f32 cost matrix let costs_f32 = Matrix::::from_shape_vec( (3, 3), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], ) .unwrap(); let result_f32 = lapjv(&costs_f32).unwrap(); println!("f32 solution: {:?}", result_f32.0); // [2, 0, 1] // f64 cost matrix let costs_f64 = Matrix::::from_shape_vec( (3, 3), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], ) .unwrap(); let result_f64 = lapjv(&costs_f64).unwrap(); println!("f64 solution: {:?}", result_f64.0); // [2, 0, 1] } ``` -------------------------------- ### lapjv() — Solve the Linear Assignment Problem Source: https://context7.com/antti/lapjv-rust/llms.txt The `lapjv()` function provides a simple way to solve the Linear Assignment Problem. It takes a square cost matrix and returns the optimal assignment. ```APIDOC ## lapjv() — Solve the Linear Assignment Problem ### Description The `lapjv()` function takes a reference to a square `ndarray::Array2` cost matrix and returns an `Ok((row_solution, col_solution))` tuple on success. `row_solution[i]` gives the column assigned to row `i`; `col_solution[j]` gives the row assigned to column `j`. Returns `Err(LapJVError)` if the matrix is not square. ### Method `lapjv(&costs)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use lapjv::{lapjv, Matrix}; fn main() { // 3x3 cost matrix: rows = workers, columns = jobs let costs = Matrix::from_shape_vec( (3, 3), vec![ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, ], ) .unwrap(); match lapjv(&costs) { Ok((row_sol, col_sol)) => { // row_sol[i] = column assigned to row i // col_sol[j] = row assigned to column j println!("Row solution: {:?}", row_sol); // [2, 0, 1] println!("Col solution: {:?}", col_sol); // [1, 2, 0] } Err(e) => eprintln!("Error: {}", e), } } ``` ### Response #### Success Response (Ok) - **row_solution** (Vec) - A vector where `row_solution[i]` is the column assigned to row `i`. - **col_solution** (Vec) - A vector where `col_solution[j]` is the row assigned to column `j`. #### Error Response (Err) - **LapJVError** - An error indicating why the assignment could not be computed (e.g., non-square matrix). ### Response Example ```json // On success: // Row solution: [2, 0, 1] // Col solution: [1, 2, 0] // On error: // Error: Input matrix must be square. ``` ``` -------------------------------- ### Structured Error Handling with LapJVError in Rust Source: https://context7.com/antti/lapjv-rust/llms.txt Illustrates how to handle potential errors from the `lapjv` function, distinguishing between input errors (non-square matrix) and cancellation errors. Inspect the error kind using `.kind()`. ```rust use lapjv::{lapjv, Matrix, ErrorKind}; fn try_solve(rows: usize, cols: usize) { // Deliberately construct a non-square matrix to trigger an error let data: Vec = (0..(rows * cols)).map(|x| x as f64).collect(); // ndarray requires the total size to match; simulate a shape mismatch scenario // by passing a square matrix but with a non-square logical expectation let m = Matrix::from_shape_vec((rows, cols), data).unwrap(); match lapjv(&m) { Ok((row_sol, _)) => println!("Solution: {:?}", row_sol), Err(e) => match e.kind() { ErrorKind::Msg(msg) => { // "Input error: matrix is not square" eprintln!("Input error caught: {}", msg); } ErrorKind::Cancelled => { eprintln!("Solve was cancelled"); } }, } } fn main() { try_solve(3, 3); // OK // A non-square matrix (e.g., 2x3) passed to lapjv() returns Err(Msg(...)) } ``` -------------------------------- ### Calculate Total Assignment Cost with cost() Source: https://context7.com/antti/lapjv-rust/llms.txt Compute the total cost of an assignment using the `cost()` function, which sums the costs from the original matrix based on the provided row solution. This is useful after obtaining a solution from `lapjv()`. ```rust use lapjv::{lapjv, cost, Matrix}; fn main() { let c = vec![ 612.0, 643.0, 717.0, 2.0, 946.0, 534.0, 242.0, 235.0, 376.0, 839.0, 224.0, 141.0, 799.0, 180.0, 386.0, 745.0, 592.0, 822.0, 421.0, 42.0, 241.0, 369.0, 831.0, 67.0, 258.0, ]; let matrix = Matrix::from_shape_vec((5, 5), c).unwrap(); let (row_sol, _col_sol) = lapjv(&matrix).unwrap(); let total_cost = cost(&matrix, &row_sol); println!("Optimal assignment: {:?}", row_sol); println!("Total cost: {}", total_cost); // Total cost is the minimum possible sum of assigned costs } ``` -------------------------------- ### Solve Linear Assignment Problem in Rust Source: https://github.com/antti/lapjv-rust/blob/master/README.md Use the `lapjv` function to solve the Linear Assignment Problem. Ensure the `lapjv` crate is added as a dependency and imported. The function takes a cost matrix and returns the optimal assignment and its cost. ```rust use lapjv::lapjv; let m = Matrix::from_shape_vec((3, 3), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]).unwrap(); let result = lapjv(&m).unwrap(); assert_eq!(result.0, vec![2, 0, 1]); assert_eq!(result.1, vec![1, 2, 0]); ``` -------------------------------- ### cost() — Calculate Total Assignment Cost Source: https://context7.com/antti/lapjv-rust/llms.txt The `cost()` function calculates the total cost of an assignment given the original cost matrix and the row solution vector. ```APIDOC ## cost() — Calculate Total Assignment Cost ### Description The `cost()` function computes the total cost of a given assignment by summing `matrix[(i, row[i])]` for all rows `i`. It takes the original cost matrix and the row solution vector returned by `lapjv()`. ### Method `cost(&matrix, &row_solution)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use lapjv::{lapjv, cost, Matrix}; fn main() { let c = vec![ 612.0, 643.0, 717.0, 2.0, 946.0, 534.0, 242.0, 235.0, 376.0, 839.0, 224.0, 141.0, 799.0, 180.0, 386.0, 745.0, 592.0, 822.0, 421.0, 42.0, 241.0, 369.0, 831.0, 67.0, 258.0, ]; let matrix = Matrix::from_shape_vec((5, 5), c).unwrap(); let (row_sol, _col_sol) = lapjv(&matrix).unwrap(); let total_cost = cost(&matrix, &row_sol); println!("Optimal assignment: {:?}", row_sol); println!("Total cost: {}", total_cost); // Total cost is the minimum possible sum of assigned costs } ``` ### Response #### Success Response - **total_cost** (f64) - The sum of the costs for the optimal assignment. #### Response Example ```json // Total cost: 1177.0 (example value) ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.