Как извлечь несколько параметров из двоичной хромосомы
Я пытаюсь использовать библиотеку AForge.Net Genetics для создания простого приложения в целях оптимизации. У меня есть сценарий, в котором у меня есть четыре входных параметра, поэтому я попытался изменить класс " OptimizationFunction2D.cs", расположенный в проекте AForge.Genetic, для обработки четырех параметров. При преобразовании бинарных хромосом в 4 параметра (type = double) я не уверен, что мой подход правильный, так как я не знаю, как проверить извлеченные значения. Ниже приведен сегмент кода, где мой код отличается от исходного кода AForge:
public double[] Translate( IChromosome chromosome )
{
// get chromosome's value
ulong val = ((BinaryChromosome) chromosome).Value;
// chromosome's length
int length = ((BinaryChromosome) chromosome).Length;
// length of W component
int wLength = length/4;
// length of X component
int xLength = length / 4;
// length of Y component
int yLength = length / 4;
// length of Z component
int zLength = length / 4;
// W maximum value - equal to X mask
ulong wMax = 0xFFFFFFFFFFFFFFFF >> (64 - wLength);
// X maximum value
ulong xMax = 0xFFFFFFFFFFFFFFFF >> (64 - xLength);
// Y maximum value - equal to X mask
ulong yMax = 0xFFFFFFFFFFFFFFFF >> (64 - yLength);
// Z maximum value
ulong zMax = 0xFFFFFFFFFFFFFFFF >> (64 - zLength);
// W component
double wPart = val & wMax;
// X component;
double xPart = (val >> wLength) & xMax;
// Y component;
double yPart = (val >> (wLength + xLength) & yMax);
// Z component;
double zPart = val >> (wLength + xLength + yLength);
// translate to optimization's function space
double[] ret = new double[4];
ret[0] = wPart * _rangeW.Length / wMax + _rangeW.Min;
ret[1] = xPart * _rangeX.Length / xMax + _rangeX.Min;
ret[2] = yPart * _rangeY.Length / yMax + _rangeY.Min;
ret[3] = zPart * _rangeZ.Length / zMax + _rangeZ.Min;
return ret;
}
Я не уверен, правильно ли разделяю значение хромосомы на четыре части (wPart/xPart/yPart/zPart). Исходная функция в библиотеке AForge.Genetic выглядит следующим образом:
public double[] Translate( IChromosome chromosome )
{
// get chromosome's value
ulong val = ( (BinaryChromosome) chromosome ).Value;
// chromosome's length
int length = ( (BinaryChromosome) chromosome ).Length;
// length of X component
int xLength = length / 2;
// length of Y component
int yLength = length - xLength;
// X maximum value - equal to X mask
ulong xMax = 0xFFFFFFFFFFFFFFFF >> ( 64 - xLength );
// Y maximum value
ulong yMax = 0xFFFFFFFFFFFFFFFF >> ( 64 - yLength );
// X component
double xPart = val & xMax;
// Y component;
double yPart = val >> xLength;
// translate to optimization's function space
double[] ret = new double[2];
ret[0] = xPart * rangeX.Length / xMax + rangeX.Min;
ret[1] = yPart * rangeY.Length / yMax + rangeY.Min;
return ret;
}
Может кто-нибудь подтвердить, если мой процесс конвертирования правильный или есть лучший способ сделать это.
1 ответ
Нет, это работает, но вам не нужно, чтобы это было так сложно.
ulong wMax = 0xFFFFFFFFFFFFFFFF >> (64 - wLength);
это возвращает одно и то же значение для всех результатов wMax xMax yMax zMax
так что просто сделайте один и назовите его componentMask
part = (val >> (wLength * pos) & componentMask);
где pos - позиция компонента на основе 0. так что 0 для ш, 1 для х...
остальное в порядке.
РЕДАКТИРОВАТЬ: если длина не делится на 4, вы можете сделать последнюю часть просто val >> (wLength * pos), чтобы она имела оставшиеся биты.