I am trying to solve PSO (Particle Swarm Optimisation) to have a particle where some values must be integers and must be unique and some are float (may not be unique) e.g. a solution like this is desirable after every velocity update: {0,2,1,5,4,6,8,7,0.087,0.345} The first eight values must be unique and integers and last two can be regular updates. The problem I am having is that after velocity update the first eight values tend to duplicate like e.g.: {0,0,1,2,3,4,5,6,7,0.76,0.345}. How this can be achieved? Your help is much appreciated. Thank you
After the velocity (and position) update for a single particle, I assume you perform some discretisation of the first 6 of the 8 (position?) values to transform them from floating points to integers. In this step, you need to define a measure to ensure the uniqueness of the integer numbers.
Lets say, for some particle i, that we have the following position matrix after the velocity update (leaving out the 7th and 8th entry)
posVector(particle i) = {0.1, -0.2, 1.3, 6.2, 2.4, 1.6}.
If we just round these number, we would end up with integers
posVectorInt(particle i) = {0, 0, 1, 6, 2, 2},
in which the entries are non-unique. One simple way to fix this would be to, prior to transforming float->int, ranking the numbers in position 1 through 6, e.g., w.r.t. increasing value, as
posVectorRank(particle i) = {2, 1, 3, 6, 5, 4}.
Next, we could start rounding particles, starting with rank 1, but, from rank 2 and onwards, ascertaining that the rounded value is not equal to the previously rounded value. In some pseudo/mixed-code,
// Rank 1 rounding
for entry in posVectorRank where posVectorRank(entry) = 1
posVector(entry) = round(posVector(entry))
// Rank 2->6 rounding
for entry in posVectorRank where posVectorRank(entry) = 2 to 6
previousInteger = posVector(entry-1)
if round(posVector(entry-1)) equals previousInteger
posVector(entry) = round(posVector(entry))+1
else
posVector(entry) = round(posVector(entry))
This would result in the final posVectorInt as
posVectorInt(particle i) = {1, 0, 2, 6, 4, 3}.
Note, however, that it's probably better to build a more sophisticated "rank -> integer" function that takes into account e.g. swarm best or particle best values w.r.t. the objective function.
If you're using this method to find the optimal solution to some optimization problem with mixed continuous and integer valued (decision) variables, note that such problems are non-convex. Going, by rounding, from a "good" continuously relaxed variable vector to one that is (integer) feasible in the non-relaxed problem doesn't necessarily yield a "good" solution in the latter. Hence, if you decide to use PSO in such context, the "rank -> integer" method should probably contain some clever heuristics, constructed with the actual problem to be solved in mind. This, in itself, is---in my experience---an unusual approach for using PSO, as PSO can generally be considered a "brute-force" method of solving nonlinear/nonconvex optimisation problems with continuous variables.