0/1背包问题遗传算法

来源:互联网 发布:唐大华知乎 编辑:程序博客网 时间:2024/06/10 20:39
 

#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;
}

原创粉丝点击