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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//!
//! Copyright : Copyright (c) MOSEK ApS, Denmark. All rights reserved.
//!
//! File : solvebasis.rs
//!
extern crate mosek;
use mosek::{Task,Boundkey,Objsense,Streamtype};
/// Demonstrate the usage of solve_with_basis on the problem:
///
/// ```
/// maximize x0 + x1
/// st.
/// x0 + 2.0 x1 <= 2
/// x0 + x1 <= 6
/// x0 >= 0, x1>= 0
/// ```
///
/// The problem has the slack variables `xc0`, `xc1` on the
/// constraints and the variabels `x0` and `x1`.
///
/// ```
/// maximize x0 + x1
/// st.
/// x0 + 2.0 x1 -xc1 = 2
/// x0 + x1 -xc2 = 6
/// x0 >= 0, x1>= 0,
/// xc1 <= 0 , xc2 <= 0
/// ```
///
fn solve() -> Result<(),String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.put_obj_name("solvebasis")?;
let numcon : i32 = 2;
let numvar : i32 = 2;
let mut w1 = vec![2.0, 6.0];
let mut w2 = vec![1.0, 0.0];
task.input_data(numcon, numvar,
&[1.0, 1.0], // c
0.0, // cfix
&[0,2], // ptrb
&[2,3], // ptre
&[0,1,
0,1], // sub
&[1.0, 1.0,
2.0, 1.0], // val
&[Boundkey::UP,
Boundkey::UP], // bkc
&[0.0,0.0], // blc
&[2.0,6.0], // buc
&[Boundkey::LO,
Boundkey::LO], // bkx
&[0.0, 0.0], // blx
&[0.0,0.0])?; // bux;
task.put_obj_sense(Objsense::MAXIMIZE)?;
let _ = task.optimize()?;
let mut basis = vec![0i32; numcon as usize];
task.init_basis_solve(basis.as_mut_slice())?;
// List basis variables corresponding to columns of B
let mut varsub = vec![0i32, 1];
for i in 0..numcon {
if basis[varsub[i as usize] as usize] < numcon {
println!("Basis variable no {} is xc{}",i,basis[varsub[i as usize] as usize]);
}
else {
println!("Basis variable no {} is x{}",i,basis[i as usize]-numcon);
// solve Bx = w1
// varsub contains index of non-zeros in b.
// On return b contains the solution x and
// varsub the index of the non-zeros in x.
{
let nz = task.solve_with_basis(false, 2, varsub.as_mut_slice(), w1.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to Bx = {:?}",w1);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
println!("xc {} = {}",basis[*vsubi as usize],w1[*vsubi as usize]);
}
else {
println!("x{} = {}",basis[*vsubi as usize] - numcon,w1[*vsubi as usize])
}
}
}
// Solve B^Tx = w2
{
varsub[0] = 1;
let nz = task.solve_with_basis(true,1,varsub.as_mut_slice(),w2.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to B^Tx = {:?}",w2);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
print!("xc{} = {}",basis[*vsubi as usize],w2[*vsubi as usize]);
}
else {
print!("x{} = {}",basis[*vsubi as usize] - numcon,w2[*vsubi as usize]);
}
}
}
}
}
Ok(())
}
fn main() -> Result<(),String> {
solve()
}
#[cfg(test)]
mod tests {
#[test]
fn test() {
super::main().unwrap();
}
}