milo1/milo1.rs
1//!
2//!   Copyright : Copyright (c) MOSEK ApS, Denmark. All rights reserved.
3//!
4//!   File : milo1.rs
5//!
6//!   Purpose :   Demonstrates how to solve a small mixed
7//!               integer linear optimization problem using the MOSEK Java API.
8//!
9extern crate mosek;
10
11use mosek::{Task,Boundkey,Objsense,Streamtype,Solsta,Prosta,Soltype,Variabletype,Dparam};
12
13fn main() -> Result<(),String> {
14    let numcon : i32 = 2;
15    let numvar : i32 = 2;
16
17    let infinity = 0.0; // only for symbolic purposes, value never used
18
19    let bkc = vec![Boundkey::UP, Boundkey::LO];
20    let blc = vec![ -infinity,         -4.0 ];
21    let buc = vec![ 250.0,             infinity ];
22
23    let bkx = vec![ Boundkey::LO, Boundkey::LO  ];
24    let blx = vec![ 0.0,               0.0 ];
25    let bux = vec![ infinity,          infinity ];
26
27    let c   = vec![1.0, 0.64];
28
29    let asub = vec![0,   1,
30                    0,    1];
31    let aval = vec![50.0, 3.0, 31.0, -2.0];
32
33    let ptrb : Vec<usize> = vec![ 0, 2 ];
34    let ptre : Vec<usize> = vec![ 2, 4 ];
35
36    /* Create the optimization task. */
37    Task::new().expect("Failed to create task")
38        .with_stream_callback(
39            Streamtype::LOG,
40            &mut |msg| print!("{}",msg),
41            |task| task.with_itg_sol_callback(
42                &mut |xx| { println!("Found a new solution = {:?}",xx); false },
43                |task| {
44                    /* Append 'numcon' empty constraints.
45                    The constraints will initially have no bounds. */
46                    task.append_cons(numcon)?;
47
48                    /* Append 'numvar' variables.
49                    The variables will initially be fixed at zero (x=0). */
50                    task.append_vars(numvar)?;
51
52                    for ((((j,cj),bk),bl),bu) in (0..numvar).zip(c.iter()).zip(bkx.iter()).zip(blx.iter()).zip(bux.iter()) {
53                        /* Set the linear term c_j in the objective.*/
54                        task.put_c_j(j, *cj)?;
55                        /* Set the bounds on variable j.
56                           blx[j] <= x_j <= bux[j] */
57                        task.put_var_bound(j, *bk, *bl, *bu)?;
58                        /* Input column j of A */
59                        task.put_a_col(j,                     /* Variable (column) index.*/
60                                       &asub[ptrb[j as usize]..ptre[j as usize]],               /* Row index of non-zeros in column j.*/
61                                       &aval[ptrb[j as usize]..ptre[j as usize]])?;              /* Non-zero Values of column j. */
62                    }
63                    // Set the bounds on constraints.
64                    // for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] 
65                    for (((i,bk),bl),bu) in (0..numcon).zip(bkc.iter()).zip(blc.iter()).zip(buc.iter()) {
66                        task.put_con_bound(i, *bk, *bl, *bu)?;
67                    }
68
69                    /* Specify integer variables. */
70                    for j in 0..numvar {
71                        task.put_var_type(j, Variabletype::TYPE_INT)?;
72                    }
73                    /* Set max solution time */
74                    task.put_dou_param(Dparam::MIO_MAX_TIME, 60.0)?;
75
76                    /* A maximization problem */
77                    task.put_obj_sense(Objsense::MAXIMIZE)?;
78                    /* Solve the problem */
79
80                    let _trm = task.optimize()?;
81
82                    // Print a summary containing information
83                    //   about the solution for debugging purposes
84                    task.solution_summary(Streamtype::MSG)?;
85
86                    let mut xx = vec![0.0; numvar as usize];
87                    task.get_xx(Soltype::ITG, xx.as_mut_slice())?;
88
89                    /* Get status information about the solution */
90
91                    match task.get_sol_sta(Soltype::ITG)? {
92                        Solsta::INTEGER_OPTIMAL => {
93                            println!("Optimal solution");
94                            for (j,xj) in (0..numvar).zip(xx.iter()) {
95                                println!("x[{}]: {}", j,xj);
96                            }
97                        }
98                        Solsta::PRIM_FEAS => {
99                            println!("Feasible solution");
100                            for (j,xj) in (0..numvar).zip(xx.iter()) {
101                                println!("x[{}]: {}", j,xj);
102                            }
103                        }
104                        Solsta::UNKNOWN => {
105                          match task.get_pro_sta(Soltype::ITG)? {
106                              Prosta::PRIM_INFEAS_OR_UNBOUNDED => {
107                                  println!("Problem status Infeasible or unbounded");
108                              }
109                              Prosta::PRIM_INFEAS => {
110                                  println!("Problem status Infeasible.");
111                              }
112                              Prosta::UNKNOWN => {
113                                  println!("Problem status unknown.");
114                              }
115                              _ => {
116                                  println!("Other problem status.");
117                              }
118                          }
119                        }
120                        _ => {
121                            println!("Other solution status");
122                        }
123                    }
124                    Ok(())
125                }))
126}
127
128
129#[cfg(test)]
130mod tests {
131    #[test]
132    fn test() {
133        super::main().unwrap();
134    }
135}