cplex_rs_sys/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4#![allow(clippy::approx_constant)]
5
6include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
7
8#[cfg(test)]
9mod tests {
10    use super::*;
11    use std::ffi::CString;
12
13    #[test]
14    fn mipex1() {
15        const NUMROWS: usize = 3;
16        const NUMCOLS: usize = 4;
17        const NUMNZ: usize = 9;
18
19        let mut status = 0;
20        let env = unsafe { CPXopenCPLEX(&mut status) };
21
22        if env.is_null() {
23            panic!("Could not open CPLEX environment");
24        }
25
26        status = unsafe { CPXsetintparam(env, CPXPARAM_ScreenOutput as i32, CPX_ON as i32) };
27        if status != 0 {
28            panic!("Failure to turn on screen indicator");
29        }
30
31        let probname = CString::new("example").expect("CString::new failed");
32        let lp = unsafe { CPXcreateprob(env, &mut status, probname.as_c_str().as_ptr()) };
33        if lp.is_null() {
34            panic!("Failed to create LP");
35        }
36
37        let zobj = unsafe {
38            libc::malloc(NUMCOLS * std::mem::size_of::<libc::c_double>()) as *mut libc::c_double
39        };
40        let zrhs = unsafe {
41            libc::malloc(NUMROWS * std::mem::size_of::<libc::c_double>()) as *mut libc::c_double
42        };
43        let zsense = unsafe {
44            libc::malloc(NUMROWS * std::mem::size_of::<libc::c_char>()) as *mut libc::c_char
45        };
46        let zmathbeg = unsafe {
47            libc::malloc(NUMCOLS * std::mem::size_of::<libc::c_int>()) as *mut libc::c_int
48        };
49        let zmathcnt = unsafe {
50            libc::malloc(NUMCOLS * std::mem::size_of::<libc::c_int>()) as *mut libc::c_int
51        };
52        let zmathind =
53            unsafe { libc::malloc(NUMNZ * std::mem::size_of::<libc::c_int>()) as *mut libc::c_int };
54        let zmathval = unsafe {
55            libc::malloc(NUMNZ * std::mem::size_of::<libc::c_double>()) as *mut libc::c_double
56        };
57        let zlb = unsafe {
58            libc::malloc(NUMCOLS * std::mem::size_of::<libc::c_double>()) as *mut libc::c_double
59        };
60        let zub = unsafe {
61            libc::malloc(NUMCOLS * std::mem::size_of::<libc::c_double>()) as *mut libc::c_double
62        };
63        let zctype = unsafe {
64            libc::malloc(NUMCOLS * std::mem::size_of::<libc::c_char>()) as *mut libc::c_char
65        };
66        let obj = unsafe { std::slice::from_raw_parts_mut(zobj, NUMCOLS) };
67
68        let rhs = unsafe { std::slice::from_raw_parts_mut(zrhs, NUMROWS) };
69        let sense = unsafe { std::slice::from_raw_parts_mut(zsense, NUMROWS) };
70        let mathbeg = unsafe { std::slice::from_raw_parts_mut(zmathbeg, NUMCOLS) };
71        let mathcnt = unsafe { std::slice::from_raw_parts_mut(zmathcnt, NUMCOLS) };
72        let mathind = unsafe { std::slice::from_raw_parts_mut(zmathind, NUMNZ) };
73        let mathval = unsafe { std::slice::from_raw_parts_mut(zmathval, NUMNZ) };
74        let lb = unsafe { std::slice::from_raw_parts_mut(zlb, NUMCOLS) };
75        let ub = unsafe { std::slice::from_raw_parts_mut(zub, NUMCOLS) };
76        let ctype = unsafe { std::slice::from_raw_parts_mut(zctype, NUMCOLS) };
77
78        obj[0] = 1.0;
79        obj[1] = 2.0;
80        obj[2] = 3.0;
81        obj[3] = 1.0;
82
83        mathbeg[0] = 0;
84        mathbeg[1] = 2;
85        mathbeg[2] = 5;
86        mathbeg[3] = 7;
87
88        mathcnt[0] = 2;
89        mathcnt[1] = 3;
90        mathcnt[2] = 2;
91        mathcnt[3] = 2;
92
93        mathind[0] = 0;
94        mathval[0] = -1.0;
95        mathind[2] = 0;
96        mathval[2] = 1.0;
97        mathind[5] = 0;
98        mathval[5] = 1.0;
99        mathind[7] = 0;
100        mathval[7] = 10.0;
101
102        mathind[1] = 1;
103        mathval[1] = 1.0;
104        mathind[3] = 1;
105        mathval[3] = -3.0;
106        mathind[6] = 1;
107        mathval[6] = 1.0;
108
109        mathind[4] = 2;
110        mathval[4] = 1.0;
111        mathind[8] = 2;
112        mathval[8] = -3.5;
113
114        lb[0] = 0.0;
115        lb[1] = 0.0;
116        lb[2] = 0.0;
117        lb[3] = 2.0;
118
119        ub[0] = 40.0;
120        ub[1] = 1e+20;
121        ub[2] = 1e+20;
122        ub[3] = 3.0;
123
124        ctype[0] = 'C' as libc::c_char;
125        ctype[1] = 'C' as libc::c_char;
126        ctype[2] = 'C' as libc::c_char;
127        ctype[3] = 'I' as libc::c_char;
128
129        sense[0] = 'L' as libc::c_char;
130        rhs[0] = 20.0;
131
132        sense[1] = 'L' as libc::c_char;
133        rhs[1] = 30.0;
134
135        sense[2] = 'E' as libc::c_char;
136        rhs[2] = 0.0;
137
138        status = unsafe {
139            CPXcopylp(
140                env,
141                lp,
142                NUMCOLS as libc::c_int,
143                NUMROWS as libc::c_int,
144                CPX_MAX,
145                zobj,
146                zrhs,
147                zsense,
148                zmathbeg,
149                zmathcnt,
150                zmathind,
151                zmathval,
152                zlb,
153                zub,
154                std::ptr::null(),
155            )
156        };
157
158        if status != 0 {
159            panic!("Failed to copy problem data");
160        }
161
162        status = unsafe { CPXcopyctype(env, lp, zctype) };
163
164        if status != 0 {
165            panic!("Failed to copy ctype");
166        }
167
168        status = unsafe { CPXmipopt(env, lp) };
169
170        if status != 0 {
171            panic!("Failed to optimize MIP");
172        }
173
174        let solstat = unsafe { CPXgetstat(env, lp) };
175
176        println!("Solution status = {}", solstat);
177
178        let mut objval = 0.0;
179        status = unsafe { CPXgetobjval(env, lp, &mut objval) };
180        if status != 0 {
181            panic!("No MIP objective value available");
182        }
183
184        assert_eq!(objval, 122.5);
185    }
186}