This project is read-only.

Asking information about TribePSO implementation

Dec 15, 2011 at 9:12 AM

Good day,

I have been studing TribePSO and I have been running the given software. I would like to gongratulate Mr. Peter Baughman for his excellent work.

Trying to embed TribePSO in a loop so as to be able to run it multiple times (say 100) in order to get statistics, I get stuck! The reason is that the "s.movethenAdapt()" I think teturns the minimum fitness among all particles for a given generation. This value is retained, so if the algorithm has ran for the total number of generations and I try to run it again, for the second experiment, from the beginning generation, the minimum fitness (i.e. s.BestSolution.Error) having being retained, causes the problem. Actualy, the situation is that, as the experiments proceed,  in every succesive experiment I get a smaller total minimum than the total minimum of the previous experiment. Obviously, I suppose that the initial value of fitness is not being re-initialized to worst possible value. I wonder if you would be kind enough to give me some advise on how to overcome this problem. Perhaps you could provide the source code of "s.movethenAdapt" so as to be able to make the appropriate adjustent.

Thanks in advance for your time

John Tassopoulos, Phd student

Dec 15, 2011 at 4:34 PM
Edited Dec 16, 2011 at 7:22 AM

John,

If I understand your question correctly, the behavior you're describing is by-design.  None of the default  SearchSpace objects have a way to roll them back to their original state.  In order to collect the type of statistics that you're trying to collect, you'll need to create a new SearchSpace object every time you want to perform an optimization.  I did this type of measurement near the end of the Tripod example but I never really elaborated on it.  Let me show you what to do for the Tripod example as it should be very similar for any type of objective function.  This assumes that you're going to use a Tripod IObjectiveFunction and a SingleThreadedGaussianSearchSpace SearchSpace object.  I'm also assuming that you want to count the number of calls to MoveThanAdapt() for a given optimization.  This is probably not exactly what you want, but it will serve as a good example.  I'm going to take the original Program.cs and modify it a bit.

First, I'm going to pull all of the code that actually makes the measurements out into a method called "OptimizeTripod".  That will look something like this:

const double maxError = .0001;
public static int OptimizeTripod(IHyperspaceRandom rng)
{
    Tripod functionToSolve = new Tripod(); //Create a Tripod function to solve
    SearchSpace s = new SingleThreadedGaussianSearchSpace(functionToSolve, rng); //Create a fresh search space

    for (int n = 0; n < 10000; n++)
    {
         s.MoveThenAdapt();
         if (s.BestSolution.Error <= maxError)
        {
            return n;
        }
    }

    //We didn't find a good-enough solution.  Return -1 to indicate failure
    return -1;
}

 

You'll note that we actually pass in the instance of the random number generator that we're going to use to create the SearchSpace.  That's because, by default, the search space will create it's own random number generator and seed it with the system time.  Normally this is OK, but if we run these trials fast enough back-to-back, we'll probably have two trials using a PRNG that was seeded with the same value.  That could generate some bogus performance statistics.  To solve that problem, we'll use the same PRNG for every trial, but not re-initialize it between trials.  That way each optimization gets its own sequence of pseudo random numbers

Then we'll modify the Main method a bit.  I'm going to modify it to just dump the results out to the Console.  You probably want to do something more useful like put the results in a CSV file so you can analyze them

static void Main(string[] args) 
{ 
    HyperspaceRandom randomNumberGenerator = new HyperspaceRandom();
    for (int n = 0; n < 100; n++) //100 trials 
    {
        int result = OptimizeTripod(randomNumberGenerator);

        if(result != -1) Console.WriteLine(result); 
        else Console.WriteLine("Failed"); 
    } 
} 

There are a few tricky problems that could pop up depending on exactly what you're trying to measure with regards to the performance of this algorithm.  For example, every time you create a new SingleThreadedGaussianSearchSpace, it will be seeded with a single particle in a random location.  If you need the single particle to be in the same starting location every time, you'll need to provide an Initial Guess in your implementation of the IObjectiveFunction.  If you need more than one initial particle, you'll need to provide your own implementation of SearchSpace and override the SeedSearchSpace() method.

Regarding the source code for TribesPSO, you can always find the latest source up at the top of the page under "Source Code."  The default MoveThenAdapt() method is located under Main->Source->TribesPSO->SearchSpace.cs.  TribesPSO was designed so hopefully you never have to actually change the source code.  If there's a behavior in a class you want to change, you should be able to inherit from that class and override the behavior in question.  Doing it that way also makes it easier to compare results with other people because you can both ensure that you're using the same base library.

Let me know if you run into any more issues.  I've got a bit more free time these days, so I'd like to add a few more examples to the documentation that show how to do things like create your own SearchSpace implementation and how to create particles with new movement strategies.

Best Regards,

Peter Baughman

Dec 16, 2011 at 7:15 AM
Edited Dec 16, 2011 at 7:23 AM

It's also important to note that when you're comparing the performance of particle swarm optimization algorithms, you're usually not interested in the number of moves (calls to MoveThanAdapt() in this example) as much as you're interested in the number of evaluations of the objective function.  The easiest way to measure thatt is to add a property to your objective function called something like "NumberOfEvaluations" that gets initialized to zero in the constructor and gets incremented in the Evaluate(EuclidianVector position) method.  Then, when you've converged on a good enough solution, return NumberOfEvaluations instead of the number of moves.

If you're using one of the multi-threaded search spaces, you'll want to use Interlocked.Increment or some other method of ensuring that only one thread increments the NumberOfEvaluations at a time.

Dec 20, 2011 at 6:17 AM

Note to readers, this thread is continued here