PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // CartesianProductOracle.cc 00004 // 00005 // Copyright (C) 2003-2004 ApSTAT Technologies Inc. 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: CartesianProductOracle.cc 8897 2008-04-25 18:18:23Z nouiz $ 00037 ******************************************************* */ 00038 00040 #include "CartesianProductOracle.h" 00041 00042 namespace PLearn { 00043 using namespace std; 00044 00045 CartesianProductOracle::CartesianProductOracle() 00046 :OptionsOracle(), last_combination(false) 00047 /* ### Initialise all fields to their default value */ 00048 { 00049 } 00050 00051 PLEARN_IMPLEMENT_OBJECT( 00052 CartesianProductOracle, 00053 "This OptionsOracle generates all combinations of values for a set of options", 00054 "This 'oracle' traverses a fixed list of option values, obtained from a set" 00055 "of values associated with each option of interest. That list is the cartesian" 00056 "product of those sets, i.e. it is the list of all combinations of values." 00057 "The user specifies the names of each option, and for each of them, a list" 00058 "of the values that should be tried." 00059 ); 00060 00061 void CartesianProductOracle::declareOptions(OptionList& ol) 00062 { 00063 declareOption(ol, "option_names", &CartesianProductOracle::option_names, OptionBase::buildoption, 00064 "name of each of the options to optimize"); 00065 00066 declareOption(ol, "option_values", &CartesianProductOracle::option_values, OptionBase::buildoption, 00067 "A list of lists of options: the top list must have as many elements as there are" 00068 "options in the option_names field. Each sub-list contains the values to be tried" 00069 "for the corresponding option." 00070 ); 00071 declareOption(ol, "option_values_indices", 00072 &CartesianProductOracle::option_values_indices, 00073 OptionBase::learntoption, 00074 "The indices of each option value."); 00075 00076 // Now call the parent class' declareOptions 00077 inherited::declareOptions(ol); 00078 } 00079 00080 TVec<string> CartesianProductOracle::getOptionNames() const 00081 { 00082 return option_names; 00083 } 00084 00085 TVec<string> CartesianProductOracle::generateNextTrial(const TVec<string>& older_trial, 00086 real obtained_objective) 00087 { 00088 if (last_combination) 00089 return TVec<string>(); 00090 else 00091 { 00092 int n=option_names.length(); 00093 TVec<string> values(n); 00094 // copy current combination 00095 for (int i=0;i<n;i++) 00096 values[i]=option_values[i][option_values_indices[i]]; 00097 // increment indices to next combination, in lexicographical order 00098 last_combination=true; 00099 for (int i=0;i<n;i++) 00100 { 00101 option_values_indices[i]++; 00102 if (option_values_indices[i]<option_values[i].length()) { last_combination=false; break; } 00103 else option_values_indices[i]=0; 00104 } 00105 return values; 00106 } 00107 } 00108 00109 void CartesianProductOracle::forget() 00110 { 00111 option_values_indices.clear(); 00112 last_combination=false; 00113 } 00114 00115 void CartesianProductOracle::build_() 00116 { 00117 // Ensure consistency between option_names and option_values 00118 if (option_names.size() != option_values.size()) 00119 PLERROR("CartesianProductOracle::build_: the 'option_names' and 'option_values'\n" 00120 "fields don't have the same length; len(option_names)=%d / len(option_values)=%d", 00121 option_names.size(), option_values.size()); 00122 if (option_names.size() == 0 || option_values.size() == 0) 00123 PLWARNING("CartesianProductOracle::build_: either 'option_names' or 'option_values'\n" 00124 "has size zero; is this what you want?"); 00125 00126 // Try to detect zero-length subarrays of options 00127 for (int i=0, n=option_values.size() ; i<n ; ++i) 00128 if (option_values[i].size() == 0) 00129 PLWARNING("CartesianProductOracle::build_: zero option values were specified\n" 00130 "for option '%s'", option_names[i].c_str()); 00131 00132 option_values_indices.resize(option_names.length()); 00133 forget(); 00134 } 00135 00136 // ### Nothing to add here, simply calls build_ 00137 void CartesianProductOracle::build() 00138 { 00139 inherited::build(); 00140 build_(); 00141 } 00142 00143 00144 void CartesianProductOracle::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00145 { 00146 inherited::makeDeepCopyFromShallowCopy(copies); 00147 deepCopyField(option_values_indices, copies); 00148 deepCopyField(option_values, copies); 00149 deepCopyField(option_names, copies); 00150 } 00151 00152 } // end of namespace PLearn 00153 00154 00155 /* 00156 Local Variables: 00157 mode:c++ 00158 c-basic-offset:4 00159 c-file-style:"stroustrup" 00160 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00161 indent-tabs-mode:nil 00162 fill-column:79 00163 End: 00164 */ 00165 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :