Skip to main content

djc1/
djc1.rs

1//
2//   Copyright: MOSEK ApS
3//
4//   File:      djc1.rs
5//
6//   Purpose: Demonstrates how to solve the problem with two disjunctions:
7//
8//      minimize    2x0 + x1 + 3x2 + x3
9//      subject to   x0 + x1 + x2 + x3 >= -10
10//                  (x0-2x1<=-1 and x2=x3=0) or (x2-3x3<=-2 and x1=x2=0)
11//                  x0=2.5 or x1=2.5 or x2=2.5 or x3=2.5
12//
13
14extern crate mosek;
15
16use mosek::{Task,Boundkey,Objsense,Streamtype,Soltype};
17
18// Since the value of infinity is ignored, we define it solely
19// for symbolic purposes
20const INF : f64 = 0.0;
21
22
23fn main() -> Result<(),String> {
24    // Create a task object
25    let mut task = match Task::new() {
26        Some(e) => e,
27        None => return Err("Failed to create task".to_string()),
28        }.with_callbacks();
29
30    task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
31
32    // Append free variables
33    let numvar : i32 = 4;
34    task.append_vars(numvar)?;
35    let x : Vec<i32> = (0..numvar).collect();
36    task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
37
38    // The linear part: the linear constraint
39    task.append_cons(1)?;
40    task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
41    task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
42
43    // The linear part: objective
44    task.put_obj_sense(Objsense::MINIMIZE)?;
45    task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
46
47    // Fill in the affine expression storage F, g
48    let numafe : i64 = 10;
49    task.append_afes(numafe)?;
50
51    let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
52    let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
53    let fval             = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
54    let g                = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
55
56    task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
57    task.put_afe_g_slice(0, numafe, g)?;
58
59    // Create domains
60    let zero1   = task.append_rzero_domain(1)?;
61    let zero2   = task.append_rzero_domain(2)?;
62    let rminus1 = task.append_rminus_domain(1)?;
63
64    // Append disjunctive constraints
65    let numdjc : i64 = 2;
66    task.append_djcs(numdjc)?;
67
68    // First disjunctive constraint
69    task.put_djc(0,                                        // DJC index
70                 &[rminus1, zero2, rminus1, zero2],        // Domains     (domidxlist)
71                 &[0, 4, 5, 1, 2, 3],                      // AFE indices (afeidxlist)
72                 &[0.0,0.0,0.0,0.0,0.0,0.0],               // Unused
73                 &[2, 2])?;                                // Term sizes  (termsizelist)
74
75    // Second disjunctive constraint
76    task.put_djc(1,                                        // DJC index
77                 &[zero1, zero1, zero1, zero1],            // Domains     (domidxlist)
78                 &[6, 7, 8, 9],                            // AFE indices (afeidxlist)
79                 &[0.0,0.0,0.0,0.0],                       // Unused
80                 &[1, 1, 1, 1])?;                          // Term sizes  (termidxlist)
81
82    // Useful for debugging
83    task.write_data("djc1.ptf")?;                         // Write file in human-readable format
84
85    // Solve the problem
86    let _ = task.optimize()?;
87
88    // Print a summary containing information
89    // about the solution for debugging purposes
90    task.solution_summary(Streamtype::MSG)?;
91
92    // Get status information about the solution
93    let sta = task.get_sol_sta(Soltype::ITG)?;
94
95    let mut xx = vec![0.0; numvar as usize];
96    task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
97
98
99    println!("Optimal solution: ");
100    for (i,&xi) in xx.iter().enumerate() {
101        println!("x[{}]={}",i,xi);
102    }
103
104    Ok(())
105}
106
107#[cfg(test)]
108mod tests {
109    #[test]
110    fn test() {
111        super::main().unwrap();
112    }
113}