source: branches/MetisMQI/src/main/java/weka/attributeSelection/TabuSearch.java @ 29

Last change on this file since 29 was 29, checked in by gnappo, 14 years ago

Taggata versione per la demo e aggiunto branch.

File size: 26.6 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 *    TabuSearch.java
19 *    Copyright (C) 2009 Adrian Pino
20 *    Copyright (C) 2009 University of Waikato, Hamilton, NZ
21 *
22 */
23
24package weka.attributeSelection;
25
26
27import java.io.Serializable;
28import java.util.ArrayList;
29import java.util.BitSet;
30import java.util.Enumeration;
31import java.util.List;
32import java.util.Random;
33import java.util.Vector;
34
35import weka.core.Instances;
36import weka.core.Option;
37import weka.core.OptionHandler;
38import weka.core.RevisionUtils;
39import weka.core.TechnicalInformation;
40import weka.core.TechnicalInformationHandler;
41import weka.core.Utils;
42import weka.core.TechnicalInformation.Field;
43import weka.core.TechnicalInformation.Type;
44
45
46/**
47 * Class for performing the TabuSearch method. <p>
48 *
49 <!-- globalinfo-start -->
50 * Tabu Search :<br/>
51 * <br/>
52 * Performs a search  through the space of attribute subsets. Evading local maximums by accepting bad and diverse solutions and make further search in the best soluions. Stops when there's not more improvement in n iterations<br/>
53 * ;For more information see:<br/>
54 * <br/>
55 * Abdel-Rahman Hedar, Jue Wangy,, Masao Fukushima (2006). Tabu Search for Attribute Reduction in Rough Set Theory. .
56 * <p/>
57 <!-- globalinfo-end -->
58 *
59 <!-- options-start -->
60 * Valid options are: <p/>
61 *
62 * <pre> -Z &lt;numInitialSolution&gt;
63 *  Specify the number of attributes
64 *  in the initial Solution..</pre>
65 *
66 * <pre> -P &lt;diversificationProb&gt;
67 *  Specify the diversification probabilities,
68 *  if this value is near to 0 then the best attributes
69 *   will have more probabilities of keeping in the new diverse solution</pre>
70 *
71 * <pre> -S &lt;seed&gt;
72 *  Set the random number seed.
73 *  (default = 1)</pre>
74 *
75 * <pre> -N &lt;number of neighbors&gt;
76 *  Set the number of neighbors to generate.</pre>
77 *
78 <!-- options-end -->
79 *
80 <!-- technical-bibtex-start -->
81 * BibTeX:
82 * <pre>
83 * &#64;book{Abdel-RahmanHedar2006,
84 *    author = {Abdel-Rahman Hedar, Jue Wangy, and Masao Fukushima},
85 *    month = {July},
86 *    title = {Tabu Search for Attribute Reduction in Rough Set Theory},
87 *    year = {2006},
88 *    language = {English}
89 * }
90 * </pre>
91 * <p/>
92 <!-- technical-bibtex-end -->
93 *
94 * from the Book: Tabu Search for Attribute Reduction in Rough Set Theory, Abdel-Rahman Hedar, Jue Wangy, and Masao Fukushima.
95 *
96 * @author Adrian Pino (apinoa@facinf.uho.edu.cu)
97 * @version $Revision: 4976 $
98 *
99 */
100
101public class TabuSearch extends ASSearch
102  implements OptionHandler, TechnicalInformationHandler{
103
104  /** for serialization */
105  static final long serialVersionUID = -8812132617585120414L;
106
107  /** number of attributes in the data */
108  private int m_numAttribs;
109
110  /** holds the class index */
111  private int m_classIndex;
112
113  /** random number generation */
114  private Random m_random;
115
116  /** seed for random number generation */
117  private int m_seed;
118
119  /** probabilities of diversification */
120  private double m_diversificationProb;
121
122  /** number of iterations for getting the best subset*/
123  private int m_numIterations;
124
125  /** total number of subsets evaluated during a search */
126  private int m_totalEvals;
127
128  /** holds the best Subset found */
129  protected Subset m_Sbest;
130
131  /** holds the number of neighborhood to generate from a Subset*/
132  private int m_numNeighborhood;
133
134  /** time for procesing the search method */
135  private long m_processinTime;
136
137  /** holds the solution size*/
138  private int m_initialSize;
139
140  /**Subset holding the initial solution*/
141  private Subset m_initialSolution;
142
143  /**attribute ranking*/
144  private List<Subset> m_rankedAttribs;
145
146  /**tabu List*/
147  private List<BitSet> m_vectorTabu;
148
149  /**Evaluator used to know the significance of a subset (for guiding the search)*/
150  private SubsetEvaluator ASEvaluator =null;
151
152
153  /**
154   * Searches the attribute subset space using Tabu Search.
155   *
156   * @param ASEvaluator the attribute evaluator to guide the search
157   * @param data the training instances.
158   * @return an array of selected attribute indexes
159   * @exception Exception if the search can't be completed
160   */
161  public int[] search(ASEvaluation ASEval, Instances data)
162  throws Exception{
163    m_totalEvals = 0;
164    m_processinTime =System.currentTimeMillis ();
165
166    m_numAttribs =data.numAttributes ();
167    m_classIndex =data.classIndex ();
168
169    ASEvaluator =(SubsetEvaluator)ASEval;
170
171    m_random = new Random(m_seed);
172
173    int numN = m_numNeighborhood;
174    numN = (m_numNeighborhood <= 0) ? 3*m_numAttribs/4 : m_numNeighborhood;
175
176
177    if(m_numAttribs <= 14) m_numIterations = m_numAttribs;
178    else if(m_numAttribs > 14) m_numIterations = m_numAttribs/3;
179
180    m_rankedAttribs = RankEachAttribute ();
181
182    /** generating an initial Solution based in SFS*/
183    if(m_initialSize < 0)m_initialSize = m_numAttribs;
184    m_initialSolution = GenerateInitialSolution(new Subset(new BitSet(m_numAttribs), 0), m_initialSize);
185
186
187    /**Initializing Vector Tabu*/
188    m_vectorTabu =new ArrayList<BitSet>();
189    BitSet tabu1 = new BitSet(m_numAttribs);
190    BitSet tabu2 = new BitSet(m_numAttribs);
191
192    tabu2.set (0,m_numAttribs-1);
193    if (m_classIndex >= 0) tabu2.set (m_classIndex, false);
194
195    m_vectorTabu.add (tabu1);
196    m_vectorTabu.add (tabu2);
197
198
199    /**For Controlling the Search*/
200    int iterationCounter = 0;
201    int numGenerationNeighborForDiv = (m_numAttribs/m_numIterations >= 2) ? m_numAttribs/m_numIterations : 3;
202    int numTotalWImp = 0;
203    int numTotalWImpForFinishing = m_numIterations/2;
204
205    BitSet S = m_initialSolution.subset;
206    m_Sbest = m_initialSolution;
207
208    List<Subset> RedSet = new ArrayList<Subset>();
209    RedSet.add (m_Sbest.clone ());
210
211    while(iterationCounter < m_numIterations && numTotalWImp < numTotalWImpForFinishing){
212      iterationCounter ++;
213
214      List<Subset> neighborhood = null;
215      int counterGenerationNeighborWImp = 0;
216      while (counterGenerationNeighborWImp < numGenerationNeighborForDiv) {
217
218        neighborhood = generateNeighborhood(S, numN);
219        if(neighborhood != null){
220          S =((Subset)neighborhood.get (0)).subset;
221          double Smerit = ASEvaluator.evaluateSubset (S);
222          m_totalEvals ++;
223
224          RedSet.add (new Subset((BitSet)S.clone (), Smerit));
225
226          m_vectorTabu.add ((BitSet)S.clone ());
227
228
229          if(Smerit > m_Sbest.merit){
230            m_Sbest = new Subset((BitSet)S.clone (), Smerit);
231            Subset aux = shake ();
232            if(aux != null)
233              m_Sbest = aux.clone ();
234          }
235          else{
236            counterGenerationNeighborWImp ++;
237            numTotalWImp ++;
238          }
239        }
240        else break;
241      }
242      S = diversify (neighborhood);
243    }
244
245    Subset elite = eliteReducts(RedSet, RedSet.size ());
246
247    if(elite.merit >= m_Sbest.merit)
248      return attributeList (elite.subset);
249
250    m_processinTime = System.currentTimeMillis () - m_processinTime;
251
252    return attributeList (m_Sbest.subset);
253  }
254
255  /**
256   * Generates a list of neighborhood given a Solution, flipping randomly the state of many attributes.
257   *
258   * @param S the Solution from which we are going to find the neighborhood
259   * @param numNeighborhood number of attributes for flipping
260   * @return a Subset list containing the neighborhood
261   * @exception Exception if the evaluation can not be complete
262   */
263  private List<Subset> generateNeighborhood(BitSet S, int numNeighborhood)
264  throws Exception{
265    int counter = 0;
266    List<Subset> neighborhood = new ArrayList<Subset>();
267
268    int numAttribs = (m_classIndex == -1) ? m_numAttribs  : m_numAttribs - 1;
269
270    if(numNeighborhood >= numAttribs){
271      for (int i = 0; i < m_numAttribs; i++) {
272        if(i == m_classIndex)continue;
273
274        BitSet aux = (BitSet)S.clone ();
275        aux.flip (i);
276
277        if(!m_vectorTabu.contains (aux)){
278          neighborhood.add (new Subset((BitSet)aux.clone (), ASEvaluator.evaluateSubset (aux)));
279          m_totalEvals ++;
280        }
281      }
282    }
283    else{
284      while (counter < numNeighborhood) {
285        BitSet aux = (BitSet)S.clone ();
286
287        int randomNumber = m_random.nextInt (m_numAttribs);
288        if(randomNumber == m_classIndex)
289          continue;
290
291        aux.flip (randomNumber);
292        if(!m_vectorTabu.contains (aux)){
293          neighborhood.add (new Subset((BitSet)aux.clone (), ASEvaluator.evaluateSubset (aux)));
294          m_totalEvals ++;
295          counter ++;
296        }
297      }
298    }
299
300    if(neighborhood.isEmpty ())
301      return null;
302
303    return bubbleSubsetSort (neighborhood);
304  }
305
306  /**
307   * Generate a diverse Bitset given a List of Subset
308   *
309   * @param neighborhood the list from which are going to be generate the diverse solution
310   * @return a diverse Bitset
311   */
312  public BitSet diversify(List<Subset> neighborhood){
313
314    if(neighborhood == null)
315      return m_Sbest.subset;
316
317    BitSet result = new BitSet(m_numAttribs);
318
319    double [] counts = new double[m_numAttribs];
320    int numNeighborhood = neighborhood.size ();
321
322
323
324    for (int i = 0; i < m_numAttribs; i++) {
325      if(i == m_classIndex)
326        continue;
327
328      int counter = 0;
329
330      for (int j = 0; j < numNeighborhood; j++) {
331        if(((Subset)neighborhood.get (j)).subset.get (i))
332          counter ++;
333      }
334      counts [i] = counter/(double)numNeighborhood;
335    }
336
337    for (int i = 0; i < m_numAttribs; i++) {
338      double randomNumber = m_random.nextDouble ();
339      double ocurrenceAndRank = counts [i] * (m_diversificationProb) + doubleRank (i) * (1 - m_diversificationProb);
340
341      if(randomNumber > ocurrenceAndRank)
342        result.set (i);
343    }
344
345    return result;
346  }
347
348
349  /**
350   * Try to improve the best Solution obtained till now in the way of Sequential Backward Selection(SBS)
351   *
352   * @param ASEvaluator the attribute evaluator to guide the search
353   * @return null if there is not improvement otherwise a Subset better than the obtained till now.
354   */
355  private Subset shake()
356  throws Exception{
357    Subset bestCopy = m_Sbest.clone ();
358    boolean anyImprovement = false;
359
360    for (int i = m_rankedAttribs.size ()-1; i >= 0; i --) {
361      Subset ranking = m_rankedAttribs.get (i);
362      int attributeIndex = ranking.subset.nextSetBit (0);
363
364      BitSet aux = (BitSet)bestCopy.subset.clone ();
365      if(aux.get (attributeIndex)){
366        aux.set (attributeIndex, false);
367
368        if(m_vectorTabu.contains (aux))
369          continue;
370
371        double tempMerit = ASEvaluator.evaluateSubset (aux);
372        m_totalEvals ++;
373
374        if(tempMerit >= bestCopy.merit){
375          bestCopy = new Subset((BitSet)aux.clone (), tempMerit);
376          anyImprovement = true;
377        }
378      }
379    }
380    if(anyImprovement)
381      return bestCopy;
382    return null;
383  }
384
385  /**
386   * Find a better solution by intersecting and SFS of the best elite Reducts found till that moment
387   *
388   * @param RedSet the Subset List of the Elite Reducted found till that moment
389   * @param numSubset number of elites to intersect
390   * @return a the resulting Subset
391   * @exception Exception if any evaluation can't be completed
392   */
393  public Subset eliteReducts(List<Subset>RedSet, int numSubset)
394  throws Exception{
395
396    if(numSubset <= 0)
397      return null;
398
399    List<Subset>orderedRedSet = bubbleSubsetSort (RedSet);
400    int numAttribsOfBest = m_Sbest.cardinality ();
401
402    BitSet result =new BitSet(m_numAttribs);
403    result.set (0,m_numAttribs-1,true);
404
405    BitSet aux;
406
407    for (int i = 0; i < numSubset; i++) {
408      aux = ((Subset)orderedRedSet.get (i)).subset;
409      result.and (aux);
410    }
411
412    int diff = numAttribsOfBest - result.cardinality ();
413
414    Subset resultSet = GenerateInitialSolution (new Subset(result,ASEvaluator.evaluateSubset (result)),result.cardinality () + diff-1);
415    m_totalEvals ++;
416
417    if(resultSet == null)
418      return null;
419
420    return resultSet;
421  }
422
423
424  /**
425   * Generate an initial solution based in a Sequential Forward Selection (SFS)
426   *
427   * @param size number of posible attributes in the initial Solution
428   * @return an initial Subset containing the initial Solution
429   * @exception Exception if the evaluation can not be completed
430   */
431  public Subset GenerateInitialSolution(Subset initial, int size)
432  throws Exception{
433
434    List<Subset> rankedAttribsCopy = new ArrayList<Subset>();
435
436    for (int i = 0; i<m_rankedAttribs.size (); i++)
437      rankedAttribsCopy.add (m_rankedAttribs.get (i));
438
439    Subset solution = initial.clone ();
440
441    while(solution.cardinality () < size) {
442
443      Subset tempSubset =new Subset();
444      double bestMerit =solution.merit;
445      int bestIndex =-1;
446
447      for (int i = 0; i<rankedAttribsCopy.size (); i++) {
448        Subset candidate = ((Subset)rankedAttribsCopy.get (i)).clone ();
449        if(solution.subset.get (candidate.subset.nextSetBit (0)))
450          continue;
451
452        tempSubset =joinSubsets(solution, rankedAttribsCopy.get (i));
453
454        if(tempSubset.merit > bestMerit){
455          bestMerit = tempSubset.merit;
456          bestIndex = i;
457        }
458      }
459
460      if(bestIndex == -1) break;
461
462      solution =joinSubsets (solution, rankedAttribsCopy.get (bestIndex));
463      rankedAttribsCopy.remove (bestIndex);
464    }
465
466    return solution;
467  }
468
469
470
471  //--------Auxiliar methods****
472
473  /**
474   * get the importance of an individual attribute according to his position in m_rankedAttribs List.
475   *
476   * @param idAttrib the index attribute of the attribute that we want to get the doubleRank
477   * @return a double giving the result. If is a good attribute the result will be a number near of 0(inclusive),
478   *                                     If is a bad one the result will be near of 1(exclusive).
479   */
480  private double doubleRank(int idAttrib){
481    int rankSize = m_rankedAttribs.size ();
482    int rankAttribute = -1;
483
484    if(idAttrib == m_classIndex) return -1;
485
486    for (int i = 0; i < rankSize; i++) {
487      if(((Subset)m_rankedAttribs.get (i)).subset.nextSetBit (0) == idAttrib){
488        rankAttribute = i;
489        break;
490      }
491    }
492
493    return rankAttribute/(double)rankSize;
494  }
495
496  /**
497   * Rank all the attributes individually acording to their merits
498   *
499   * @return an ordered List  of Subsets with just one attribute
500   * @exception Exception if the evaluation can not be completed
501   */
502  private List<Subset> RankEachAttribute()
503  throws Exception{
504
505    List<Subset> result =new ArrayList<Subset>();
506
507    for (int i = 0; i<m_numAttribs; i++) {
508      if(i==m_classIndex)continue;
509
510      BitSet an_Attribute =new BitSet(m_numAttribs);
511      an_Attribute.set (i);
512
513      double merit =ASEvaluator.evaluateSubset (an_Attribute);
514      m_totalEvals++;
515
516      result.add (new Subset(an_Attribute, merit));
517    }
518
519    return bubbleSubsetSort(result);
520  }
521
522  /**
523   * Sort a List of subsets according to their merits
524   *
525   * @param subsetList the subsetList to be ordered
526   * @return a List with ordered subsets
527   */
528  public List<Subset> bubbleSubsetSort(List<Subset> subsetList){
529    List<Subset> result =new ArrayList<Subset>();
530
531    for (int i = 0; i<subsetList.size ()-1; i++) {
532      Subset subset1 =subsetList.get (i);
533      double merit1 =subset1.merit;
534
535      for (int j = i+1; j<subsetList.size (); j++) {
536        Subset subset2 =subsetList.get (j);
537        double merit2 =subset2.merit;
538
539        if(merit2 > merit1){
540          Subset temp =subset1;
541
542          subsetList.set (i,subset2);
543          subsetList.set (j,temp);
544
545          subset1 =subset2;
546          merit1 =subset1.merit;
547        }
548      }
549    }
550    return subsetList;
551  }
552
553
554
555  /**
556   * Join two subsets
557   *
558   * @param subset1 one of the subsets
559   * @param subset2 the other subset
560   * @return a new Subset that is te result of the Join
561   * @exception Exception if the evaluation of the subsets can not be completed
562   */
563  public Subset joinSubsets(Subset subset1, Subset subset2)
564  throws Exception{
565    BitSet b1 =(BitSet)subset1.subset.clone ();
566    BitSet b2 =(BitSet)subset2.subset.clone ();
567
568    b1.or (b2);
569
570    double newMerit =ASEvaluator.evaluateSubset (b1);
571    m_totalEvals++;
572
573    return new Subset((BitSet)b1, newMerit);
574  }
575
576  /**
577   * converts a BitSet into a list of attribute indexes
578   *
579   * @param group the BitSet to convert
580   * @return an array of attribute indexes
581   */
582  public int[] attributeList (BitSet group) {
583    int count = 0;
584
585    // count how many were selected
586    for (int i = 0; i < m_numAttribs; i++) {
587      if (group.get(i)) {
588        count++;
589      }
590    }
591
592    int[] list = new int[count];
593    count = 0;
594
595    for (int i = 0; i < m_numAttribs; i++) {
596      if (group.get(i)) {
597        list[count++] = i;
598      }
599    }
600
601    return  list;
602  }
603
604
605  // Auxiliar Class for handling solutions and its respective merit
606  public class Subset implements Serializable{
607
608    double merit;
609    BitSet subset;
610
611    public Subset(BitSet subset, double merit){
612      this.subset = (BitSet)subset.clone ();
613      this.merit = merit;
614    }
615
616    public Subset(){
617      this.subset =null;
618      this.merit =-1.0;
619    }
620
621    public boolean isEqual(Subset otherSubset){
622      if(subset.equals (otherSubset.subset))return true;
623      return false;
624    }
625
626    public Subset clone(){
627      return new Subset((BitSet)subset.clone (), this.merit);
628    }
629
630    public int cardinality(){
631      if(subset == null) return 0;
632      return subset.cardinality ();
633    }
634
635    public void flip(int index)
636    throws Exception{
637
638      subset.flip (index);
639      merit = ASEvaluator.evaluateSubset (subset);
640      m_totalEvals ++;
641    }
642
643    public boolean contains(int indexAttribute){
644      return subset.get (indexAttribute);
645    }
646  }
647  //..........
648
649
650  // Test Methods
651
652  public String printSubset(Subset subset){
653    StringBuffer bufferString = new StringBuffer();
654
655    if(subset == null){
656      //System.out.println ("null");
657      return "";
658    }
659
660    BitSet bits =subset.subset;
661    double merit =subset.merit;
662    List<Integer> indexes =new ArrayList<Integer>();
663
664    for (int i = 0; i<m_numAttribs; i++) {
665      if(bits.get (i)){
666        //System.out.print ("1");
667        indexes.add (i+1);
668      }
669      //else System.out.print ("0");
670    }
671    bufferString.append (Utils.doubleToString (merit,8,5)+"\t "+indexes.toString ()+"\n");
672    //System.out.print (" with a merit of: "+merit);
673
674    return bufferString.toString ();
675  }
676
677  //........
678
679
680
681  /**
682   * Returns a string describing this search method
683   * @return a description of the search suitable for
684   * displaying in the explorer/experimenter gui
685   */
686  public String globalInfo() {
687    return "Tabu Search :\n\nPerforms a search  "
688    +"through "
689    +"the space of attribute subsets. Evading local maximums by accepting bad and diverse solutions "
690    +"and make further search in the best soluions."
691    +" Stops when there's not more improvement in n iterations\n;"
692    + "For more information see:\n\n"
693    + getTechnicalInformation().toString();
694  }
695
696  /**
697   * Returns an instance of a TechnicalInformation object, containing
698   * detailed information about the technical background of this class,
699   * e.g., paper reference or book this class is based on.
700   *
701   * @return the technical information about this class
702   */
703  public TechnicalInformation getTechnicalInformation() {
704    TechnicalInformation        result;
705
706    result = new TechnicalInformation(Type.BOOK);
707    result.setValue(Field.AUTHOR, "Abdel-Rahman Hedar, Jue Wangy, and Masao Fukushima");
708    result.setValue(Field.MONTH, "July");
709    result.setValue(Field.YEAR, "2006");
710    result.setValue(Field.TITLE, "Tabu Search for Attribute Reduction in Rough Set Theory");
711    result.setValue(Field.LANGUAGE, "English");
712
713    return result;
714  }
715
716  /**
717   * Returns the revision string.
718   *
719   * @return the revision
720   */
721  public String getRevision() {
722    return RevisionUtils.extract("$Revision: 4976 $");
723  }
724
725  public TabuSearch() {
726    resetOptions();
727  }
728
729
730  /**
731   * Returns the tip text for this property
732   * @return tip text for this property suitable for
733   * displaying in the explorer/experimenter gui
734   */
735  public String seedTipText() {
736    return "Set the random seed.";
737  }
738
739  /**
740   * set the seed for random number generation
741   * @param s seed value
742   */
743  public void setSeed(int s) {
744    m_seed = s;
745  }
746
747  /**
748   * get the value of the random number generator's seed
749   * @return the seed for random number generation
750   */
751  public int getSeed() {
752    return m_seed;
753  }
754
755
756  /**
757   * Returns the tip text for this property
758   * @return tip text for this property suitable for
759   * displaying in the explorer/experimenter gui
760   */
761  public String diversificationProbTipText() {
762    return "Set the probability of diversification. This is the probability of "
763    +"change of search subspace in an abrupt way";
764  }
765
766  /**
767   * set the probability of diverification
768   * @param p the probability of change of search subspace in an abrupt way
769   */
770  public void setDiversificationProb(double p) {
771    m_diversificationProb = p;
772  }
773
774  /**
775   * get the probability of diversification
776   * @return the probability of diversification
777   */
778  public double getDiversificationProb() {
779    return m_diversificationProb;
780  }
781
782  /**
783   * Returns the tip text for this property
784   * @return tip text for this property suitable for
785   * displaying in the explorer/experimenter gui
786   */
787  public String numNeighborhoodTipText() {
788    return "Set the number of current solution's neighborhood"+
789    " to generate for looking for a better solution";
790  }
791
792  /**
793   * set the number of neighborhood
794   * @param n the number of neighborhood
795   */
796  public void setNumNeighborhood(int n) {
797    m_numNeighborhood = n;
798  }
799
800  /**
801   * get the number of neighborhood
802   * @return the number of neighborhood
803   */
804  public int getNumNeighborhood() {
805    return m_numNeighborhood;
806  }
807
808  /**
809   * Returns the tip text for this property
810   * @return tip text for this property suitable for
811   * displaying in the explorer/experimenter gui
812   */
813  public String initialSizeTipText() {
814    return "Set the number of attributes that are going to be in the initial Solution";
815  }
816
817  /**
818   * set the number of attributes that are going to be in the initial Solution
819   * @param n the number of attributes
820   */
821  public void setInitialSize(int n) {
822    m_initialSize = n;
823  }
824
825  /**
826   * get the number of of attributes that are going to be in the initial Solution
827   * @return the number of attributes
828   */
829  public int getInitialSize() {
830    return m_initialSize;
831  }
832
833
834  public Enumeration listOptions () {
835    Vector newVector = new Vector(4);
836
837    newVector.addElement(new Option("\tSpecify the number of attributes "
838        + "\n\tin the initial Solution.."
839        ,"Z",1
840        , "-Z <numInitialSolution>"));
841    newVector.addElement(new Option("\tSpecify the diversification probabilities,"
842        + "\n\tif this value is near to 0 then the best attributes"
843        + "\n\t will have more probabilities of keeping in the new diverse solution"
844        , "P", 1
845        , "-P <diversificationProb>"));
846    newVector.addElement(new Option("\tSet the random number seed."
847        +"\n\t(default = 1)"
848        , "S", 1, "-S <seed>"));
849    newVector.addElement(new Option("\tSet the number of neighbors to generate."
850        , "N", 1, "-N <number of neighbors>"));
851
852    return  newVector.elements();
853  }
854
855  /**
856   *
857   <!-- options-start -->
858   * Valid options are: <p/>
859   *
860   * <pre> -Z &lt;numInitialSolution&gt;
861   *  Specify the number of attributes
862   *  in the initial Solution..</pre>
863   *
864   * <pre> -P &lt;diversificationProb&gt;
865   *  Specify the diversification probabilities,
866   *  if this value is near to 0 then the best attributes
867   *   will have more probabilities of keeping in the new diverse solution</pre>
868   *
869   * <pre> -S &lt;seed&gt;
870   *  Set the random number seed.
871   *  (default = 1)</pre>
872   *
873   * <pre> -N &lt;number of neighbors&gt;
874   *  Set the number of neighbors to generate.</pre>
875   *
876   <!-- options-end -->
877   *
878   * @param options the list of options as an array of strings
879   * @exception Exception if an option is not supported
880   *
881   **/
882  public void setOptions (String[] options)
883  throws Exception {
884    String optionString;
885    resetOptions();
886
887
888    optionString = Utils.getOption('Z', options);
889    if (optionString.length() != 0) {
890      setInitialSize (Integer.parseInt(optionString));
891    }
892
893    optionString = Utils.getOption('P', options);
894    if (optionString.length() != 0) {
895      setDiversificationProb (Double.parseDouble(optionString));
896    }
897
898    optionString = Utils.getOption('S', options);
899    if (optionString.length() != 0) {
900      setSeed(Integer.parseInt(optionString));
901    }
902
903    optionString = Utils.getOption('N', options);
904    if (optionString.length() != 0) {
905      setNumNeighborhood (Integer.parseInt(optionString));
906    }
907
908  }
909
910  /**
911   * Gets the current settings of TabuSearch.
912   *
913   * @return an array of strings suitable for passing to setOptions()
914   */
915  public String[] getOptions () {
916    String[] options = new String[8];
917    int current = 0;
918
919    options[current++] = "-Z";
920    options[current++] = "" + getInitialSize ();
921
922    options[current++] = "-P";
923    options[current++] = ""+getDiversificationProb ();
924
925    options[current++] = "-S";
926    options[current++] = "" + getSeed();
927
928    options[current++] = "-N";
929    options[current++] = "" + getNumNeighborhood ();
930
931
932    while (current < options.length)
933      options[current++] = "";
934
935    return  options;
936  }
937
938  /**
939   * returns a description of the search.
940   * @return a description of the search as a String.
941   */
942  public String toString() {
943    StringBuffer FString = new StringBuffer();
944
945    FString.append("\nTabu Search "
946        + "\n\tInitial Size: "+getInitialSize ());
947
948
949    if(getInitialSize () > 0){
950      FString.append("\n\tInitial Solution (Generated by SFS):");
951      FString.append("\n\tmerit:"+"\t\t"+" subset");
952      FString.append("\n\t"+ printSubset (m_initialSolution));
953
954    }
955    FString.append("\tdiversificationProb: "
956        +Utils.doubleToString(Math.abs(getDiversificationProb ()),8,3)+"\n");
957
958    FString.append("\tTotal number of subsets evaluated: "
959        + m_totalEvals + "\n");
960
961    FString.append("\tMerit of best subset found: "
962        +Utils.doubleToString(Math.abs(m_Sbest.merit),8,3)+"\n");
963
964    /*FString.append("\tTime procesing the search space: "
965        +(double)m_processinTime/1000+" seconds\n"); */
966
967    return FString.toString();
968  }
969
970  protected void resetOptions () {
971    m_initialSize = -1;
972    m_numNeighborhood = -1;
973    m_seed = 1;
974    m_diversificationProb = 1.0;
975    m_totalEvals = 0;
976    m_processinTime = 0;
977  }
978
979}
980
Note: See TracBrowser for help on using the repository browser.