Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GA_Minimizer.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 // :noTabs=false:tabSize=4:indentSize=4:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file core/optimization/GA_Minimizer.cc
12 /// @brief Minimizer based on Genetic Algorithm
13 /// @author Sergey Lyskov
14 
15 
17 
18 #include <numeric/random/random.hh>
19 #include <basic/Tracer.hh>
20 #include <core/types.hh>
21 
22 #include <algorithm>
23 
25 #include <utility/vector1.hh>
26 
27 
28 namespace core {
29 namespace optimization {
30 
31 static basic::Tracer TR("core.optimization.GA_Minimizer");
32 
33 static numeric::random::RandomGenerator RG(740); /// <- Magic number, do not change it!
34 
35 using core::Size;
36 
37 /// Return true with given probability
38 static bool yes_no_random(Real probability)
39 {
40  if( RG.uniform() < probability ) return true;
41  else return false;
42 }
43 
44 
45 // starting position, and solution is returned here
46 Real GA_Minimizer::run( Multivec & v, int max_time)
47 {
48  allowed_time_ = max_time;
49 
50  best_.v.resize( v.size() );
51  for(Size i=1; i<=v.size(); i++) {
52  best_.v[i] = v[i];
53  }
54  best_.r = func_(best_.v);
55 
56  TR << "Initial score (time=0): " << best_.r << /*" V=" << best_.v << */ std::endl;
57 
58 
59  int ctime = allowed_time_;
60 
61  TR << "Randomizing..." << std::endl;
62  EItem r = randomize(best_, ctime);
63  for(Size i=1; i<=v.size(); i++) {
64  v[i] = r.v[i];
65  }
66 
67  return func_(v);
68 }
69 
70 EItem GA_Minimizer::randomize(const EItem& sit, int &time)
71 {
72  std::vector<EItem> pop;
73  for(int i=0; i<20; i++) {
74  EItem t = sit; t.tag = 'r';
75  for(Size j=1; j<=t.v.size(); j++)
76  // Original: Random::DoubleUniformRandom()*2. - 1.;
77  t.v[j] = sit.v[j] + RG.uniform()*2. - 1.;
78 
79  t.r = func_(t.v);
80 
81  pop.push_back(t);
82  time--;
83  }
84  EItem t = sit; t.tag = 'O'; t.r = func_(t.v);
85  pop.push_back(t);
86 
87  best_ = pop[0];
88 
89  loop(pop, time); return best_;
90 }
91 
92 EItem GA_Minimizer::loop(std::vector<EItem> & pop, int &time)
93 {
94  EItem shift; for(Size i=1; i<=best_.v.size(); i++) shift.v.push_back(0);
95  int mres = 10;
96 
97  for(;time>0;) {
98  if( mres < -5 ) {
99  TR << "Shifting...(" << allowed_time_-time<< ") -> " << pop[0].r << std::endl;
100  std::vector<EItem> npop;
101 
102  if(add_original_) {
103  EItem t = pop[0]; fill(t.v.begin(), t.v.end(), 1.e-10);
104  npop.push_back( t );
105  }
106 
107  for(int i=0; i<10; i++) {
108  EItem t = pop[0]; t.tag = 'r';
109  for(Size j=1; j<=t.v.size(); j++)
110  t.v[j] = RG.uniform()*2. - 1.; //Random::DoubleUniformRandom()*2. - 1.;
111 
112  t.r = func_(t.v);
113 
114  npop.push_back(t);
115  }
116 
117  for(Size i=1; i<=shift.v.size(); i++) shift.v[i] += pop[0].v[i];
118 
119  mres = 7;
120 
121  pop = npop;
122  time -= pop.size();
123  }
124  else {
125  step(pop, time, mres, shift);
126  if( pop[0].r < min_error_ ) {
127  TR << " Best < MaxError... - stoping, time=" << time << "." << std::endl;
128  for(Size i=1; i<=shift.v.size(); i++) pop[0].v[i] += shift.v[i];
129  //StopTime = time;
130  return pop[0];
131  }
132  }
133  }
134 
135  //StopTime = time;
136  for(Size i=1; i<=shift.v.size(); i++) pop[0].v[i] += shift.v[i];
137  return pop[0];
138 }
139 
140 void GA_Minimizer::step(std::vector<EItem> &pop, int &c_time, int &mres, EItem &shift)
141 {
142  int i_ev = pop.size(); double best = pop[0].r;
143 
144  for(int i=pop.size()-1; i>=0; i--) { // for each item in pop do: mutation/crossover/...
145  // Plain Mutation
146  if( yes_no_random(1.) ) {
147  c_time--;
148  int last_i = pop.size();
149  pop.push_back(pop[i]);
150  mutate(pop[last_i]);
151  }
152 
153  // Cross over mutation
154  if( yes_no_random(1.) ) {
155  c_time--;
156  int last_i = pop.size();
157  pop.push_back(pop[i]);
158 
159  int i2 = RG.random_range(0, i_ev-1); //Random::RangeRandom(i_ev);
160  if( i2 != i ) cross_over(pop[last_i], pop[i], pop[i2]);
161  }
162  }
163 
164  EItem tmp; // evaluate new items
165  tmp.v.resize( shift.v.size() );
166  for(Size i=i_ev; i<pop.size(); i++) {
167  for(Size j=1; j<=pop[i].v.size(); j++)
168  tmp.v[j] = pop[i].v[j] + shift.v[j];
169 
170  pop[i].r = func_(tmp.v);
171  }
172 
173  // sort pop by perfomarce, and take best 10 items.
174  sort(pop.begin(), pop.end(), EItem::sort_R_function);
175  if( pop.size() > 10 ) pop.erase(pop.begin()+10, pop.end());
176 
177  // see if best value improved
178  if( best > pop[0].r + minimize_tolerance_ ) {
179  TR << pop[0].tag;
180  mres++;
181  }
182  else
183  mres--;
184 
185  if( best_.r > pop[0].r ) { // global best value;
186  best_ = pop[0];
187  for(Size j=1; j<=best_.v.size(); j++)
188  best_.v[j] = best_.v[j] + shift.v[j];
189 
190  TR << " Time=" << allowed_time_ - c_time << " Score=" << best_.r /*<< " V=" << best_.v */<< std::endl;
191  }
192 }
193 
194 
195 
197 {
198  for(Size i=1; i<=V.v.size(); i++) {
200  double r = RG.gaussian() + .7; //Random::NormalRandom(1, .7);
201  V.v[i] *= r * 1.0;
202  //V.v[i] += RG.gaussian();
203  }
204  }
205  V.tag='m';
206 }
207 
209 {
210  for(Size i=1; i<=V.v.size(); i++) {
211  if( yes_no_random(.5) ) V.v[i] = A.v[i];
212  else V.v[i] = B.v[i];
213  }
214  mutate(V) ;
215  V.tag='c';
216 }
217 
218 } // namespace optimization
219 } // namespace core