libfgen
0.1.15
Library for optimization using a genetic algorithm or particle swarm optimization
|
00001 /* 00002 bitstring.c -- functions for handling bitstrings. 00003 00004 fgen -- Library for optimization using a genetic algorithm or particle swarm optimization. 00005 Copyright 2012, Harm Hanemaaijer 00006 00007 This file is part of fgen. 00008 00009 fgen is free software: you can redistribute it and/or modify it 00010 under the terms of the GNU Lesser General Public License as published 00011 by the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 fgen is distributed in the hope that it will be useful, but WITHOUT 00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00016 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00017 License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with fgen. If not, see <http://www.gnu.org/licenses/>. 00021 00022 */ 00023 00024 00025 #include <stdlib.h> 00026 #include <stdint.h> 00027 #include <limits.h> 00028 #include <fgen.h> 00029 #include <random.h> 00030 00031 #if __WORDSIZE == 64 00032 #define POINTER_TO_UINT(x) ((unsigned long int)(x)) 00033 #else 00034 #define POINTER_TO_UINT(x) ((unsigned int)(x)) 00035 #endif 00036 00037 void CreateRandomBitstring(FgenRNG *rng, unsigned char *bitstring, int size_in_bytes) { 00038 while (size_in_bytes >= 1 && (POINTER_TO_UINT(bitstring) & 3) != 0) { 00039 *bitstring = fgen_random_8(rng); 00040 size_in_bytes--; 00041 bitstring++; 00042 } 00043 while (size_in_bytes >= 4) { 00044 *(unsigned int *)bitstring = fgen_random_32(rng); 00045 size_in_bytes -= 4; 00046 bitstring += 4; 00047 } 00048 while (size_in_bytes >= 1) { 00049 *bitstring = fgen_random_8(rng); 00050 size_in_bytes--; 00051 bitstring++; 00052 } 00053 } 00054 00060 static void fgen_set_random_bit(FgenRNG *rng, unsigned char *bitstring, const int offset) { 00061 bitstring[offset / 8] &= 0xFF ^ (1 << (offset & 7)); 00062 bitstring[offset / 8] |= fgen_random_2(rng) << (offset & 7); 00063 } 00064 00070 void fgen_set_random_bitstring(FgenRNG *rng, unsigned char *bitstring, int offset, int nu_bits) { 00071 int i; 00072 if (nu_bits == 1) { 00073 fgen_set_random_bit(rng, bitstring, offset); 00074 return; 00075 } 00076 /* Fast case when offset and nu_bits are a multiple of 8. */ 00077 if ((offset & 7) == 0 && (nu_bits & 7) == 0) { 00078 CreateRandomBitstring(rng, bitstring + offset / 8, nu_bits / 8); 00079 return; 00080 } 00081 for (i = offset; i < offset + nu_bits; i++) 00082 fgen_set_random_bit(rng, bitstring, i); 00083 } 00084 00089 void fgen_mutate_bit(unsigned char *bitstring, int bitnumber) { 00090 bitstring[bitnumber / 8] ^= 1 << (bitnumber & 7); 00091 } 00092 00097 int fgen_get_bit(const unsigned char *bitstring, int bitnumber) { 00098 return (bitstring[bitnumber / 8] & (1 << (bitnumber & 7))) >> (bitnumber & 7); 00099 } 00100 00101 00107 void fgen_copy_partial_bitstring(const unsigned char *src, unsigned char *dest, int bitoffset, int number_of_bits) { 00108 int i, offset; 00109 if (number_of_bits == 0) 00110 return; 00111 offset = bitoffset / 8; 00112 if ((bitoffset & 7) != 0) { 00113 for (i = bitoffset & 7; i < 8; i++) { 00114 dest[offset] &= ~(1 << i); 00115 dest[offset] |= src[offset] & (1 << i); 00116 number_of_bits--; 00117 if (number_of_bits == 0) 00118 return; 00119 } 00120 offset++; 00121 } 00122 while (number_of_bits >= 8 && (POINTER_TO_UINT(&dest[offset]) & 3) != 0) { 00123 dest[offset] = src[offset]; 00124 number_of_bits -= 8; 00125 offset++; 00126 } 00127 while (number_of_bits >= 32) { 00128 *(unsigned int *)&dest[offset] = *(unsigned int *)&src[offset]; 00129 number_of_bits -= 32; 00130 offset += 4; 00131 } 00132 while (number_of_bits >= 8) { 00133 dest[offset] = src[offset]; 00134 number_of_bits -= 8; 00135 offset++; 00136 } 00137 for (i = 0; i < number_of_bits; i++) { 00138 dest[offset] &= ~(1 << i); 00139 dest[offset] |= src[offset] & (1 << i); 00140 } 00141 } 00142