1+ use std:: fmt;
2+ use std:: usize;
3+ use std:: iter;
4+
15use mtl:: array:: { Array , ArrayType , concatenate} ;
26
37
48/// Simplex solver
59pub struct Simplex {
610 a : Array < f64 > ,
711 m : usize ,
8- n : usize
12+ n : usize ,
13+ basis : Vec < usize >
14+ }
15+
16+ impl fmt:: Display for Simplex {
17+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
18+ let ( m, n) = ( self . m , self . n ) ;
19+ try!( writeln ! ( f, "M = {}" , m) ) ;
20+ try!( writeln ! ( f, "N = {}" , n) ) ;
21+ for i in 0 .. m+1 {
22+ for j in 0 .. m+n+1 {
23+ try!( write ! ( f, "{:7.2}" , self . a[ [ i, j] ] ) ) ;
24+ }
25+ try!( writeln ! ( f, "" ) ) ;
26+ }
27+
28+ try!( writeln ! ( f, "value = {}" , self . value( ) ) ) ;
29+ for i in 0 .. m {
30+ if self . basis [ i] < n {
31+ try!( writeln ! ( f, "x_{} = {}" , self . basis[ i] , self . a[ [ i, m+n] ] ) ) ;
32+ }
33+ }
34+
35+ Ok ( ( ) )
36+ }
937}
1038
1139
1240impl Simplex {
41+ #[ allow( non_snake_case) ]
1342 pub fn new ( A : Vec < Vec < f64 > > , b : Vec < f64 > , c : Vec < f64 > ) -> Simplex {
1443 let m = b. len ( ) ; // M constrains
1544 let n = c. len ( ) ; // N variables
@@ -24,15 +53,111 @@ impl Simplex {
2453 let c = Array :: from_vec ( c) . reshape ( [ 1 , n] ) ;
2554
2655 let ashape = A . shape ( ) ;
27- let mut M = concatenate ( [ concatenate ( [ A , Array :: eye ( ashape[ 0 ] ) , b] , 1 ) ,
28- concatenate ( [ c, Array :: zeros ( [ 1 , ashape[ 0 ] + 1 ] ) ] , 1 ) ] , 0 ) ;
56+ let M = concatenate ( [ concatenate ( [ A , Array :: eye ( ashape[ 0 ] ) , b] , 1 ) ,
57+ concatenate ( [ c, Array :: zeros ( [ 1 , ashape[ 0 ] + 1 ] ) ] , 1 ) ] , 0 ) ;
2958
30- Simplex {
59+ let mut ret = Simplex {
3160 a : M ,
3261 m : m,
33- n : n
62+ n : n,
63+ basis : ( 0 ..m) . map ( |i| n+i) . collect ( )
64+ } ;
65+ ret. solve ( ) ;
66+ ret
67+ }
68+
69+ /// return optimal objective value
70+ pub fn value ( & self ) -> f64 {
71+ -self . a [ [ self . m , self . m +self . n ] ]
72+ }
73+
74+ /// primal solution vector
75+ pub fn primal ( & self ) -> Vec < f64 > {
76+ let ( m, n) = ( self . m , self . n ) ;
77+ let mut x = iter:: repeat ( 0.0 ) . take ( n) . collect :: < Vec < f64 > > ( ) ;
78+ for i in 0 .. m {
79+ if self . basis [ i] < n {
80+ x[ self . basis [ i] ] = self . a [ [ i, m+n] ] ;
81+ }
82+ }
83+ x
84+ }
85+
86+ pub fn dual ( & self ) -> Vec < f64 > {
87+ let ( m, n) = ( self . m , self . n ) ;
88+ let mut y = iter:: repeat ( 0.0 ) . take ( m) . collect :: < Vec < f64 > > ( ) ;
89+ for i in 0 .. m {
90+ y[ i] = -self . a [ [ m, n+1 ] ] ;
3491 }
92+ y
3593 }
94+
95+ /// Bland's rule
96+ fn bland ( & self ) -> usize {
97+ let ( m, n) = ( self . m , self . n ) ;
98+ for j in 0 .. m+n {
99+ if self . a [ [ m, j] ] > 0.0 {
100+ return j;
101+ }
102+ }
103+ usize:: MAX // optimal :)
104+ }
105+
106+ fn min_ratio_rule ( & self , q : usize ) -> usize {
107+ // leaving row
108+ let mut p = usize:: MAX ;
109+ let ( m, n) = ( self . m , self . n ) ;
110+ for i in 0 .. self . m {
111+ // skip negative
112+ if self . a [ [ i, q] ] <= 0.0 {
113+ continue ;
114+ } else if p == usize:: MAX {
115+ p = i
116+ } else if self . a [ [ i, m+n] ] / self . a [ [ i, q] ] < self . a [ [ p, m+n] ] / self . a [ [ p, q] ] {
117+ p = i
118+ }
119+ }
120+ p
121+ }
122+
123+ pub fn pivot ( & mut self , p : usize , q : usize ) {
124+ let ( m, n) = ( self . m , self . n ) ;
125+ for i in 0 .. m+1 {
126+ for j in 0 .. m+n+1 {
127+ if i != p && j != q {
128+ self . a [ [ i, j] ] -= self . a [ [ p, j] ] * self . a [ [ i, q] ] / self . a [ [ p, q] ] ;
129+ }
130+ }
131+ }
132+
133+ // zero out column q
134+ for i in 0 .. m+1 {
135+ if i != p { self . a [ [ i, q] ] = 0.0 ; }
136+ }
137+
138+ for j in 0 .. m+n+1 {
139+ if j != q { self . a [ [ p, j] ] /= self . a [ [ p, q] ] } ;
140+ }
141+
142+ self . a [ [ p, q] ] = 1.0 ;
143+ }
144+
145+ pub fn solve ( & mut self ) {
146+ loop {
147+ let q = self . bland ( ) ;
148+ if q == usize:: MAX { break }
149+
150+ let p = self . min_ratio_rule ( q) ;
151+ if p == usize:: MAX {
152+ panic ! ( "wrong in input question." )
153+ }
154+
155+ self . pivot ( p, q) ;
156+
157+ self . basis [ p] = q;
158+ }
159+ }
160+
36161}
37162
38163
@@ -41,9 +166,9 @@ fn test_simplex_solve() {
41166 /*
42167 maximize: 13 * A + 23 * B
43168 sbject to:
44- 5 * A + 15 * B <= 480
45- 4 * A + 4 * B <= 160
46- 35 * A + 20 * B <= 1190
169+ 5 * A + 15 * B <= 480
170+ 4 * A + 4 * B <= 160
171+ 35 * A + 20 * B <= 1190
47172 */
48173 let simplex = Simplex :: new (
49174 vec ! [
@@ -53,5 +178,8 @@ fn test_simplex_solve() {
53178 ] ,
54179 vec ! [ 480.0 , 160.0 , 1190.0 ] ,
55180 vec ! [ 13.0 , 23.0 ]
56- ) ;
181+ ) ;
182+ println ! ( "solve => \n {}" , simplex) ;
183+ assert_eq ! ( simplex. value( ) , 800.0 ) ;
184+
57185}
0 commit comments