遗传算法解决0-1背包问题

研1入学以前的作业,本来想用Python写,但是两三年没用Python了,考研期间也天天c++,所以就用c++写了,还有能优化的地方,而且有些地方写的很蠢,但是…能跑起来就行了(逃)

#include
#include 
#include 
#include
#include
#define random(x) rand()%(x)
using namespace std;

struct individual{
	vector<bool> DNA;
	int fitness;
};

struct stuff{
	int weight;
	int value;
	stuff(int w,int v) : weight(w) , value(v) {}
}; 

int capacity; 							//背包容量 
int number; 							//物品数量(DNA长度)
int popsize;
int max_gen;
int max_fitness;
int mutate_rate = 1;
vector<stuff> mystuff; 						//物品重量 
vector<bool> NewDNA;
vector<individual> population; 			//本代种群 
vector<individual> population_n;   		 //下一代种群与本代种群的混合 

void sort_by_fitness(){
	for(int i=0;i<popsize-1;i++)
	{
		for(int j=0;j<popsize-1-i;j++)
		{
			if(population[j].fitness < population[j+1].fitness)
			{
				individual temp = population[j];
				population[j] = population[j+1];
				population[j+1] = temp;
			}
		}
	}
}


int get_fitness(individual myind){
	int cntw = 0;
	int cntv = 0;
	for(int i=0;i<number;i++)
	{
		if(myind.DNA[i]) 
		{
			cntw += mystuff[i].weight;
			cntv += mystuff[i].value;
		}
	}
	if(cntw> capacity) return 0;
	else return cntv;
}

void initial(){
	individual tempind;
	srand((int)time(0));
	for(int i=0;i<popsize;i++)
	{
		for(int j=0;j<number;j++)
		{
			bool temp = random(2);
			tempind.DNA.push_back(temp);
		}
		tempind.fitness = get_fitness(tempind);
		population.push_back(tempind);
		tempind.DNA.clear();
	}
}


void cross(){
	srand((int)time(0));
	int front = 0,tail = popsize - 1;
	if(popsize % 2 == 1) tail--;
	int crosspoint = random(number);
	while(front+1 != tail)
	{
		individual offspring1;
		individual offspring2;
		for(int i=0;i<crosspoint;i++)
		{
			offspring1.DNA.push_back(population[front].DNA[i]);
			offspring2.DNA.push_back(population[tail].DNA[i]);
		}
		for(int i=crosspoint;i<number;i++)
		{
			offspring1.DNA.push_back(population[tail].DNA[i]);
			offspring2.DNA.push_back(population[front].DNA[i]);
		}
		offspring1.fitness = get_fitness(offspring1);
		offspring2.fitness = get_fitness(offspring2);
		
		population_n.push_back(offspring1);
		population_n.push_back(offspring2);
		population_n.push_back(population[front]);
		population_n.push_back(population[tail]);
		
		front++;
		tail--;
	}
}

void select(){
	max_fitness = 0;
	for(int i=0;i<population_n.size();i++)
	{
		max_fitness = max(max_fitness,population_n[i].fitness);
	}
	population.clear();
	while(population.size() < popsize)
	{
		for(int i=0;i<popsize;i++)
		{	
			if(population_n[i].fitness == 0) //超重的个体有百分之15的几率活下来,以保持多样性 
			{
				if(random(100) < 15)
				population.push_back(population_n[i]);
				if(population.size() == popsize) return;
			}
			else
			{
				if(random(max_fitness) < population_n[i].fitness)
				population.push_back(population_n[i]);
				if(population.size() == popsize) return;
			}
		}
	}
	
}

void mutate(){
	for(int i=0;i<popsize;i++)
	{
		srand((int)time(0));
		if(random(100) < mutate_rate)
		{
			int mutatepoint = random(number);
			if(population[i].DNA[mutatepoint]) population[i].DNA[mutatepoint] = 0;
			else population[i].DNA[mutatepoint] = 1;
		}
	}
}

void print_pop(){
	for(int i=0;i<popsize;i++)
	{
		cout<<"个体"<<i<<"的适应度为:"<<population[i].fitness<<",其DNA为:";
		for(int j=0;j<number;j++)
		{
			cout<<population[i].DNA[j];
		}
		cout<<endl;
	}
	cout<<"-------------------------------------------------------------"<<endl;
} 

int main(){
	cout<<"输入背包容量:"; 
    cin >> capacity;
	cout<<"输入物品件数:"; 
    cin >> number;
    for(int i=0;i<number;i++)
	{
		cout<<"输入第"<<i+1<<"个物品重量与价值:"; 
		int temp1,temp2;
		cin >> temp1 >> temp2;
		mystuff.push_back(stuff(temp1,temp2));
	}
	
	cout<<"输入种群规模与最大世代数:"; 
	cin>>popsize>>max_gen;
	initial();
	for(int k=1;k<=max_gen;k++)
	{
		sort_by_fitness();
		print_pop();
		cross();
		select();
		population_n.clear();
		mutate();
	}
	
}

你可能感兴趣的:(遗传算法)