Example #1
0
bool reduceRoute(solution &sol, const problem& input){
	if(sol.routes.size() <= 1) return false;
	unsigned int before = sol.routes.size();
	
	// find route with highest (distance / # of customers).
	list<route>::iterator minR;
	double dis = 0;
	for(list<route>::iterator it = sol.routes.begin(); it != sol.routes.end(); it++){
		double p = it->distance / it->visits.size();
		if(p > dis){
			minR = it;
			dis = p;
		}
	}

	// remove this shortest route
	route shortest = (*minR);
	sol.routes.erase(minR);

	for(list<int>::iterator cus = shortest.visits.begin(); cus != shortest.visits.end();){
		solution min = sol;

		for(int tryCount = 0; tryCount < input.getNumCusto(); tryCount++){
			solution temp = min;
			list<route>::iterator r = temp.routes.begin();
			advance(r, rand() % temp.routes.size() );
			list<int>::iterator ins = r->visits.begin();
			advance(ins, r->visits.size());
			r->visits.insert(ins, *cus);
			r->modified = true;
			temp.fitness(input);
			if(temp.totalDistance < min.totalDistance){
				min = temp;
			}
		}

		if(min.totalDistance < sol.totalDistance){
			cus = shortest.visits.erase(cus);
			shortest.modified = true;
			sol = min;
		}else{
			cus++;
		}
	}

	// append a new route with customers can't be inserted.
	if( !shortest.visits.empty() ){
		sol.routes.push_front(shortest);
	}

	return (sol.routes.size() < before);
}
Example #2
0
void mutation(solution &sol, const problem& input){
	int tryCount = 0;
	while(tryCount < input.getNumCusto() ){
		solution test = sol;

		// randomly select two routes
		list<route>::iterator routeA = test.routes.begin();
		advance(routeA, rand() % test.routes.size() );
		list<route>::iterator routeB = test.routes.begin();
		advance(routeB, rand() % test.routes.size() );

		// # of feasible route BEFORE the reinsertion
		int beforeFeasibleCount = 0;
		if(routeA->feasible) beforeFeasibleCount++;
		if(routeB->feasible) beforeFeasibleCount++;

		// randomly select two positions
		list<int>::iterator cusA = routeA->visits.begin();
		advance(cusA, rand() % routeA->visits.size() );
		list<int>::iterator cusB = routeB->visits.begin();
		advance(cusB, rand() % routeB->visits.size() );

		routeB->visits.insert(cusB, *cusA);
		routeB->modified = true;
		routeA->visits.erase(cusA);
		routeA->modified = true;
		bool reduce = false;
		if( routeA->visits.empty() ){
			test.routes.erase(routeA);
			reduce = true;
		}

		test.fitness(input);
		
		// # of feasible route AFTER the reinsertion
		int afterFeasibleCount = 0;
		if(reduce || routeA->feasible) afterFeasibleCount++;
		if(routeB->feasible) afterFeasibleCount++;

		if(afterFeasibleCount >= beforeFeasibleCount) sol = test;

		tryCount++;
	}
}
Example #3
0
void solution::random(int maxRoutes, const problem& input){
	clear();

	vector< vector<int> > newRoutes;
	newRoutes.resize(maxRoutes);

	for(int id = 1; id <= input.getNumCusto(); ++id){
		newRoutes[ rand() % maxRoutes ].push_back(id);
	}

	for(int i = 0; i < maxRoutes; ++i){
		if(newRoutes[i].size() > 0){
			// insert customers according to time windows' position
			vector<int> sorted;
			sorted.reserve(newRoutes[i].size());

			for(unsigned int j = 0; j < sorted.capacity(); ++j){
				int minStart = input[0].end, minEnd = input[0].end, id;
				for(unsigned int k = 0; k < newRoutes[i].size(); ++k){
					if(input[ newRoutes[i][k] ].end < minEnd){
						minEnd = input[ newRoutes[i][k] ].end;
						minStart = input[ newRoutes[i][k] ].start;
						id = k;
					}else if(input[ newRoutes[i][k] ].end == minEnd && input[ newRoutes[i][k] ].start < minStart ){
						minStart = input[ newRoutes[i][k] ].start;
						id = k;
					}
				}
				sorted.push_back(newRoutes[i][id]);
				newRoutes[i].erase(newRoutes[i].begin() + id);
			}
			
			route newRoute;
			newRoute.visits = list<int>(sorted.begin(), sorted.end());
			routes.push_back(newRoute);
		}
	}

	fitness(input);
}