Skip to main content

papilo_rs/
problem.rs

1use crate::ffi;
2use std::ffi::{CStr, CString};
3
4/// A struct representing a problem in the Papilo library.
5pub struct Problem {
6    raw: *mut ffi::Papilo_Problem,
7}
8
9impl Problem {
10    /// Returns a raw pointer to the underlying `Papilo_Problem`.
11    pub fn raw(&self) -> *mut ffi::Papilo_Problem {
12        self.raw
13    }
14
15    /// Creates a new `Problem` instance with default parameters.
16    pub fn new() -> Self {
17        let problem_name = CStr::from_bytes_until_nul(b"papilo-rs\0").unwrap();
18        let raw = unsafe {
19            ffi::papilo_problem_create(f64::INFINITY, problem_name.as_ptr(), 1000, 10, 10)
20        };
21        assert!(!raw.is_null());
22        Problem { raw }
23    }
24
25    /// Adds a column to the problem.
26    pub fn add_col(&mut self, lb: f64, ub: f64, integer: bool, cost: f64, name: &str) -> usize {
27        let c_name = CString::new(name).expect("Failed to create CString");
28        unsafe {
29            ffi::papilo_problem_add_col(
30                self.raw,
31                lb,
32                ub,
33                integer.into(),
34                cost,
35                c_name.as_ptr(),
36            ).try_into()
37                .expect("Failed to add column")
38        }
39    }
40
41
42    /// Adds a row to the problem.
43    pub fn add_row(&mut self, name: &str, coefficients: &[(usize, f64)], lhs: f64, rhs: f64) -> usize {
44        let c_name = CString::new(name).expect("Failed to create CString");
45        let row_id = unsafe {
46            ffi::papilo_problem_add_generic_row(
47                self.raw,
48                lhs,
49                rhs,
50                c_name.as_ptr(),
51            )
52        } as usize;
53
54        for &(col_id, coeff) in coefficients {
55            self.set_row_coef(row_id, col_id, coeff);
56        }
57
58
59        row_id
60    }
61
62
63    /// Sets a coefficient for a specific row and column.
64    pub fn set_row_coef(&mut self, row_id: usize, col_id: usize, value: f64) {
65        unsafe {
66            ffi::papilo_problem_add_nonzero(self.raw, row_id as i32, col_id as i32, value);
67        }
68    }
69}
70
71impl Drop for Problem {
72    fn drop(&mut self) {
73        if !self.raw.is_null() {
74            unsafe { ffi::papilo_problem_free(self.raw) };
75        }
76    }
77}