1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
// Copyright : Copyright (c) MOSEK ApS, Denmark. All rights reserved.
//
// File : lo2.rs
//
// Purpose : Demonstrates how to solve a small linear
// optimization problem using the MOSEK Java API.
extern crate mosek;
extern crate itertools;
use mosek::{Task,Boundkey,Objsense,Streamtype,Solsta,Soltype};
use itertools::izip;
const INF : f64 = 0.0;
fn main() -> Result<(),String> {
let numcon : i32 = 3;
let numvar : i32 = 4;
let c = [3.0, 1.0, 5.0, 1.0];
let asub = [0, 1, 2,
0, 1, 2, 3,
1, 3];
let aval = [3.0, 1.0, 2.0,
2.0, 1.0, 3.0, 1.0,
2.0, 3.0];
let aptr = [0,3,7,9];
let bkc = [Boundkey::FX,
Boundkey::LO,
Boundkey::UP];
let blc = [30.0,
15.0,
-INF];
let buc = [30.0,
INF,
25.0];
let bkx = [Boundkey::LO,
Boundkey::RA,
Boundkey::LO,
Boundkey::LO];
let blx = [0.0,
0.0,
0.0,
0.0];
let bux = [INF,
10.0,
INF,
INF];
// Create a task object linked with the environment env.
let mut task = Task::new().unwrap().with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Give MOSEK an estimate of the size of the input data.
This is done to increase the speed of inputting data.
However, it is optional. */
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for (j,(&cj,&bkj,&blj,&buj)) in izip!(c.iter(),bkx.iter(),blx.iter(),bux.iter()).enumerate() {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32, cj)?;
/* Set the bounds on variable j.
blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, bkj, blj, buj)?;
};
/* Set the bounds on constraints.
for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,(&bki,&bli,&bui,&ptrb,&ptre)) in izip!(bkc.iter(),blc.iter(),buc.iter(),aptr[..aptr.len()-1].iter(),aptr[1..].iter()).enumerate() {
task.put_con_bound(i as i32, bki, bli, bui)?;
/* Input row i of A */
task.put_a_row(i as i32, /* Row index.*/
&asub[ptrb..ptre], /* Column indexes of non-zeros in row i.*/
&aval[ptrb..ptre])?; /* Non-zero Values of row i. */
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS, // Basic solution.
xx.as_mut_slice());
match solsta {
Solsta::OPTIMAL =>
println!("Optimal primal solution = {:?}",xx),
Solsta::DUAL_INFEAS_CER|Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility."),
Solsta::UNKNOWN =>
println!("Unknown solution status."),
_ =>
println!("Other solution status")
}
Ok(())
}