#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define popsize 200
#define pc 0.618
#define pm 0.03
#define lchrom 50
#define maxgen 1000
struct population
{
int chrom[lchrom];
double weight;
double fitness;
}oldpop[popsize], newpop[popsize];
int weight[lchrom]= { 80, 82, 85, 70, 72, 70, 66, 50, 55, 25,
50, 55, 40, 48, 50, 32, 22, 60, 30, 32,
40, 38, 35, 32, 25, 28, 30, 22, 50, 30,
45, 30, 60, 50, 20, 65, 20, 25, 30, 10,
20, 25, 15, 10, 10, 10, 4, 4, 2, 1 },
profit[lchrom]= { 220, 208, 198, 192, 180, 180, 165, 162, 160, 158,
155, 130, 125, 122, 120, 118, 115, 110, 105, 101,
100, 100, 98, 96, 95, 90, 88, 82, 80, 77,
75, 73, 72, 70, 69, 66, 65, 63, 60, 58,
56, 50, 30, 20, 15, 10, 8, 5, 3, 1},
contain = 1000;
double sumfitness, maxfitness;
int maxpop;
int Cal_weight(struct population pop)
{
int pop_weight = 0;;
int i = 0;
for (i = 0; i < lchrom; i++)
{
pop_weight = pop_weight + pop.chrom[i] * weight[i];
}
return pop_weight;
}
int Cal_fit(struct population pop)
{
int pop_profit = 0;
int i = 0;
for (i = 0; i < lchrom; i++)
{
pop_profit = pop_profit + pop.chrom[i] * profit[i];
}
return pop_profit;
}
void statistics(struct population pop[popsize])
{
int i = 0;
sumfitness = pop[0].fitness;
maxfitness = pop[0].fitness;
maxpop = 0;
for (i = 0; i < popsize; i++)
{
sumfitness = sumfitness + pop[i].fitness;
if (pop[i].fitness > maxfitness)
{
maxfitness = pop[i].fitness;
maxpop = i;
}
}
}
void initpop(void)
{
int i = 0, j = 0;
int flag = 0;
int temp;
for (i = 0; i < popsize; i++)
{
flag = 1;
while(flag)
{
for (j = 0; j < lchrom; j++)
{
oldpop[i].chrom[j] = rand()%2;
}
temp = Cal_weight(oldpop[i]);
if (temp <= contain)
{
oldpop[i].weight = temp;
oldpop[i].fitness = Cal_fit(oldpop[i]);
flag = 0;
}
}
}
}
int execise(double probability)
{
if ((rand()%20001/20000.0) <= probability)
return 1;
return 0;
}
int selection()
{
int i = 0;
double P = 0.0;
double rand_number;
rand_number = (rand()%2001/2000.0);
do
{
P = P + (oldpop[i].fitness / sumfitness);
i++;
}while ((i < popsize) && (P < rand_number));
return i-1;
}
void crossover(int chr1[lchrom], int chr2[lchrom], struct population pop)
{
int i, cross_pos;
if (execise(pc))
{
cross_pos = rand()%(lchrom-1);
}
else
cross_pos = lchrom-1;
for (i = 0; i <= cross_pos; i++)
{
pop.chrom[i] = chr1[i];
}
for (i = cross_pos +1; i < lchrom; i++)
{
pop.chrom[i] = chr2[i];
}
}
int mutation(int mut)
{
if (execise(pm))
{
if (mut)
mut = 0;
else
mut = 1;
}
return mut;
}
void generation()
{
int i = 0, j = 0, mate1 = 0, mate2 = 0;
double temp;
int flag;
i = 0;
while (i < popsize)
{
flag = 1;
while (flag)
{
mate1 = selection();
mate2 = selection();
crossover(oldpop[mate1].chrom, oldpop[mate2].chrom, newpop[i]);
for (j = 0; j < lchrom; j++)
{
newpop[i].chrom[j] = mutation(newpop[i].chrom[j]);
}
temp = Cal_weight(newpop[i]);
if (temp <= contain)
{
newpop[i].weight = temp;
newpop[i].fitness = Cal_fit(newpop[i]);
flag = 0;
}
}
i++;
}
}
void print(struct population pop[popsize], int gen)
{
int j = 0;
printf("The generation is %d.\n", gen);
printf("The population's max fitness is %f.\n", pop[maxpop].fitness);
printf("The knapsack's weigth is %f.\n", pop[maxpop].weight);
printf("The population's chrom is: ");
for (j = 0; j < lchrom; j++)
{
if (0 == (j % 5))
printf(" ");
printf ("%d", pop[maxpop].chrom[j]);
}
printf("\n");
}
int main(void)
{
int i = 0, j = 0, k = 0;
double oldmax = 0;
srand((unsigned)time(NULL));
initpop();
statistics(oldpop);
print(oldpop, 0);
for (i = 1; i < maxgen; i++)
{
if (i%100==0)
{
srand( (unsigned)time( NULL ) );//置随机种子
}
generation();
statistics(newpop);
if (maxfitness < oldmax) continue;
else
{
oldmax = maxfitness;
print(newpop, i);
for(j = 0; j < popsize; j++)
{
oldpop[j].fitness = newpop[j].fitness;
oldpop[j].weight = newpop[j].weight;
for (k = 0; k < lchrom; k++)
{
oldpop[j].chrom[k] = newpop[j].chrom[k];
}
}
}
}
return 0;
}