使用模拟退火与禁忌搜索解决Capacitated Facility Location Problem

Capacitated Facility Location Problem

问题描述

Suppose there are n facilities and m customers. We wish to choose:
(1) which of the n facilities to open
(2) the assignment of customers to facilities
The objective is to minimize the sum of the opening cost and the assignment cost.
The total demand assigned to a facility must not exceed its capacity.

数学建模

将上述问题转化为数学模型。

  • 一共可选择开的工厂数目为factory_num
  • 客户的数目为customer_num
  • 每个工厂服务不同的客户的消费不同,使用allocating_cost[i][j]表示工厂i服务客户j的消费
  • 每个用户有不同的需求,用demand[i]表示客户i的需求,
  • 每个工厂有不同的容量,用capacity[i]表示工厂i的容量。
  • 工厂没有服务客户时就不开,否则就要开,用open_list[i]表示工厂i是否开。
  • 如果开,就要有开工厂的消费,用fixedcost[i]表示开工厂i的费用。
  • 每个客户只能由一个工厂服务,即只能由一个工厂处理一个客户的所有需求,用allocating_list[i]表示客户i所选择的工厂。

则这个问题对应的解为
m i n { ∑ i = 0 f a c t o r y _ n u m o p e n _ l i s t [ i ] ∗ f i x e d _ c o s t [ i ] + ∑ i = 0 c u s t o m e r _ n u m a l l o c a t i n g _ c o s t [ a l l o c a t i n g _ l i s t [ i ] ] } min\{\sum_{i = 0}^{factory\_num} open\_list[i] * fixed\_cost[i] + \sum_{i = 0}^{customer\_num} allocating\_cost[allocating\_list[i]] \} min{i=0factory_numopen_list[i]fixed_cost[i]+i=0customer_numallocating_cost[allocating_list[i]]}

解决方案一:模拟退火法

算法描述

算法的基本思想如下:

  1. 初始化:初始温度T充分大,初始解状态S,每个T值的迭代次数L
  2. 对k=1…L,做3-6步
  3. 产生新的解S’
  4. 计算增量Δt’ = C(S’) - C(S),C(S)为评价函数
  5. 若Δt’ < 0则接受S’作为新的当前解,否则以概率exp(-Δt’/T)接受S’为新的当前解
  6. 如果满足终止条件则输出当前解为最优解
  7. T逐渐减少,且T->0,然后转到第2步

产生随机初始解

作为一个解的首要条件是能服务全部的客户,因此从客户进行考虑,为全部的客户随机分配一个工厂,如果工厂不能满足,则换一个分配到一个为止。之后再判断每个工厂是否开。

void generate_random_solution(){
	for(int i = 0; i < customer_num; i++){
		while(true){
			int allocated = rand() % factory_num;
			if(capacity[allocated] >= demand[i]){
				allocating_list[i] = allocated;
				open_list[allocated] += 1;
				allocating_list[i] = allocated;
				capacity[allocated] -= demand[i];
				break;
			}
		}		
	}
}

邻域解

同样也是从客户进行考虑,随机选一个客户,然后随机为其换一个工厂服务。换了之后可能出现新的工厂不能满足这个客户,对于这种情况则重新选一个解。

终止条件

对于一个温度,使用一个策略来退出这个温度,这里的策略是重复迭代一定次数。

评价函数

直接用成本来评价这个解。但对于增量来说,这里没有必要全部都要再算一次。只要判断所涉及的两个工厂和两个用户的变化即可,即判断这种操作过后有没有导致工厂新开或者关闭,再算分配的代价的变化。

double calculate_delta_cost(int customer, int factory){
	int result = 0;
	//open new factory
	if(open_list[factory] == 0){
		result += fixed_cost[factory];
	}
	int f = allocating_list[customer];
	if(open_list[f] == 1){
		result -= fixed_cost[f];
	}
	result += allocating_cost[factory][customer] - allocating_cost[f][customer];
	return result;

}

温度的变化

使用函数 T = 0.99 T T=0.99T T=0.99T来降温,当T小于某一特定值时,算法终止,产生最终解,最小温度定为0.01。

完整代码

#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<cmath>
#include<time.h>

using namespace std;
#define FILE_NUM 71
#define T 500
#define T_min 0.01
#define L 10

int factory_num;
int customer_num;
int* capacity;
int* fixed_cost;
double* demand;
double** allocating_cost;

// how many customer to allocate
int* open_list;
// witch factory to allocate
int* allocating_list;

double get_total_cost(){
	double cost = 0;

	for(int i = 0; i < factory_num; i++){
		if(open_list[i] != 0){
			cost += fixed_cost[i];
		}
	}
	for(int i = 0; i < customer_num; i++){
		cost += allocating_cost[allocating_list[i]][i];
	}
	return cost;
}
void generate_random_solution(){
	for(int i = 0; i < customer_num; i++){
		while(true){
			int allocated = rand() % factory_num;
			if(capacity[allocated] >= demand[i]){
				allocating_list[i] = allocated;
				open_list[allocated] += 1;
				allocating_list[i] = allocated;
				capacity[allocated] -= demand[i];
				break;
			}
		}
		
	}
}
double calculate_delta_cost(int customer, int factory){
	int result = 0;
	//open new factory
	if(open_list[factory] == 0){
		result += fixed_cost[factory];
	}
	int f = allocating_list[customer];
	if(open_list[f] == 1){
		result -= fixed_cost[f];
	}
	result += allocating_cost[factory][customer] - allocating_cost[f][customer];
	return result;
}

void accept(int customer, int factory){
	int f = allocating_list[customer];
	capacity[f] += demand[customer];
	capacity[factory] -= demand[customer];
	allocating_list[customer] = factory;
	open_list[f] -= 1;
	open_list[factory] += 1;
}
int main(){
	int file_num = 0;
	ofstream result("SAresult");
	srand((int)time(0));
	while(file_num != FILE_NUM){
		file_num++;
		string file_name = "Instances/p" + to_string(file_num);	
		ifstream file(file_name);
		if(!file.is_open()){
			cout << "open error" << endl;
		}
		file >> factory_num >> customer_num;
		capacity = new int[factory_num];
		fixed_cost = new int[factory_num];

		for(int i = 0; i < factory_num; i++){
			file >> capacity[i] >> fixed_cost[i];
		}
		demand = new double[customer_num];
		for(int i = 0; i < customer_num; i++){
			file >> demand[i];
		}
		//allocating_cost[i][j] means the cost allocating of 
		//customer j to facity i
		allocating_cost = new double*[factory_num];
		
		for(int i = 0; i < factory_num; i++){
			allocating_cost[i] = new double[customer_num];		
		}
		for(int i = 0; i < factory_num; i++){
			for(int j = 0; j < customer_num; j++){
				file >> allocating_cost[i][j];
			}		
		}

		open_list = new int[factory_num];
		allocating_list = new int[customer_num];
		for(int i = 0; i < factory_num; i++){
			open_list[i] = 0;
		}
		
		//Simulated Annealing
		clock_t start = clock();
		generate_random_solution();
		int repeat = 100;
		int t = T;
		double current_cost = get_total_cost();
		double min_cost = current_cost;
		int time = 0;
		while(t > T_min){
			time++;
			int n = 0;
			while(n != repeat){
				int customer = rand() % customer_num;
				int factory = rand() % factory_num;
				//not valid neibor
				if(capacity[factory] < demand[customer]) continue;
				if(allocating_list[customer] == factory) continue;
				n++;
				int delta = calculate_delta_cost(customer, factory);
				if(delta <= 0){
					accept(customer, factory);
				}else{
					if((rand() % 10000) / 10000.0 < exp(-1.0 * delta / t)){
						accept(customer, factory);
					}
				}
			}			
			//cout << get_total_cost() << endl;
			t = 0.99 * t;		
		}
		clock_t end = clock();		
		//get result
		//string file_name = "result/p" + to_string(file_num);
		result << "p" << file_num << ": ";
		result << get_total_cost() << ' ';
		result << (end - start) * 1.0 / CLOCKS_PER_SEC << "s" << endl;
		
		for(int i = 0; i < factory_num; i++){
			result << open_list[i] << ' ';
		}
		result << endl;
		for(int i = 0; i < customer_num; i++){
			result << allocating_list[i] << ' ';
		}
		result << endl;
		
		//release
		delete capacity;
		delete fixed_cost;
		delete demand;
		delete open_list;
		for(int i = 0; i < factory_num; i++){
			delete allocating_cost[i];
		}
		delete allocating_list;
		delete allocating_cost;

	}

	
}

结果

p1: 8916 0.027765s
7 5 8 7 11 0 7 0 5 0 
2 2 1 6 3 8 2 4 4 1 4 8 3 2 8 3 2 0 6 4 3 8 6 4 2 6 1 6 0 1 2 6 0 3 4 4 4 3 0 4 3 8 1 6 4 0 2 0 4 0 
p2: 7949 0.027256s
8 5 5 8 11 0 5 2 4 2 
8 2 1 6 3 8 2 4 4 1 9 0 3 2 8 3 4 0 9 7 3 4 6 4 2 6 3 1 0 1 2 6 0 3 4 4 4 3 0 4 3 8 1 6 7 0 4 0 4 0 
p3: 9575 0.036489s
8 5 5 7 11 0 7 3 4 0 
8 2 1 6 3 8 2 4 4 1 4 8 3 2 0 3 4 0 6 7 3 7 6 4 2 6 1 6 0 1 2 6 0 3 4 4 4 3 0 4 3 8 1 6 7 0 4 0 4 0 
p4: 11046 0.045844s
7 0 6 8 11 9 0 0 5 4 
2 2 5 5 3 8 2 4 4 5 9 8 3 2 8 3 4 0 9 4 3 8 9 4 2 5 3 5 0 5 2 5 0 3 9 4 4 3 0 4 5 8 3 5 4 0 4 0 4 0 
p5: 9037 0.053169s
6 7 6 6 7 0 5 2 7 4 
8 2 1 6 3 8 2 4 2 1 9 8 3 2 8 3 4 0 9 7 3 8 6 4 2 6 1 1 0 1 2 6 0 3 9 4 4 3 8 4 1 8 1 6 7 0 9 0 4 0 
p6: 7892 0.049795s
7 6 5 5 7 4 3 3 7 3 
8 8 1 6 1 8 2 4 4 1 9 8 0 2 8 3 4 0 9 7 3 8 6 4 2 5 1 5 0 5 2 6 0 3 9 4 7 3 0 4 1 8 1 5 7 0 2 0 4 3 
p7: 9843 0.051843s
6 6 5 5 8 5 3 0 7 5 
8 8 1 6 1 8 2 4 4 1 9 8 3 2 8 3 2 0 9 9 3 2 6 4 5 5 1 5 8 5 2 6 0 3 9 4 4 3 0 4 1 8 1 5 4 0 9 0 4 0 
p8: 11378 0.042351s
6 8 5 6 7 0 5 3 7 3 
8 8 1 6 1 8 2 4 4 1 9 8 3 2 8 3 4 0 9 7 3 8 6 4 2 6 1 1 0 1 2 6 0 3 9 4 4 3 0 4 1 8 1 6 7 0 2 3 7 0 
p9: 8576 0.02834s
7 7 5 6 10 0 5 0 7 3 
8 8 1 6 3 8 2 4 4 1 9 8 3 2 8 3 4 0 9 4 3 8 6 4 2 6 1 1 0 1 2 6 0 3 9 4 4 3 0 4 1 8 1 6 4 0 2 0 4 0 
p10: 7772 0.020728s
7 6 5 5 10 4 3 0 7 3 
8 8 1 6 1 8 2 4 4 1 9 8 3 2 8 3 4 0 9 4 3 8 6 4 2 5 1 5 0 5 2 6 0 3 9 4 4 3 0 2 1 8 1 5 4 0 4 0 4 0 
p11: 9128 0.027357s
10 9 4 0 11 0 6 2 8 0 
8 8 1 6 1 8 2 4 4 1 4 8 0 2 8 0 4 0 6 7 1 8 6 4 2 6 1 1 0 1 2 6 0 0 4 4 4 0 8 4 1 8 1 6 7 0 4 0 4 0 
p12: 10449 0.036066s
7 7 6 6 11 0 6 0 7 0 
8 8 1 6 3 8 2 4 4 1 4 8 3 2 8 3 4 0 6 4 3 8 6 4 2 6 1 1 0 1 2 6 0 3 2 4 4 3 0 4 1 8 1 6 4 0 2 0 4 0 
p13: 8280 0.041783s
5 5 0 0 0 0 0 0 0 5 6 0 0 7 4 6 0 6 0 6 
0 1 10 10 1 13 17 13 14 17 15 19 19 10 13 14 15 10 17 9 14 15 15 19 9 1 0 17 1 17 13 15 13 0 1 10 17 19 19 13 9 0 15 0 9 13 14 10 19 9 
p14: 7169 0.031457s
0 0 0 6 0 0 5 0 0 0 5 0 0 6 3 6 6 6 0 7 
16 3 10 10 19 15 17 13 14 17 15 19 19 6 13 3 15 10 17 6 14 15 15 19 6 17 16 17 3 17 13 15 13 16 3 10 3 19 19 13 6 16 16 16 3 13 14 10 19 6 
p15: 8964 0.032357s
0 0 0 6 0 0 5 0 0 0 5 0 0 7 3 6 5 6 0 7 
16 3 10 10 19 13 17 13 14 17 15 19 19 6 13 3 15 10 17 6 14 15 15 19 6 17 16 17 3 17 13 15 13 16 3 10 3 19 19 13 6 16 15 16 3 13 14 10 19 6 
p16: 11765 0.041187s
5 4 0 6 0 0 0 5 0 0 7 0 0 6 0 6 0 6 0 5 
0 1 10 10 1 15 17 13 7 17 15 19 1 7 13 3 15 10 17 10 15 15 15 19 10 17 7 17 1 17 13 7 13 0 3 10 3 19 19 13 3 0 0 0 3 13 7 10 19 3 
p17: 8455 0.038385s
5 0 0 6 0 0 5 0 0 0 5 0 0 6 3 7 0 6 0 7 
0 3 10 10 19 15 17 13 14 17 15 19 19 6 13 3 15 10 17 6 14 15 15 19 6 17 0 17 3 17 13 15 13 0 3 10 3 19 19 13 6 0 15 0 3 13 14 10 19 6 
p18: 7821 0.033585s
5 4 0 4 0 0 5 0 0 0 6 0 0 6 3 7 0 5 0 5 
0 1 10 10 1 15 17 13 14 17 15 19 1 6 13 3 15 10 17 6 14 15 15 19 6 10 0 17 1 17 13 15 13 0 3 10 3 19 19 13 6 0 15 0 3 13 14 10 19 6 
p19: 9324 0.035205s
5 6 0 0 0 0 6 0 0 0 6 0 0 6 4 6 0 6 0 5 
10 1 10 10 1 15 17 13 14 17 15 19 1 6 13 14 15 10 17 6 14 15 15 19 6 1 0 17 1 17 13 15 13 0 1 10 17 19 19 13 6 0 0 0 6 13 14 10 19 6 
p20: 11997 0.02347s
5 5 0 0 0 6 4 0 3 0 5 0 0 0 5 0 0 6 6 5 
0 1 10 10 1 18 17 18 14 17 5 19 1 6 18 14 5 10 17 6 14 5 5 19 6 17 0 17 1 17 18 14 18 0 1 10 8 19 19 18 6 0 5 0 8 5 14 10 19 8 
p21: 8419 0.038995s
6 7 0 4 0 0 0 0 0 3 7 0 5 7 0 5 0 6 0 0 
0 12 10 10 1 12 17 13 12 17 15 1 1 10 13 3 15 10 17 9 12 15 15 13 9 17 0 17 1 17 13 15 13 0 3 10 3 1 1 13 10 0 0 0 3 13 12 10 1 9 
p22: 7226 0.040295s
0 5 0 0 0 0 0 0 0 4 7 0 0 6 4 7 5 7 0 5 
16 1 10 10 1 15 17 13 14 17 15 19 1 10 13 14 15 10 17 9 14 15 15 19 9 17 16 17 1 17 13 15 13 16 1 10 17 19 19 13 10 16 15 16 9 13 14 10 19 9 
p23: 9105 0.037604s
6 7 0 0 0 0 0 7 0 4 7 0 0 7 0 0 0 7 0 5 
0 1 10 10 1 13 17 13 7 17 7 19 1 10 13 1 7 10 17 9 1 7 7 19 9 17 0 17 1 17 13 7 13 0 1 10 17 19 19 13 10 0 0 0 9 13 7 10 19 9 
p24: 11303 0.041301s
0 5 0 8 0 0 7 8 0 0 0 0 5 6 0 0 6 0 0 5 
16 12 7 7 1 12 3 13 12 3 7 19 1 6 13 3 7 7 1 6 12 7 7 19 6 1 16 3 1 3 13 7 13 16 3 6 3 19 19 13 6 16 16 16 3 13 12 6 19 6 
p25: 13113 0.0407s
12 0 9 0 0 14 2 10 9 0 0 14 0 0 18 0 0 10 0 0 21 0 0 0 22 9 0 0 0 0 
20 25 20 2 20 5 14 24 14 17 24 20 8 20 2 14 14 17 5 11 14 7 24 7 24 20 2 24 5 24 5 25 6 25 20 20 24 24 7 14 0 14 24 14 24 14 7 20 11 8 25 14 14 5 20 20 17 11 0 14 0 5 20 11 11 11 24 0 24 5 7 6 11 0 24 8 24 20 14 24 20 7 20 17 7 17 2 7 20 5 2 24 17 11 17 5 2 7 25 8 20 17 17 25 2 25 7 0 14 8 14 14 2 11 11 11 24 24 24 24 5 8 11 20 20 0 5 24 0 0 0 11 24 25 8 14 0 5 20 17 0 8 20 14 8 11 25 5 2 5 
p26: 11506 0.031927s
17 0 9 0 0 14 0 0 15 5 0 12 0 0 17 0 0 11 0 0 19 0 0 0 18 13 0 0 0 0 
20 11 20 2 8 5 2 24 14 17 9 8 8 20 0 14 14 17 5 11 2 0 5 0 5 8 17 24 24 24 5 25 20 25 20 20 24 24 0 14 0 14 24 8 24 14 0 20 11 8 25 14 14 5 20 20 14 11 11 14 0 5 20 25 11 11 24 0 9 9 8 20 11 0 24 8 9 20 2 9 20 0 20 17 2 17 17 0 20 5 2 24 17 11 0 5 2 14 25 8 8 17 14 25 2 25 0 11 14 8 14 14 17 11 11 25 24 24 24 24 5 8 25 20 20 0 5 24 0 25 0 25 24 24 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p27: 14115 0.025686s
12 0 10 0 0 17 0 7 12 0 0 13 0 0 16 0 0 10 0 0 20 0 0 0 21 10 0 0 2 0 
20 11 20 2 20 5 14 24 14 17 5 8 8 20 7 14 14 17 5 11 2 0 24 7 5 8 2 24 5 24 5 25 20 25 20 20 24 24 7 14 0 14 24 28 24 14 7 20 25 8 11 14 14 5 20 20 2 11 0 14 0 5 20 11 11 11 24 0 24 5 20 20 11 17 24 8 24 20 14 24 20 7 8 17 2 17 17 0 20 5 2 24 17 11 0 24 2 0 11 20 8 17 17 25 2 25 7 11 14 8 14 14 2 11 25 25 24 24 24 24 5 28 25 20 8 0 5 24 0 5 0 25 24 5 8 14 7 5 20 17 0 8 20 14 8 11 25 5 2 5 
p28: 17339 0.039803s
10 0 9 0 0 18 0 7 9 0 0 13 0 5 18 0 0 10 0 0 20 0 0 0 19 7 0 5 0 0 
20 11 13 14 20 5 2 24 14 17 24 8 20 20 7 14 14 17 5 11 2 0 5 2 5 8 2 24 5 24 5 25 13 25 20 20 24 24 0 14 0 14 24 8 24 14 0 13 27 8 5 8 14 5 13 20 17 11 11 14 0 5 20 11 11 25 24 0 11 24 20 13 11 17 24 8 5 20 14 24 20 7 20 17 17 17 2 7 20 5 2 24 17 11 7 5 2 7 27 20 8 17 14 25 14 11 7 0 14 8 14 14 2 11 11 27 24 24 24 24 5 20 25 20 20 27 5 24 0 25 0 27 24 5 14 14 7 5 20 17 0 20 20 14 8 11 25 5 2 5 
p29: 14945 0.039794s
13 0 12 0 0 15 0 0 8 0 0 14 0 6 14 6 3 14 0 0 14 0 0 0 14 9 0 4 4 0 
20 25 13 14 13 5 2 24 14 17 15 16 8 20 0 14 14 17 25 11 2 0 5 2 5 8 2 24 5 15 5 11 16 25 20 20 24 15 0 14 0 14 15 8 24 14 17 13 11 28 25 28 14 5 20 20 17 11 11 14 0 5 20 27 11 11 24 0 5 24 13 13 11 17 24 8 24 20 2 24 20 0 20 17 2 17 17 0 20 5 2 24 17 11 17 5 2 2 25 13 8 17 17 25 2 25 17 11 14 28 14 14 2 11 11 11 24 15 24 24 5 8 25 20 16 0 5 15 0 27 0 11 24 27 8 14 0 5 20 17 0 8 20 14 28 27 25 5 2 5 
p30: 12291 0.030974s
13 0 10 0 0 14 0 0 13 0 0 17 0 7 14 0 0 15 0 0 13 0 0 0 15 15 0 1 3 0 
20 25 13 14 20 5 2 24 14 17 11 8 8 20 2 14 14 17 25 11 2 0 25 17 24 8 2 24 24 25 25 25 13 25 20 20 24 24 0 14 0 8 24 8 24 14 0 13 11 8 25 14 14 5 13 20 17 11 11 14 0 5 20 27 11 11 5 0 24 25 20 20 11 17 24 8 5 20 14 24 13 0 13 17 17 17 17 0 20 25 2 24 0 11 17 5 2 2 25 20 28 17 17 11 2 11 17 11 28 28 14 14 2 11 25 11 24 24 5 5 5 8 11 13 8 0 5 5 0 11 0 11 24 25 8 14 17 5 8 17 0 8 20 14 8 25 25 5 2 5 
p31: 14070 0.040869s
12 0 12 0 0 15 0 0 14 9 0 15 0 8 14 0 0 15 0 0 13 0 0 0 13 10 0 0 0 0 
20 11 13 2 20 5 14 9 14 17 9 8 8 20 2 14 14 17 5 11 2 0 5 2 25 8 2 24 5 9 5 25 13 25 20 20 24 24 0 14 0 14 24 8 24 14 11 20 11 8 5 2 14 5 13 20 17 11 0 14 0 5 20 11 11 11 9 0 9 5 13 13 11 17 24 8 9 20 14 9 13 0 13 17 17 17 17 0 20 5 2 24 17 11 17 9 2 2 25 8 8 17 17 25 2 25 17 11 8 8 14 14 2 11 11 25 24 24 24 24 5 8 25 13 20 0 5 24 0 11 0 11 24 9 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p32: 17270 0.028115s
13 0 9 0 0 14 0 4 14 7 0 13 0 7 14 0 0 16 0 0 13 0 0 0 14 12 0 0 0 0 
20 25 13 14 20 5 2 24 14 17 24 8 8 20 2 14 17 17 25 11 2 0 9 17 5 8 17 24 5 24 5 25 13 25 20 20 24 9 0 14 0 14 24 8 24 14 7 20 11 8 5 2 14 5 13 20 17 0 11 14 0 5 20 11 11 11 24 0 25 9 8 13 11 17 24 8 9 20 14 9 20 7 13 17 17 17 2 7 20 5 0 24 17 11 0 9 2 17 11 13 8 17 17 25 2 25 7 11 14 8 14 14 2 11 11 25 24 24 5 24 5 8 25 13 8 0 5 9 0 25 0 0 24 25 8 14 17 5 20 17 0 8 20 14 8 11 25 5 2 5 
p33: 13280 0.021133s
15 0 11 0 0 17 0 2 13 0 0 12 0 6 15 0 0 14 0 0 15 0 0 0 19 11 0 0 0 0 
20 11 13 14 13 5 2 24 14 17 5 8 8 20 17 14 14 17 25 11 2 0 11 2 5 8 2 24 5 24 5 25 13 25 20 20 24 24 0 14 0 14 24 8 24 14 0 13 25 8 5 14 14 5 20 20 17 11 11 14 0 5 20 11 11 11 5 0 24 24 20 20 11 17 24 8 24 20 2 24 20 0 13 17 17 17 17 0 20 5 2 24 7 0 17 24 2 2 25 13 8 17 17 25 2 25 17 0 14 8 14 14 2 11 25 11 24 24 5 24 5 8 25 20 8 0 5 24 0 0 0 11 24 5 8 14 7 5 20 17 0 8 20 14 8 25 25 5 2 5 
p34: 11959 0.021929s
9 0 8 0 0 18 0 4 13 4 0 15 0 5 16 0 0 16 0 0 17 0 0 0 15 10 0 0 0 0 
20 11 13 2 20 5 2 9 14 17 5 8 8 20 17 14 14 17 25 11 14 17 5 17 5 8 2 24 5 9 5 25 20 25 20 20 24 24 0 14 0 14 24 8 24 14 25 13 11 8 5 14 14 5 20 20 17 11 0 14 0 5 20 11 11 11 9 0 5 5 20 20 11 17 24 8 24 20 14 9 20 0 20 17 17 17 17 7 20 25 2 24 17 11 17 5 2 14 25 13 8 17 17 25 2 25 7 11 8 8 14 14 2 11 11 5 24 24 24 24 5 8 25 13 13 7 5 24 0 11 0 11 24 24 8 14 7 5 20 17 0 8 20 14 8 11 25 5 2 5 
p35: 14540 0.028361s
13 0 12 0 0 15 0 0 12 0 0 10 0 5 14 0 0 15 0 0 17 0 4 0 18 10 0 5 0 0 
13 25 20 2 13 5 2 24 2 17 22 8 8 20 17 14 14 17 5 11 2 0 5 2 22 8 2 24 5 24 5 25 20 25 20 20 24 24 11 14 0 14 24 8 24 14 17 13 27 8 5 14 14 5 20 20 17 27 0 14 0 5 20 27 11 11 24 0 22 24 20 20 11 17 24 8 22 20 14 24 20 0 13 17 17 17 17 0 20 5 2 24 17 11 0 5 2 2 25 20 8 17 17 11 2 25 17 11 14 8 14 14 2 11 11 25 24 24 24 24 5 8 25 13 20 0 5 24 0 27 0 27 24 25 8 14 0 5 20 17 0 8 20 14 8 25 25 5 2 5 
p36: 15852 0.024144s
11 0 12 0 0 18 0 5 14 0 0 10 0 0 15 0 0 15 0 0 19 0 0 0 19 12 0 0 0 0 
20 11 20 2 20 5 2 24 14 17 24 8 8 20 2 14 14 17 5 11 2 7 25 17 5 8 0 24 5 24 25 25 20 25 20 20 24 24 7 14 0 14 24 14 24 14 7 20 11 8 5 14 14 5 20 20 17 25 0 14 0 5 20 11 11 11 24 0 5 5 8 20 5 17 24 8 24 20 14 24 20 17 8 17 2 17 17 0 20 5 2 24 17 11 17 24 2 2 25 8 8 7 17 25 2 25 17 0 14 8 14 2 2 11 11 25 24 24 5 24 5 8 25 20 20 0 5 24 7 0 0 11 24 5 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p37: 13651 0.027567s
9 0 10 0 0 14 0 0 12 0 0 11 0 4 16 3 0 19 0 0 18 0 0 0 18 10 0 6 0 0 
20 25 13 2 13 5 2 24 14 17 25 20 8 20 2 14 14 17 25 11 2 0 5 17 24 8 2 24 5 24 5 25 20 25 20 20 24 15 11 14 0 14 15 14 24 14 27 20 27 8 11 14 14 5 20 20 17 27 11 14 0 5 20 11 0 11 24 0 5 24 20 20 11 17 24 8 24 20 14 24 20 17 13 17 17 17 17 17 20 5 2 24 17 11 17 24 2 8 25 13 8 17 17 11 2 25 17 0 14 8 14 14 2 11 11 25 24 15 24 24 5 8 25 20 8 17 5 24 0 27 0 27 24 5 8 14 17 5 20 17 0 8 20 14 8 27 25 5 2 5 
p38: 11738 0.026482s
9 0 11 0 0 16 0 0 14 0 0 12 0 6 14 0 0 19 0 0 15 0 0 0 20 10 0 4 0 0 
13 11 13 14 20 5 2 24 14 17 5 8 8 20 17 8 14 17 5 11 2 17 5 17 5 8 2 24 5 24 5 25 20 25 20 20 24 24 17 14 0 14 24 8 24 14 17 13 27 8 5 14 14 5 20 20 17 25 0 14 0 5 20 11 11 11 24 0 5 24 20 20 11 17 24 8 24 20 2 24 20 0 13 17 17 17 17 2 20 25 2 24 17 11 17 24 2 14 11 13 8 17 17 11 2 25 17 11 14 8 14 2 2 11 25 25 24 24 24 24 5 8 25 13 8 0 5 24 11 25 0 27 24 27 8 14 0 5 20 17 0 8 20 14 8 27 25 5 2 5 
p39: 14076 0.025329s
12 0 10 0 0 14 0 2 11 4 0 13 0 0 18 0 0 18 0 0 21 0 0 0 19 8 0 0 0 0 
20 11 20 14 20 5 2 9 14 17 24 8 8 20 2 14 14 17 5 11 2 0 24 17 5 8 2 24 5 24 5 25 20 25 20 20 24 24 0 14 0 14 24 14 24 14 0 20 11 8 5 14 14 5 20 20 17 11 7 14 0 5 20 11 0 11 24 0 24 24 20 20 11 17 24 8 24 20 14 24 20 17 20 17 17 17 17 17 20 5 2 9 17 0 17 9 2 2 25 8 20 17 17 25 2 25 17 11 14 14 14 14 2 11 11 0 24 24 24 24 5 8 25 20 8 17 5 9 0 25 0 11 24 11 8 14 7 5 20 17 0 8 20 14 8 11 25 5 2 5 
p40: 15767 0.021328s
14 0 11 0 0 17 0 0 8 0 0 11 0 5 16 0 0 16 0 0 20 0 0 0 19 13 0 0 0 0 
20 11 20 2 13 5 2 24 14 17 5 20 8 20 2 14 14 17 5 11 2 0 5 17 5 8 2 24 5 24 5 25 13 25 20 20 24 24 0 14 0 14 24 8 24 14 0 20 0 8 25 14 14 5 13 20 17 25 0 14 0 5 20 11 11 11 24 0 5 5 20 20 11 17 24 8 24 20 14 24 20 0 20 17 17 17 17 0 20 5 2 24 17 11 17 24 2 2 25 13 20 17 17 25 2 25 17 11 14 14 14 14 2 11 25 0 24 24 24 24 5 20 25 13 20 11 5 24 0 11 0 25 24 25 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p41: 6995 0.024675s
10 0 11 6 11 8 17 11 7 9 
5 6 4 6 7 9 3 7 8 8 4 9 2 6 2 7 7 3 0 6 6 6 4 4 6 5 5 4 8 5 8 0 0 0 3 9 2 6 6 9 2 7 3 3 3 5 0 5 6 4 4 6 6 6 2 7 2 8 8 8 0 0 6 5 0 6 6 6 4 4 0 4 4 0 7 7 2 2 9 5 7 2 2 7 9 7 9 9 9 2 
p42: 7122 0.027451s
0 0 0 7 0 7 4 0 0 0 9 10 7 0 0 11 0 9 8 8 
12 10 11 5 15 18 12 3 17 17 11 18 6 10 6 15 15 17 10 10 5 11 5 11 12 12 11 12 17 3 17 19 6 18 10 10 10 15 15 15 15 3 3 12 11 5 18 19 15 15 17 17 17 3 17 5 12 5 10 5 11 11 3 11 11 3 15 15 19 6 10 18 19 19 19 18 18 18 19 19 
p43: 6458 0.029136s
8 0 0 0 0 7 6 0 0 9 0 0 3 0 0 0 0 0 4 0 0 8 0 11 0 0 0 9 5 0 
18 21 18 23 23 0 9 21 27 5 5 23 23 9 18 6 21 21 12 0 0 9 0 0 9 23 27 6 27 27 5 23 23 23 0 9 23 12 21 6 27 12 28 23 5 9 9 9 0 6 21 0 9 18 6 6 21 21 23 5 5 27 28 5 27 28 27 27 28 28 
p44: 7393 0.026649s
9 8 8 11 10 10 7 12 6 9 
4 4 4 4 4 4 4 4 0 0 0 0 6 0 0 0 1 1 1 7 1 7 1 2 2 2 2 2 7 2 2 3 3 3 3 3 3 3 3 3 4 0 1 1 2 8 7 5 9 7 7 6 5 5 8 8 7 7 9 5 5 5 3 3 0 6 6 8 1 5 4 9 9 7 7 8 6 6 5 8 7 9 9 9 9 9 6 5 7 5 
p45: 7236 0.02323s
10 0 0 9 0 11 9 0 7 6 0 11 6 0 0 0 0 0 7 4 
0 0 0 0 0 0 0 6 6 6 6 6 6 6 6 3 3 3 3 3 3 11 11 12 11 11 11 12 11 5 5 5 5 5 5 5 5 5 0 0 3 3 11 12 18 5 19 3 18 19 8 8 11 19 18 19 5 6 9 9 12 9 0 8 18 8 11 12 9 9 18 12 18 8 11 11 8 8 9 18 
p46: 6767 0.023007s
0 6 10 0 0 0 6 0 5 0 9 0 4 8 6 0 0 3 7 0 0 0 6 0 0 0 0 0 0 0 
10 10 10 10 10 10 10 1 22 22 1 1 1 1 1 2 2 2 2 2 2 6 6 6 6 6 6 13 8 8 8 8 13 8 10 2 2 17 14 22 18 12 2 22 17 14 18 17 13 18 10 13 13 22 2 14 13 18 18 14 12 12 22 18 14 13 14 13 12 18 
p47: 6468 0.03173s
12 5 13 8 12 7 12 9 7 5 
0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 2 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 7 7 6 7 6 0 7 7 7 7 7 7 8 8 6 8 8 8 8 8 6 9 0 2 9 9 9 9 
p48: 5849 0.040644s
12 0 0 6 0 13 0 0 8 6 0 6 0 9 7 0 0 13 0 0 
0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 9 9 5 9 5 5 5 8 8 8 8 8 8 8 9 8 9 9 11 11 11 11 11 11 13 13 13 13 13 13 13 14 14 13 14 13 0 14 14 14 14 17 17 17 17 17 17 17 17 17 17 17 17 17 0 0 
p49: 6476 0.037012s
9 0 6 0 0 5 4 11 0 0 0 0 8 5 0 0 0 7 0 0 0 0 6 0 0 9 0 0 0 0 
0 0 2 2 2 2 2 2 5 5 5 5 5 6 6 6 7 7 7 7 7 7 7 7 7 7 7 12 12 12 13 13 13 6 13 13 17 17 17 17 17 17 12 25 17 12 12 12 22 12 22 25 0 22 22 22 22 25 25 25 25 25 25 25 0 0 0 0 0 0 
p50: 9345 0.027264s
12 8 11 15 9 11 9 13 0 12 
3 6 3 0 2 1 5 5 3 7 7 4 1 9 6 9 9 2 5 3 6 0 0 4 0 0 7 4 4 7 7 7 3 3 3 5 9 9 0 6 0 9 9 1 5 5 5 5 5 3 3 5 6 4 0 0 9 6 1 2 2 7 7 7 3 3 0 4 7 7 3 6 6 0 0 4 4 3 3 4 3 5 2 2 2 2 6 7 2 7 9 1 2 2 1 1 1 9 9 9 
p51: 8204 0.024044s
8 8 0 0 0 16 9 0 0 0 7 0 10 15 5 10 0 0 0 12 
15 6 19 10 12 12 5 5 15 1 5 14 6 13 6 13 12 5 5 15 0 0 10 14 14 14 1 19 19 15 1 1 15 19 15 5 13 13 10 0 0 13 13 13 12 5 5 5 5 19 15 5 0 14 10 10 6 6 13 12 13 5 1 5 15 15 10 19 1 1 15 0 0 0 10 19 19 19 19 19 19 5 12 12 13 13 6 5 5 1 13 12 12 6 13 13 6 13 12 6 
p52: 9236 0.028758s
0 0 0 20 15 15 18 16 8 8 
7 7 7 7 7 7 7 7 3 4 4 4 4 4 4 4 4 3 3 8 8 3 8 8 8 9 9 9 9 9 9 9 9 5 6 6 6 6 6 6 6 6 6 6 7 7 4 8 8 5 5 3 4 6 7 5 3 3 3 4 6 5 5 3 3 3 5 7 4 7 6 6 4 3 3 5 3 4 7 6 6 3 8 5 5 3 3 7 5 3 5 5 6 5 5 6 3 4 3 7 
p53: 9408 0.030053s
0 6 0 11 0 12 8 9 0 10 0 0 7 6 0 15 0 0 16 0 
5 5 5 5 5 5 5 5 1 7 7 7 1 7 7 7 7 12 13 12 12 13 12 12 3 9 9 9 9 9 15 9 9 15 18 18 18 18 18 18 18 18 18 18 5 5 7 12 12 15 15 3 7 18 6 15 3 3 1 6 18 9 15 13 3 13 15 18 6 5 9 18 6 3 3 15 3 6 6 13 18 1 13 15 15 3 1 6 15 3 15 15 9 15 15 18 1 6 3 5 
p54: 9289 0.031193s
11 0 15 19 9 6 17 8 8 7 
7 7 7 7 7 7 7 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 2 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 6 6 8 8 6 8 8 8 8 8 8 6 3 6 6 6 6 6 6 6 6 6 5 5 6 5 5 5 6 6 0 0 6 0 5 7 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 9 4 9 9 9 2 9 9 9 
p55: 9249 0.026301s
9 0 0 0 8 0 15 14 6 8 4 0 0 6 6 10 0 0 14 0 
18 18 4 18 4 4 4 4 4 8 4 8 4 8 18 8 8 6 8 6 14 6 14 14 6 14 14 6 6 6 6 14 6 6 6 6 6 6 6 7 10 7 0 7 0 0 0 0 0 0 0 0 7 7 7 7 10 7 7 7 7 9 13 7 9 7 10 7 10 9 13 9 9 13 18 13 9 13 9 9 13 15 15 15 15 15 15 15 15 15 15 18 18 18 18 18 18 18 18 18 
p56: 22598 0.029667s
8 0 8 7 13 11 7 7 0 9 10 7 7 8 4 0 8 4 7 12 11 10 4 0 9 8 0 9 12 0 
18 19 21 27 2 12 21 27 22 28 4 28 13 13 28 18 3 20 22 0 18 16 5 24 10 18 27 14 4 2 19 19 4 16 27 6 20 9 24 16 18 9 6 4 20 19 13 21 19 14 24 16 24 16 20 6 11 9 18 7 4 0 7 20 13 11 5 14 28 25 18 12 19 9 5 10 20 5 20 16 10 0 9 25 4 13 6 5 27 7 28 6 25 25 2 3 28 6 0 28 28 21 25 7 4 0 4 24 22 3 19 4 27 12 12 20 28 7 17 20 9 11 17 19 9 16 2 11 19 17 28 24 25 20 5 9 3 3 28 10 12 22 11 11 25 5 24 21 27 25 24 17 10 0 13 11 2 16 3 13 13 27 10 24 5 27 5 4 3 21 5 20 19 14 4 2 0 10 4 10 5 21 2 19 12 9 28 10 0 21 2 21 6 4 7 12 7 21 10 19 
p57: 29956 0.024212s
9 0 7 0 12 8 8 0 13 0 7 13 9 14 3 0 8 9 0 14 5 10 6 6 9 13 5 12 0 0 
27 19 21 27 2 12 21 27 22 17 4 19 13 13 19 11 13 20 22 0 27 16 5 24 10 27 27 19 4 2 19 19 4 16 27 6 20 8 24 16 25 8 6 4 8 19 13 21 19 14 24 16 24 16 8 6 12 8 22 25 4 0 25 8 13 11 5 14 19 25 22 12 6 8 5 23 20 23 8 16 10 0 26 25 4 13 19 5 27 25 17 6 25 25 0 13 11 6 0 17 17 21 12 11 4 0 4 24 22 13 19 4 27 12 12 8 11 25 17 8 26 11 17 19 26 16 2 11 26 17 11 24 11 20 23 8 13 13 17 10 12 22 11 11 25 5 24 21 27 25 24 17 23 0 8 11 2 16 13 13 13 27 10 24 23 27 5 4 13 21 5 20 19 14 26 2 0 10 4 10 5 21 2 6 12 8 11 23 0 21 2 21 6 4 25 12 25 21 10 19 
p58: 44019 0.0257s
11 0 12 7 13 11 0 5 14 0 0 8 11 10 7 0 15 3 7 13 0 0 4 10 0 9 6 12 12 0 
18 19 2 27 2 12 2 27 22 28 4 28 13 13 28 27 3 13 22 0 18 16 5 0 23 18 27 19 4 5 19 19 4 16 27 12 14 8 27 16 18 8 12 4 8 26 13 16 19 14 0 16 2 16 8 12 11 8 18 25 4 0 7 8 13 11 5 14 28 25 18 12 19 8 23 23 13 23 8 16 23 0 26 25 4 13 4 5 27 7 28 19 25 25 2 3 11 12 0 28 28 16 25 18 4 0 4 27 22 3 19 4 27 12 12 8 28 7 17 8 26 11 28 19 26 16 5 11 26 17 28 2 25 13 23 8 3 3 28 14 12 22 11 11 25 5 16 16 27 25 0 17 23 0 8 11 5 16 3 13 13 27 23 2 5 27 5 4 3 16 5 8 19 14 26 2 0 14 4 14 5 2 2 19 12 8 28 23 0 16 2 16 19 4 7 12 7 2 23 19 
p59: 33436 0.023092s
7 0 8 8 0 8 8 0 0 14 10 9 6 6 7 6 0 4 9 13 0 10 0 7 12 13 0 13 11 11 
18 19 21 27 2 11 15 27 27 28 29 28 23 3 28 18 3 10 24 27 18 21 5 24 10 18 27 14 29 2 19 19 19 21 27 6 14 9 24 15 18 9 6 29 9 19 13 21 19 14 24 24 24 21 9 6 11 9 18 25 29 0 18 9 13 11 5 14 28 25 18 12 19 9 23 23 10 23 9 24 10 0 9 25 29 13 6 5 27 25 28 6 25 25 2 3 11 6 0 28 28 15 25 18 29 0 29 24 27 3 19 29 27 12 12 9 28 25 17 9 14 11 17 19 9 21 2 11 19 17 28 24 25 10 23 9 3 3 28 14 12 27 11 11 25 5 24 15 27 25 24 17 23 0 13 11 2 15 3 13 13 27 10 24 5 27 5 29 3 21 5 10 19 14 29 2 0 10 29 10 5 21 2 19 12 9 28 23 0 21 2 21 6 6 25 12 25 15 10 19 
p60: 23326 0.022809s
10 0 11 6 7 7 8 6 12 0 8 8 7 8 0 4 9 5 8 11 7 8 4 6 0 8 6 11 11 4 
18 19 21 27 2 12 15 27 22 28 4 28 13 13 19 18 3 20 22 0 18 16 5 0 10 18 27 28 29 2 19 19 4 16 27 6 20 8 16 16 18 8 6 26 8 19 13 21 19 20 0 16 2 16 8 6 11 8 18 7 29 0 7 8 13 11 5 17 28 25 18 12 19 8 23 23 20 23 8 16 10 0 26 25 29 13 6 2 27 7 28 6 25 25 2 3 11 6 0 28 28 15 25 18 4 0 4 27 22 3 19 4 27 12 12 8 28 7 17 8 26 11 17 19 26 16 2 11 26 17 28 21 25 20 23 20 3 3 28 10 12 22 11 11 25 5 16 15 27 25 27 17 23 0 8 11 2 15 13 13 13 27 10 2 5 27 5 4 3 21 5 20 19 10 26 2 0 10 29 10 5 21 2 6 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p61: 29336 0.02241s
7 0 8 0 10 8 7 0 13 0 9 7 8 14 0 0 9 6 9 12 5 9 0 6 9 13 7 13 11 0 
18 19 21 27 2 12 21 27 27 28 4 28 13 13 28 18 13 20 27 0 18 16 5 24 10 18 27 19 4 2 19 19 4 16 27 6 20 8 24 16 18 8 6 26 8 19 13 21 19 20 24 16 24 16 8 6 11 8 18 25 19 0 18 8 13 11 5 17 28 25 18 12 19 8 23 23 20 23 8 16 10 0 26 25 4 13 6 5 27 25 28 6 25 25 2 13 11 6 17 28 28 21 25 18 4 0 4 24 27 13 26 4 27 12 12 8 28 25 17 8 26 11 17 19 26 16 2 11 26 17 28 24 25 10 23 8 13 13 28 10 12 27 12 11 25 5 24 16 27 25 24 17 23 0 8 11 2 16 13 13 13 27 10 24 5 27 5 4 13 21 5 20 19 10 26 2 0 10 4 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 25 12 25 21 10 19 
p62: 42170 0.022819s
10 0 8 0 0 7 0 0 13 6 8 8 11 0 0 0 8 0 9 17 11 10 0 12 11 14 14 11 12 0 
18 19 21 27 2 12 21 27 18 28 26 28 20 23 28 18 23 20 27 24 18 16 5 24 10 18 27 19 26 2 19 19 26 16 27 12 20 8 24 16 18 9 12 26 8 19 20 21 19 20 24 16 24 16 8 12 11 9 18 25 26 0 25 8 20 11 23 19 28 25 18 12 19 9 23 23 20 23 8 16 10 0 9 25 26 10 19 5 27 25 28 19 25 25 2 8 11 12 0 28 28 21 25 18 26 0 26 24 24 8 19 26 27 12 12 8 28 25 0 8 9 11 28 19 26 16 2 11 26 0 28 24 25 20 23 9 23 8 28 10 12 27 11 11 25 5 24 21 27 25 24 0 23 0 8 11 2 16 8 20 23 27 10 24 5 27 5 26 23 21 5 20 19 10 26 2 0 10 26 20 5 21 2 19 12 8 28 23 0 21 2 21 19 19 25 12 25 21 10 19 
p63: 30281 0.023375s
8 0 11 0 12 0 7 0 11 0 7 0 9 14 0 0 9 5 9 12 8 9 0 12 9 17 5 13 13 0 
18 19 21 27 2 12 21 27 27 28 4 28 13 13 28 18 13 20 27 0 18 16 23 24 10 18 27 19 4 2 19 19 4 16 27 6 20 8 24 16 18 8 6 4 8 19 13 21 19 20 24 16 24 16 8 6 25 8 18 25 4 0 18 8 13 25 23 17 28 25 18 12 19 20 23 23 20 23 8 16 23 0 26 25 4 13 6 2 27 25 28 6 25 25 2 13 28 6 0 28 28 21 25 18 4 0 4 24 27 13 19 4 27 12 12 8 28 25 17 8 26 25 17 19 26 16 2 12 26 17 28 24 25 20 23 20 13 13 28 10 12 27 12 25 25 2 24 16 27 25 24 17 23 0 8 28 2 16 13 13 13 27 10 24 23 27 23 4 13 21 23 20 19 10 26 2 0 10 4 10 2 21 2 19 12 8 28 23 0 21 2 21 6 4 25 12 25 21 10 19 
p64: 22837 0.023797s
8 0 9 6 8 11 7 0 10 5 13 9 7 8 5 0 8 4 9 11 0 9 4 0 9 12 4 9 11 4 
18 19 2 27 2 12 21 27 22 28 4 28 13 13 28 18 13 10 22 0 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 14 8 24 16 18 9 6 4 8 19 13 21 19 14 24 16 24 16 8 6 11 9 18 25 29 0 18 8 13 11 5 14 28 25 18 12 19 9 5 10 10 5 8 16 10 0 9 25 29 13 6 5 27 25 28 6 11 25 2 3 11 6 0 28 28 21 25 18 4 0 4 24 22 3 19 4 27 12 12 8 28 25 17 8 26 11 17 19 26 16 2 11 26 17 28 24 25 10 5 9 3 3 28 10 12 22 11 11 25 5 24 21 27 25 24 17 10 0 8 11 2 16 3 13 13 27 10 24 5 27 5 4 3 21 5 8 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 10 0 21 2 21 6 4 25 12 25 21 10 19 
p65: 28885 0.024375s
11 0 11 0 9 0 8 10 9 7 9 7 8 14 0 0 8 0 0 13 5 10 5 11 9 8 0 11 13 4 
7 19 21 27 2 12 21 27 22 28 4 28 13 13 19 7 13 20 22 0 27 16 23 24 10 27 27 19 29 2 19 19 4 16 27 6 20 8 24 16 7 9 6 4 8 19 13 21 19 20 24 16 24 16 8 6 11 9 22 25 29 0 7 8 13 11 23 28 28 25 7 12 19 9 23 23 20 23 8 16 10 0 9 25 29 13 6 2 27 7 28 6 25 25 2 13 28 6 0 28 28 21 12 7 4 0 4 24 22 13 19 4 27 12 12 8 28 7 0 8 9 25 28 19 9 16 2 11 19 0 28 24 11 10 23 9 13 13 28 10 12 22 11 11 25 2 24 21 27 25 24 0 23 0 8 11 2 16 13 13 13 27 10 24 23 27 23 4 13 21 23 20 19 10 4 2 0 10 29 10 2 21 2 6 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p66: 41820 0.022734s
8 0 14 0 12 0 0 10 14 5 20 8 11 0 0 0 0 4 0 16 11 16 5 0 11 9 4 11 11 0 
7 19 21 27 2 12 21 27 22 28 4 28 20 10 28 7 10 20 22 0 27 21 2 24 10 27 27 19 4 2 19 19 4 21 27 12 20 8 24 21 7 9 12 4 8 19 8 21 19 20 24 24 24 21 20 12 11 9 22 25 4 0 7 8 20 11 2 19 28 25 7 12 19 9 10 10 20 10 8 24 10 0 9 25 4 10 19 2 27 7 28 19 25 25 2 8 11 12 0 28 28 21 25 7 4 0 4 24 22 8 19 4 27 12 12 8 28 7 17 8 26 11 17 19 26 21 2 11 26 17 28 24 25 20 10 9 8 20 28 10 12 22 11 11 25 2 24 21 27 25 24 17 10 0 8 11 2 21 8 20 10 27 10 24 10 27 2 4 8 21 10 20 19 10 26 2 0 10 4 10 2 21 2 19 12 8 28 10 0 21 2 21 19 4 7 12 7 21 10 19 
p67: 31928 0.023798s
0 0 12 6 15 8 7 5 12 0 7 0 9 8 4 11 0 8 10 13 7 0 0 6 16 11 0 13 12 0 
18 19 2 24 2 12 15 27 27 28 4 28 13 13 28 18 3 20 27 27 18 24 5 24 10 18 27 19 4 2 19 19 4 15 27 6 20 8 24 15 18 8 6 4 8 19 13 2 19 14 24 24 24 24 8 6 18 8 18 25 4 2 7 8 13 12 5 14 28 25 18 12 19 20 23 23 20 23 8 24 10 17 8 25 4 13 4 5 27 7 28 6 25 25 2 3 27 6 17 28 28 15 25 18 4 24 4 24 27 13 19 4 27 12 12 8 28 7 17 8 14 25 17 19 4 15 2 12 19 17 28 24 25 20 23 20 3 3 28 10 12 18 6 25 25 5 24 15 27 25 24 17 23 17 8 28 2 15 3 13 13 27 10 24 5 27 5 4 3 15 5 20 19 14 4 2 24 10 4 10 5 15 2 19 12 8 28 23 17 2 2 15 6 4 7 12 7 15 10 19 
p68: 23250 0.024028s
9 0 11 7 8 6 6 6 9 5 8 8 8 7 0 0 8 3 9 13 6 10 0 6 8 8 4 12 11 4 
18 19 21 27 2 12 21 27 27 28 4 28 13 13 28 18 3 20 27 0 18 16 5 24 10 18 27 19 29 2 19 19 4 16 27 6 20 8 24 16 18 9 12 4 8 19 13 21 19 20 24 16 2 16 8 6 11 9 18 7 29 0 7 8 13 11 5 19 28 25 18 12 6 9 23 23 20 23 8 16 10 0 9 25 29 13 19 2 27 7 28 6 25 25 2 3 28 6 0 28 28 21 25 18 4 0 4 24 18 3 19 4 27 12 12 8 28 7 17 8 26 11 17 19 26 16 2 11 26 0 11 24 25 20 23 9 3 3 28 10 12 27 11 11 25 2 24 21 27 25 24 17 23 0 8 11 2 16 3 13 13 27 10 24 5 27 5 4 3 21 5 20 19 10 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p69: 31113 0.025707s
9 0 10 0 8 7 8 10 17 0 10 8 7 0 3 6 6 3 0 12 7 5 5 11 9 9 5 11 10 4 
7 19 2 27 2 12 15 27 22 28 4 28 10 23 19 7 23 20 22 0 27 16 5 24 10 27 27 19 29 2 19 19 4 16 27 6 20 8 24 15 7 8 6 4 8 19 8 21 19 14 24 16 24 16 8 6 11 8 22 25 29 0 7 8 20 11 5 14 28 25 7 12 19 8 23 23 20 23 8 16 10 0 26 25 29 10 6 2 27 7 28 6 25 25 2 8 11 6 0 28 28 15 25 7 4 0 4 24 22 8 19 4 27 12 12 8 28 7 17 8 26 11 17 19 26 16 2 11 26 0 28 24 11 20 23 20 23 8 28 10 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 8 10 23 27 10 24 5 27 5 4 23 21 5 20 19 14 26 2 0 10 29 10 5 21 2 6 12 8 28 23 0 21 2 21 6 4 7 12 7 15 10 19 
p70: 42229 0.029573s
0 0 8 12 13 8 12 0 0 8 8 11 0 0 5 0 7 9 9 11 11 10 0 8 12 14 0 13 11 0 
18 19 21 27 2 6 21 27 18 28 4 28 10 3 28 18 3 20 27 27 18 16 5 24 10 18 27 19 4 2 19 19 4 16 27 6 20 9 24 16 18 9 6 4 20 19 3 21 19 14 24 16 24 16 20 6 11 9 18 25 4 17 25 20 3 11 5 14 28 25 18 6 6 9 23 23 20 23 20 24 23 17 9 25 4 10 6 5 27 25 28 6 25 25 2 3 11 6 17 28 28 21 25 18 4 24 4 24 27 3 19 4 27 6 11 20 28 25 17 20 14 11 17 19 9 16 2 11 14 17 28 24 25 20 23 9 3 3 28 10 11 27 11 11 25 5 24 21 27 25 24 17 23 17 3 11 2 16 3 3 23 27 10 24 5 27 5 4 3 21 5 20 19 14 4 2 24 10 4 10 5 21 2 19 11 9 28 23 17 21 2 21 6 4 25 6 25 21 10 19 
p71: 29922 0.024978s
0 0 11 0 10 7 8 0 0 0 7 0 9 14 4 0 9 7 10 12 19 10 0 6 11 16 0 13 13 4 
18 19 21 27 2 12 21 27 27 28 4 28 13 13 28 18 13 20 27 27 18 16 5 24 10 18 27 19 29 2 19 19 4 16 27 6 20 20 24 16 18 20 6 4 20 19 13 21 19 14 24 16 24 16 20 6 18 20 18 25 29 2 18 20 13 25 5 14 28 25 18 12 6 20 23 23 20 23 20 16 10 2 20 25 29 13 6 2 27 25 28 6 25 25 2 13 28 6 17 28 28 21 25 18 4 24 4 24 16 13 19 4 27 12 12 20 28 25 17 20 14 25 17 19 4 16 2 12 19 17 28 24 25 20 23 20 13 13 28 10 12 27 12 25 25 5 24 21 27 25 24 17 23 17 20 28 2 16 13 13 13 27 10 24 5 27 5 4 13 21 5 20 19 14 4 2 24 10 29 10 5 21 2 19 12 20 28 23 17 21 2 21 6 4 25 12 25 21 10 19 

解决方案二:禁忌搜索法

算法描述

  1. 给定算法参数,随机产生初始解S,置禁忌表为空。
  2. 判断算法终止条件是否满足,若是,则结束算法,输出最优解,否则继续以下步骤。
  3. 利用当前解的领域函数产生所有领域解,并从中确定若干候选解。
  4. 对候选解判断是否能特赦准则,若成立,则用这个解S’替代S为新的当前解,并把S’放进禁忌表,然后更新禁忌表,然后进入步骤2,否则进入步骤5。
  5. 判断候选解对应的各对象的禁忌属性,选择候选解中非禁忌对象对应的最佳状态S’为新的当前解,并把S’放进禁忌表,然后更新禁忌表,进行步骤2。

流程图

在这里插入图片描述

领域解和候选解

跟前面的一样,把所有的领域解当成候选解,最多有factory_num * customer_num - 1种可能。

禁忌操作

当使用了某个解时,在一段时间内不能再恢复。即把customer i 从 factory 1 分配给 factory 2后,在一段时间内不能把customer i 从 factory 2 分配给factory 1。禁忌表用一个二维数组结构来存,记录着每个操作禁忌的迭代次数。

禁忌表的长度

如果禁忌表长度过小,那么搜索过程就可能进入死循环,整个搜索将围绕着相同的几个解徘徊;相反,如果禁忌表长度过大,那它将在相当大的程度上限制了搜索区域,好的解就有可能被跳过,同时,不会改进解的效果而增加算法运算时间。禁忌表的长度为 n \sqrt{n} n ,n为领域解的大小。

停止准则

要有停止的准则才能终止算法,这里设为一定次数之后,最优解没有更新。

特赦准则

某个解在禁忌表中,但如果它能产生比历史最优解更好的解时,就依然能使用这个解。

中期记忆与集中搜索(Intensification)

如果当前搜索出现了比较好的解,则进一步对当前区域进行更集中的搜索,这样可以发现更多更好的解。采用的策略是,如果最好的解被更新,就把禁忌表清空。

完整代码

#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<cmath>
using namespace std;
#define FILE_NUM 71
#define INT_MAX 10000

int factory_num;
int customer_num;
int* origin_capactity;
int* capacity;
int* fixed_cost;
double* demand;
double** allocating_cost;

int** tabu_list;
int** frequence;

// how many customer to allocate
int* open_list;
// witch factory to allocate
int* allocating_list;



double get_total_cost(){
	double cost = 0;

	for(int i = 0; i < factory_num; i++){
		if(open_list[i] != 0){
			cost += fixed_cost[i];
		}
	}
	for(int i = 0; i < customer_num; i++){
		cost += allocating_cost[allocating_list[i]][i];
	}
	return cost;
}

void generate_random_solution(){
	for(int i = 0; i < customer_num; i++){
		while(true){
			int allocated = rand() % factory_num;
			if(capacity[allocated] >= demand[i]){
				open_list[allocated] += 1;
				allocating_list[i] = allocated;
				capacity[allocated] -= demand[i];
				break;
			}
		}
		
	}
}

void update_tabu_list(){
	for(int i = 0; i < factory_num; i++){
		for(int j = 0; j < customer_num; j++){
			if(tabu_list[i][j] > 0){
				tabu_list[i][j]--;
			}
		}
	}
}


double calculate_delta_cost(int customer, int factory){
	int result = 0;
	//open new factory
	if(open_list[factory] == 0){
		result += fixed_cost[factory];
	}
	int f = allocating_list[customer];
	if(open_list[f] == 1){
		result -= fixed_cost[f];
	}
	result += allocating_cost[factory][customer] - allocating_cost[f][customer];
	return result;

}

void accept(int customer, int factory){
	int f = allocating_list[customer];
	capacity[f] += demand[customer];
	capacity[factory] -= demand[customer];
	allocating_list[customer] = factory;
	open_list[f] -= 1;
	open_list[factory] += 1;
}

void clear_tabu_list(){
	for(int i = 0; i < factory_num; i++){
		for(int j = 0; j < customer_num; j++){
			tabu_list[i][j] = 0;
		}
	}
}

int main(){
	int file_num = 0;
	ofstream result("TABUresult");
	srand((int)time(0));
	while(file_num != FILE_NUM){
		file_num++;
		string file_name = "Instances/p" + to_string(file_num);	
		ifstream file(file_name);
		if(!file.is_open()){
			cout << "open error" << endl;
			return -1;
		}
		file >> factory_num >> customer_num;
		capacity = new int[factory_num];
		origin_capactity = new int[factory_num];
		fixed_cost = new int[factory_num];

		for(int i = 0; i < factory_num; i++){
			file >> capacity[i] >> fixed_cost[i];
			origin_capactity[i] = capacity[i];
		}

		demand = new double[customer_num];
		for(int i = 0; i < customer_num; i++){
			file >> demand[i];
		}

		//allocating_cost[i][j] means the cost allocating of 
		//customer j to facity i
		allocating_cost = new double*[factory_num];
		
		for(int i = 0; i < factory_num; i++){
			allocating_cost[i] = new double[customer_num];		
		}
		for(int i = 0; i < factory_num; i++){
			for(int j = 0; j < customer_num; j++){
				file >> allocating_cost[i][j];
			}		
		}

		open_list = new int[factory_num];
		allocating_list = new int[customer_num];
		for(int i = 0; i < factory_num; i++){
			open_list[i] = 0;
		}

		tabu_list = new int*[factory_num];
		frequence = new int*[factory_num];
		for(int i = 0; i < factory_num; i++){
			tabu_list[i] = new int[customer_num];
			frequence[i] = new int[customer_num];
		}
		for(int i = 0; i < factory_num; i++){
			for(int j = 0; j < customer_num; j++){
				tabu_list[i][j] = 0;
				frequence[i][j] = 0;
			}
		}

		//tabu
		clock_t start = clock();
		generate_random_solution();	
		int best_ever = get_total_cost();
		int best_current = get_total_cost();
		int neibor_num = customer_num * factory_num - 1;
		int len = (int)sqrt(neibor_num);
		int repeat = 0;

		while(repeat <= customer_num){
			//generate neibor

			int best_in_neibor = INT_MAX;
			int factory = factory_num;
			int customer = customer_num;
			int f = factory_num;
			int c = customer_num;
			for(int i = 0; i < customer_num; i++){
				for(int j = 0; j < factory_num; j++){
					//invalid solution
					if(capacity[j] < demand[i]) continue;
					if(allocating_list[i] == j) continue;
					int delta = calculate_delta_cost(i, j);
					//find the best in neibor
					if(delta < best_in_neibor && tabu_list[j][i] == 0){
						best_in_neibor = delta;
						factory = j;
						customer = i;
					}else if(best_current + delta < best_ever){
						//best_ever = best_current + delta;
						f = j;
						c = i;
					}

				}
			}
			update_tabu_list();
			if(f != factory_num){
				//aspiration		
				clear_tabu_list();		
				int old_factory = allocating_list[customer];
				tabu_list[old_factory][c] = len;
				frequence[f][c]++;
				accept(c, f);
				best_current = get_total_cost();
				best_ever = best_current;
				//cout << "aspiration" << endl;
				repeat = 0;
			}else if(best_in_neibor != INT_MAX){
				//select the best in the neibor
				int old_factory = allocating_list[customer];
				tabu_list[old_factory][customer] = len;
				frequence[factory][customer]++;
				accept(customer, factory);
				best_current = get_total_cost();
				if(best_current < best_ever){
					repeat = 0;
					best_ever = best_current;
					clear_tabu_list();
					tabu_list[old_factory][customer] = len;
				} 			

			}			
			repeat++;
		}
		//get result
		clock_t end = clock();
		result << "p" << file_num << ": ";
		result << best_ever << ' ';
		result << (end - start) * 1.0 / CLOCKS_PER_SEC << "s" << endl;		
		for(int i = 0; i < factory_num; i++){
			result << open_list[i] << ' ';
		}
		result << endl;
		for(int i = 0; i < customer_num; i++){
			result << allocating_list[i] << ' ';
		}
		result << endl;
		

		
		//release
		delete capacity;
		delete fixed_cost;
		delete demand;
		delete open_list;
		for(int i = 0; i < factory_num; i++){
			delete allocating_cost[i];
		}
		delete allocating_list;
		delete allocating_cost;

	}
	result.close();

	
}

结果

p1: 9324 0.001898s
7 5 7 6 9 3 4 2 5 2 
0 2 1 6 3 8 2 4 4 1 9 8 3 2 8 3 4 0 9 7 3 2 6 4 2 5 1 5 8 1 2 6 0 3 4 4 4 3 0 4 5 8 1 6 7 0 2 0 4 0 
p2: 8010 0.001979s
9 5 3 5 8 4 4 4 5 3 
7 0 1 6 3 8 2 4 4 1 9 8 0 2 8 3 4 0 9 7 3 8 6 4 5 5 1 5 0 1 2 6 0 3 4 4 4 3 0 4 5 8 1 6 7 0 9 0 7 0 
p3: 10010 0.001769s
9 5 3 5 8 4 4 4 5 3 
7 0 1 6 3 8 2 4 4 1 9 8 0 2 8 3 4 0 9 7 3 8 6 4 5 5 1 5 0 1 2 6 0 3 4 4 4 3 0 4 5 8 1 6 7 0 9 0 7 0 
p4: 11483 0.001665s
8 0 8 7 10 6 0 2 5 4 
0 4 5 2 3 8 2 4 4 5 9 8 0 2 8 3 4 0 9 7 3 2 9 4 2 5 3 5 8 5 2 9 0 3 4 4 4 3 0 4 2 8 3 5 7 0 2 0 4 0 
p5: 9204 0.001943s
6 7 6 7 6 0 5 4 6 3 
8 8 1 6 3 8 2 4 2 1 9 8 3 2 8 3 2 0 9 7 1 7 6 4 2 6 1 1 0 1 2 6 0 3 4 4 4 3 0 4 3 8 1 6 7 0 9 3 7 0 
p6: 7809 0.001827s
7 7 5 7 7 0 5 2 6 4 
8 8 1 6 3 8 2 4 2 1 9 8 0 2 8 3 4 0 9 7 1 2 6 4 1 6 3 1 8 1 2 6 0 3 9 4 4 3 0 4 3 0 1 6 7 0 9 3 4 0 
p7: 9609 0.002642s
7 6 5 6 8 0 5 3 6 4 
8 0 1 6 1 8 2 4 4 1 9 8 0 2 8 3 4 0 9 7 1 4 9 4 2 6 1 6 0 1 2 6 0 3 9 4 7 3 8 4 3 0 3 6 7 8 2 3 4 0 
p8: 11409 0.001986s
7 7 5 7 7 0 5 2 6 4 
8 8 1 6 3 8 2 4 2 1 9 8 0 2 8 3 4 0 9 7 1 2 6 4 1 6 3 1 8 1 2 6 0 3 9 4 4 3 0 4 3 0 1 6 7 0 9 3 4 0 
p9: 8847 0.00171s
9 7 5 6 9 0 5 2 5 2 
8 0 1 6 3 8 2 4 4 1 9 8 0 2 8 3 4 0 9 7 3 2 6 4 1 6 1 1 0 1 2 6 0 3 4 4 4 3 0 4 3 8 1 6 7 0 4 0 2 0 
p10: 7855 0.001259s
8 6 6 4 8 6 0 2 7 3 
8 8 1 2 1 8 2 4 4 1 9 8 0 2 8 3 4 0 9 7 3 8 9 4 1 5 1 5 0 5 2 5 0 3 4 4 4 3 0 4 5 8 1 5 7 0 2 0 2 0 
p11: 9448 0.001916s
9 7 5 6 9 0 5 2 5 2 
8 0 1 6 3 8 2 4 4 1 9 8 0 2 8 3 4 0 9 7 3 2 6 4 1 6 1 1 0 1 2 6 0 3 4 4 4 3 0 4 3 8 1 6 7 0 4 0 2 0 
p12: 10817 0.001376s
8 7 7 5 9 0 6 2 6 0 
8 0 1 6 3 8 2 4 4 1 4 8 0 2 8 3 4 0 6 7 3 2 6 4 1 6 1 1 8 1 2 6 0 3 4 4 4 3 0 4 2 8 1 6 7 0 2 0 2 0 
p13: 8840 0.003711s
0 3 0 0 0 5 0 0 0 5 6 3 0 6 5 0 5 6 0 6 
16 17 10 10 19 1 17 13 14 17 16 19 1 10 13 9 5 10 17 9 14 5 14 19 9 11 16 17 1 17 13 5 13 16 11 10 11 19 19 13 14 5 5 16 9 13 14 10 19 9 
p14: 7510 0.005134s
0 0 0 0 0 0 3 0 0 2 5 2 0 5 6 6 6 6 0 9 
16 14 10 10 19 19 17 13 14 17 15 19 19 6 13 14 15 10 19 9 14 15 15 19 6 17 16 17 14 17 13 16 13 16 17 10 11 19 19 13 6 16 15 16 11 15 14 10 19 9 
p15: 9859 0.004145s
0 0 0 0 4 0 4 0 0 0 6 6 5 5 0 7 6 0 0 7 
16 12 10 10 19 15 11 13 15 4 15 4 19 6 13 11 15 10 4 6 12 15 15 19 6 19 16 11 12 4 13 10 13 16 11 10 11 19 19 13 12 16 16 16 11 15 12 10 19 6 
p16: 12247 0.005167s
0 0 0 4 0 2 4 0 3 0 5 0 4 0 0 5 5 6 7 5 
16 3 10 10 12 18 17 18 8 17 15 19 19 6 18 3 15 10 17 6 12 15 15 19 6 17 16 17 12 17 18 15 18 16 3 10 3 18 19 18 6 16 5 16 8 5 12 10 19 8 
p17: 8517 0.006122s
0 5 0 0 0 0 4 0 2 2 5 0 4 6 0 6 5 6 0 5 
16 12 10 10 1 13 17 13 6 17 15 19 1 6 13 12 15 10 17 9 12 15 15 19 6 17 16 17 1 17 13 12 19 16 1 10 8 1 19 13 6 16 15 16 8 13 15 10 19 9 
p18: 8198 0.004017s
0 4 5 0 0 3 4 3 0 2 3 4 0 0 0 6 5 6 2 3 
16 1 10 10 1 18 17 18 15 17 15 19 1 6 2 11 15 7 17 9 15 15 7 2 6 17 16 17 1 17 2 7 2 16 11 10 11 19 19 5 6 16 5 16 11 5 15 6 2 9 
p19: 9626 0.005439s
0 0 6 5 0 0 4 0 0 0 6 0 0 0 3 7 5 7 0 7 
16 3 10 10 17 2 17 2 14 17 15 19 19 6 2 3 15 10 17 10 14 15 15 19 6 19 16 3 17 17 2 15 2 16 3 10 3 19 19 2 6 16 15 16 17 15 14 10 19 6 
p20: 12442 0.004016s
0 0 0 6 3 3 5 5 0 0 4 2 5 6 0 0 5 0 0 6 
16 3 10 10 12 12 3 13 7 4 7 4 19 6 13 12 5 7 4 6 12 5 7 19 6 19 16 3 3 3 13 7 13 16 3 10 11 19 19 13 6 16 5 16 11 13 12 10 19 6 
p21: 8749 0.004007s
0 0 0 0 0 0 0 0 0 4 6 2 2 6 6 5 6 7 0 6 
16 12 10 10 12 13 17 13 14 17 15 19 19 10 13 14 15 10 17 9 14 15 15 19 9 17 16 17 14 17 13 14 13 16 17 10 11 19 19 13 9 16 16 16 11 15 14 10 19 9 
p22: 7706 0.003843s
0 0 0 7 4 0 3 4 0 3 4 0 0 5 4 4 4 0 0 8 
16 3 10 10 19 19 3 13 14 4 7 4 19 6 13 3 15 14 4 9 14 15 7 19 6 19 16 3 3 4 13 7 13 16 3 10 3 19 19 13 6 16 7 15 9 15 14 10 19 9 
p23: 9541 0.005277s
0 0 0 4 0 0 3 0 0 3 5 0 0 6 3 4 7 7 2 6 
16 3 10 10 13 18 17 13 14 17 15 19 19 6 13 3 15 10 17 9 14 15 15 19 6 17 16 17 3 17 13 16 13 16 3 10 17 19 19 13 6 16 16 16 9 18 14 10 19 9 
p24: 11298 0.005883s
0 0 0 8 4 0 0 5 0 2 7 0 0 6 0 6 5 0 0 7 
16 3 10 10 19 15 3 13 7 3 15 4 19 10 13 3 15 7 4 9 7 15 15 19 10 19 16 4 3 4 13 7 13 16 3 10 3 19 19 13 10 16 15 16 3 13 7 10 19 9 
p25: 13448 0.079611s
10 0 9 0 0 16 0 8 12 0 0 14 0 6 17 2 0 11 0 0 16 0 0 0 20 9 0 0 0 0 
20 11 13 14 13 5 2 24 14 17 24 8 8 20 2 14 14 0 5 11 14 7 5 17 5 8 2 24 5 24 5 25 13 25 20 20 24 15 0 14 0 14 15 13 24 14 11 20 11 8 5 14 14 5 20 20 17 0 11 14 0 5 20 11 11 11 24 0 5 24 13 20 11 0 24 8 24 20 14 24 20 7 20 17 2 17 17 7 20 5 2 24 17 11 17 24 2 25 25 8 8 17 17 25 2 25 7 11 14 8 14 14 2 11 11 7 24 24 24 24 5 8 25 13 20 7 5 24 7 0 0 11 24 24 8 14 7 5 20 17 0 8 20 14 8 25 25 5 2 5 
p26: 12259 0.07608s
16 0 9 3 0 10 0 0 12 0 0 14 0 4 16 2 0 10 0 0 18 0 0 0 20 10 0 0 0 6 
20 11 13 2 20 5 2 24 14 0 24 8 8 20 3 14 14 17 25 11 14 0 29 3 29 8 2 24 5 24 25 25 20 25 20 20 24 15 0 14 0 14 15 13 24 14 3 20 11 8 29 14 14 5 20 20 17 29 11 14 0 5 20 11 11 11 24 0 25 24 20 20 11 17 24 8 24 20 14 24 20 0 13 0 2 17 17 0 20 5 2 24 17 11 17 24 2 29 25 8 8 17 17 25 2 29 0 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 0 5 24 0 11 0 11 24 24 8 14 0 5 20 17 0 8 20 14 8 25 25 5 2 5 
p27: 13514 0.100328s
17 0 10 0 0 18 0 0 12 0 0 17 0 0 18 2 0 10 0 0 21 0 0 0 16 9 0 0 0 0 
20 11 20 14 20 5 2 24 14 17 5 20 8 20 0 14 14 0 5 11 2 11 11 0 25 8 2 24 5 24 5 25 20 25 20 20 24 15 25 14 0 14 15 14 24 14 11 20 11 8 5 14 14 5 20 20 17 0 0 14 0 5 20 11 11 11 24 0 0 5 20 20 11 17 24 8 24 20 14 24 20 0 20 17 2 17 2 0 20 5 2 24 17 11 17 5 2 14 11 8 8 17 17 25 2 25 0 11 14 8 14 14 2 11 11 5 24 24 24 24 5 8 25 20 8 11 5 24 0 5 0 0 24 11 8 14 0 5 20 17 0 8 20 14 8 25 25 5 2 5 
p28: 17181 0.080334s
19 0 9 0 0 11 0 0 12 0 0 13 0 6 17 2 0 10 0 0 17 0 0 0 19 9 0 0 0 6 
20 11 20 14 20 5 2 24 14 0 24 8 8 20 2 14 14 17 25 11 14 0 29 0 29 8 2 24 5 24 29 25 13 25 20 20 24 15 0 14 0 14 15 13 24 14 0 20 11 8 29 14 14 5 13 20 17 29 0 14 0 5 20 11 11 11 24 0 25 24 20 20 11 17 24 8 24 20 14 24 20 0 13 0 2 17 17 0 20 5 2 24 17 11 17 5 2 13 25 8 8 17 17 25 2 29 0 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 0 5 24 0 11 0 11 24 24 8 14 0 5 20 17 0 8 20 14 8 25 25 5 2 5 
p29: 14742 0.075452s
9 0 9 0 0 15 0 4 10 0 0 15 0 8 14 2 0 16 0 0 14 0 6 0 14 8 0 0 4 2 
20 11 13 2 13 5 2 24 28 17 22 20 8 20 0 14 14 17 5 11 2 7 5 17 5 8 2 24 5 24 29 25 13 25 20 20 24 15 0 14 0 14 15 28 24 14 0 13 11 8 5 14 14 5 13 20 17 25 11 14 0 5 20 11 11 11 22 0 5 22 13 20 11 17 24 8 22 20 14 24 20 7 13 17 17 17 17 7 20 5 2 24 17 11 17 22 2 14 25 8 8 17 17 25 2 29 7 11 28 28 14 14 2 11 11 11 24 24 24 24 5 8 25 13 20 17 5 24 0 11 0 11 24 22 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p30: 11879 0.076014s
15 0 11 0 0 15 0 0 11 8 0 13 0 8 14 0 0 15 0 0 13 0 0 0 14 10 0 0 3 0 
20 11 13 2 13 5 2 24 14 17 9 8 8 20 2 14 14 17 5 11 2 0 9 17 9 8 2 24 5 9 5 25 20 25 20 20 24 24 0 14 0 14 24 28 24 14 11 20 11 8 25 14 14 5 13 20 17 0 0 14 0 5 20 11 11 11 9 0 5 5 13 13 11 17 24 8 24 20 14 9 20 0 13 17 17 17 2 17 20 5 2 24 17 11 17 5 2 25 25 8 8 17 17 25 2 25 0 11 28 28 14 14 2 11 11 0 24 24 24 24 5 8 25 13 13 11 5 9 0 0 0 0 24 9 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p31: 15916 0.070015s
8 0 9 0 0 15 0 6 10 5 0 15 0 8 14 2 0 16 0 0 15 0 0 0 14 8 0 0 3 2 
20 11 13 2 20 5 2 24 28 17 9 20 8 20 0 14 14 17 5 11 2 7 9 17 5 8 2 24 5 24 29 25 13 25 20 20 24 15 7 14 0 14 15 8 24 14 7 13 11 8 5 14 14 5 13 20 17 25 0 14 0 5 20 11 11 11 9 0 5 24 20 13 11 17 24 8 9 20 14 24 20 7 13 17 17 17 17 7 20 5 2 24 17 11 17 5 2 14 25 13 8 17 17 25 2 29 7 11 28 28 14 14 2 11 11 11 24 24 24 24 5 8 25 13 20 17 5 9 0 11 0 11 24 11 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p32: 17903 0.096698s
13 0 13 0 0 15 3 0 15 7 0 14 0 0 14 2 0 15 0 0 14 0 0 0 14 8 0 0 3 0 
8 11 8 2 20 5 2 24 14 17 5 8 8 8 2 14 14 17 5 11 2 0 9 2 9 8 2 24 5 9 5 25 6 25 20 20 24 15 0 14 0 14 15 28 24 14 0 20 11 8 5 14 14 5 6 20 17 0 11 14 0 5 20 11 11 11 9 0 24 9 20 6 11 17 24 8 9 20 14 24 20 0 20 17 2 17 2 17 20 5 2 24 17 11 17 5 2 17 25 8 8 17 17 25 2 25 17 11 28 28 14 14 2 11 11 0 24 24 24 24 5 8 25 20 8 11 5 9 0 11 0 0 24 24 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p33: 12990 0.0991s
12 0 8 0 0 15 0 0 13 0 0 15 0 6 16 2 0 18 0 0 16 0 0 0 19 10 0 0 0 0 
20 11 20 14 13 5 2 24 14 17 24 8 8 20 17 14 14 17 5 11 2 17 5 17 5 8 2 24 5 24 5 25 13 25 20 20 24 15 11 14 0 14 15 13 24 14 11 20 11 8 25 14 14 5 13 20 17 0 0 14 0 5 20 11 11 11 24 0 5 24 13 20 11 17 24 8 24 20 14 24 20 0 20 17 17 17 17 0 20 5 2 24 17 11 17 24 2 8 25 8 8 17 17 25 2 25 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 11 5 24 0 11 0 0 24 25 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p34: 11535 0.093005s
11 0 9 0 0 15 0 0 13 0 0 17 0 6 16 2 0 17 0 0 16 0 0 0 19 9 0 0 0 0 
20 11 20 14 13 5 2 24 14 17 24 8 8 20 17 14 14 17 5 11 2 17 5 2 5 8 2 24 5 24 5 25 20 25 20 20 24 15 11 14 0 14 15 13 24 14 11 13 11 8 25 14 14 5 20 20 17 0 0 14 0 5 20 11 11 11 24 0 24 24 13 20 11 17 24 8 24 20 14 24 20 0 13 17 17 17 17 0 20 5 2 24 17 11 17 5 2 8 25 8 8 17 17 25 2 25 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 11 5 24 0 11 0 11 24 11 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p35: 13935 0.085017s
12 0 8 0 0 15 0 0 13 0 0 15 0 5 16 2 0 18 0 0 17 0 0 0 19 10 0 0 0 0 
20 11 20 14 13 5 2 24 14 17 24 8 8 20 17 14 14 17 5 11 2 17 5 17 5 8 2 24 5 24 5 25 20 25 20 20 24 15 11 14 0 14 15 13 24 14 11 20 11 8 25 14 14 5 13 20 17 0 0 14 0 5 20 11 11 11 24 0 5 24 13 20 11 17 24 8 24 20 14 24 20 0 20 17 17 17 17 0 20 5 2 24 17 11 17 24 2 8 25 8 8 17 17 25 2 25 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 11 5 24 0 11 0 0 24 25 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p36: 16335 0.091079s
10 0 9 0 0 15 0 0 13 0 0 18 0 7 16 2 0 17 0 0 15 0 0 0 19 9 0 0 0 0 
13 11 13 14 13 5 2 24 14 17 24 8 8 20 17 14 14 17 5 11 2 17 5 2 5 8 2 24 5 24 5 25 20 25 20 20 24 15 11 14 0 14 15 13 24 14 11 20 11 8 25 14 14 5 20 20 17 0 11 14 0 5 20 11 11 11 24 0 24 24 13 20 11 17 24 8 24 20 14 24 20 0 13 17 17 17 17 0 20 5 2 24 17 11 17 5 2 8 25 8 8 17 17 25 2 25 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 11 5 24 0 11 0 11 24 11 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p37: 12794 0.077094s
9 0 10 0 0 13 0 0 12 0 0 16 0 0 16 3 0 18 0 0 21 0 0 0 18 9 0 0 0 5 
20 11 20 2 20 5 2 24 14 17 24 8 8 20 17 14 14 17 25 11 2 17 29 17 29 8 2 24 5 24 25 25 20 25 20 20 24 15 11 14 0 14 15 14 24 14 11 20 11 8 29 14 14 5 20 20 17 29 0 14 0 5 20 11 11 11 24 0 15 5 20 20 11 17 24 8 24 20 14 24 20 0 20 17 2 17 17 17 20 5 2 24 17 11 17 5 2 5 25 20 8 17 17 25 2 29 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 20 8 11 5 24 0 11 0 11 24 24 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p38: 11535 0.086758s
11 0 8 0 0 14 0 0 13 0 0 16 0 5 16 2 0 18 0 0 17 0 0 0 21 9 0 0 0 0 
20 11 20 14 13 5 2 24 14 17 24 8 8 20 17 14 14 17 5 11 2 17 5 17 5 8 2 24 5 24 5 25 20 25 20 20 24 15 11 14 0 14 15 13 24 14 11 20 11 8 25 14 14 5 13 20 17 0 11 14 0 5 20 11 11 11 24 0 24 24 13 20 11 17 24 8 24 20 14 24 20 0 20 17 17 17 17 0 20 5 2 24 17 11 17 24 2 8 25 8 8 17 17 25 2 25 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 11 5 24 0 11 0 0 24 24 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p39: 13935 0.08725s
11 0 8 0 0 14 0 0 13 0 0 16 0 6 16 2 0 18 0 0 16 0 0 0 21 9 0 0 0 0 
20 11 13 14 13 5 2 24 14 17 24 8 8 20 17 14 14 17 5 11 2 17 5 17 5 8 2 24 5 24 5 25 13 25 20 20 24 15 11 14 0 14 15 13 24 14 11 20 11 8 25 14 14 5 20 20 17 0 11 14 0 5 20 11 11 11 24 0 24 24 13 20 11 17 24 8 24 20 14 24 20 0 20 17 17 17 17 0 20 5 2 24 17 11 17 24 2 8 25 8 8 17 17 25 2 25 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 11 5 24 0 11 0 0 24 24 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p40: 16335 0.089179s
12 0 8 0 0 16 0 0 13 0 0 15 0 7 16 2 0 18 0 0 15 0 0 0 19 9 0 0 0 0 
20 11 13 14 13 5 2 24 14 17 24 8 8 20 17 14 14 17 5 11 2 17 5 17 5 8 2 24 5 24 5 25 20 25 20 20 24 15 11 14 0 14 15 13 24 14 11 20 11 8 25 14 14 5 13 20 17 0 0 14 0 5 20 11 11 11 24 0 5 24 13 20 11 17 24 8 24 20 14 24 20 0 13 17 17 17 17 0 20 5 2 24 17 11 17 5 2 8 25 8 8 17 17 25 2 25 17 11 14 8 14 14 2 11 11 0 24 24 24 24 5 8 25 13 20 11 5 24 0 11 0 0 24 24 8 14 17 5 20 17 0 8 20 14 8 25 25 5 2 5 
p41: 7108 0.004083s
10 5 8 8 9 8 12 15 6 9 
5 6 4 6 7 9 7 7 8 3 4 5 2 6 2 7 7 3 8 6 6 1 4 1 4 5 5 4 8 5 8 0 0 0 3 9 2 6 6 2 2 7 3 3 3 5 0 7 5 4 1 6 6 6 7 7 7 8 8 3 0 0 1 5 0 6 6 1 4 4 0 0 4 0 3 7 2 2 9 7 7 2 7 7 9 9 9 9 9 9 
p42: 8679 0.009184s
6 3 2 5 0 4 4 2 0 0 4 9 3 4 7 0 6 2 8 11 
12 10 11 5 0 18 16 13 16 1 11 18 6 10 6 19 16 2 14 14 5 11 5 3 12 12 11 16 17 13 7 19 6 18 14 10 10 0 0 1 1 11 3 16 11 14 18 19 0 19 16 17 7 13 13 5 2 14 14 14 11 11 3 3 11 3 0 0 19 6 18 18 19 19 19 18 18 19 19 19 
p43: 7381 0.015727s
0 6 0 0 0 5 8 5 0 4 0 4 0 7 0 0 0 5 0 6 0 3 0 0 0 0 3 10 0 4 
27 19 11 1 13 17 9 21 27 27 5 1 13 9 6 6 21 11 7 7 7 26 19 17 17 13 27 6 29 6 5 13 13 13 19 9 7 1 21 11 6 27 27 1 5 26 26 17 17 11 19 7 9 6 6 6 19 19 13 29 5 27 1 29 1 27 27 27 29 5 
p44: 7145 0.003925s
8 7 9 9 10 5 13 14 5 10 
4 4 4 4 4 4 4 4 6 0 6 0 6 0 0 0 1 7 1 6 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 0 1 1 2 8 6 7 9 7 6 6 4 7 9 8 7 7 9 5 7 5 9 9 0 6 6 8 6 0 5 7 9 7 7 8 6 6 5 8 7 9 9 9 7 9 6 7 7 5 
p45: 8309 0.013726s
10 0 9 0 8 0 6 3 0 0 4 0 5 3 7 5 9 6 5 0 
0 0 0 0 0 0 0 15 6 6 15 6 6 6 6 2 2 2 2 2 2 4 4 4 4 4 4 4 4 14 16 14 14 16 16 16 14 16 0 0 2 2 17 12 18 16 18 7 15 16 7 13 17 16 18 0 14 15 10 10 12 2 15 16 18 13 12 12 7 10 18 12 17 17 14 17 17 14 10 13 
p46: 7661 0.017156s
0 6 8 0 0 0 0 0 5 3 0 0 3 4 5 4 0 0 0 0 0 0 5 0 10 0 0 4 3 10 
29 29 29 29 29 29 29 1 1 22 1 22 1 1 22 2 2 2 2 2 2 24 24 24 24 24 24 8 8 9 8 8 9 9 29 2 2 14 24 28 29 12 15 1 24 14 14 13 13 28 29 27 8 22 24 27 13 28 12 24 15 15 22 27 14 27 14 13 15 12 
p47: 6322 0.005021s
10 6 15 9 11 8 10 8 7 6 
0 0 0 0 2 6 0 0 2 0 1 1 1 2 1 1 1 2 2 2 2 2 2 2 2 3 2 3 3 3 3 3 3 3 3 5 2 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 2 2 7 7 6 7 6 0 7 7 7 7 7 6 8 8 4 8 8 8 8 8 9 9 9 0 0 9 9 9 
p48: 7851 0.011462s
9 5 0 0 5 7 0 7 9 0 4 2 5 5 7 0 2 6 2 5 
0 0 0 0 0 1 1 1 0 0 4 5 1 0 1 4 4 4 5 5 5 5 5 5 7 7 7 7 7 7 7 12 4 8 8 8 8 8 8 8 8 8 10 10 11 10 11 10 13 13 12 13 13 12 13 14 14 12 14 12 0 14 14 14 14 16 16 17 17 17 17 17 17 18 18 19 19 19 19 19 
p49: 10341 0.013913s
0 0 0 2 0 8 0 0 0 0 6 2 3 3 0 5 3 3 4 0 6 2 2 2 2 2 3 2 5 5 
29 28 29 29 5 29 5 5 3 5 3 5 5 15 20 5 15 20 5 10 10 10 10 10 11 11 10 12 13 12 12 13 13 15 15 15 16 17 17 16 17 16 20 20 18 20 18 20 21 18 21 18 28 22 23 23 22 24 24 26 25 26 25 26 27 27 28 29 28 28 
p50: 9645 0.006502s
13 8 11 19 5 14 10 9 0 11 
3 6 4 0 2 9 5 5 3 7 5 4 1 2 0 2 9 5 5 7 6 0 0 0 0 4 5 3 3 3 7 7 3 3 3 5 1 2 0 6 0 9 1 1 2 5 5 5 5 3 3 5 6 0 0 0 6 6 9 2 9 7 7 5 3 3 0 4 3 7 3 6 6 6 0 3 3 3 3 4 3 5 2 2 2 2 6 7 2 7 9 1 9 1 1 9 1 9 9 9 
p51: 9248 0.020551s
8 7 0 2 0 13 5 0 0 0 7 0 6 15 7 9 4 0 7 10 
15 6 19 10 12 12 5 16 15 1 5 14 18 13 6 13 12 16 5 15 0 0 10 14 14 14 6 10 19 15 1 1 19 19 15 5 18 13 10 0 0 13 13 13 16 5 5 5 5 19 15 5 14 14 14 10 6 0 13 12 13 5 1 5 15 15 10 3 1 1 15 0 0 0 10 19 19 19 19 3 19 5 16 12 13 13 6 5 12 1 13 18 18 18 18 13 13 18 13 13 
p52: 9786 0.008403s
0 0 0 19 19 16 16 12 9 9 
7 7 7 7 7 7 7 7 3 4 4 4 3 4 4 4 4 8 3 8 8 3 3 8 8 6 5 9 9 9 5 5 9 9 6 6 6 6 6 6 6 6 6 6 7 7 4 8 8 5 5 3 4 6 4 5 3 3 3 4 6 9 9 8 4 3 5 6 4 7 9 6 4 3 3 5 3 4 4 5 3 3 4 5 5 3 3 4 5 8 5 5 5 6 5 9 3 4 3 7 
p53: 9736 0.022247s
0 5 0 10 0 12 8 10 0 10 0 0 6 6 0 13 0 4 16 0 
5 5 5 5 5 5 5 5 1 7 7 7 7 7 7 7 7 12 13 13 12 13 12 13 12 15 15 9 9 9 9 9 9 15 18 18 18 18 18 18 18 18 18 18 5 5 7 12 12 9 15 3 6 18 6 15 3 3 1 6 18 15 15 13 1 15 9 18 3 5 17 18 6 3 3 15 3 6 6 3 18 6 13 15 15 3 1 6 15 18 15 17 9 17 9 17 1 7 3 5 
p54: 9545 0.004936s
11 6 13 13 11 6 17 8 8 7 
7 7 7 7 7 2 7 2 7 2 2 2 2 2 2 2 2 2 2 1 1 2 1 3 3 1 1 3 3 1 3 3 3 3 3 3 3 3 3 6 8 6 8 8 6 8 8 6 8 6 8 8 6 6 6 6 6 6 6 6 6 5 5 6 5 6 5 6 5 0 0 0 0 5 7 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 9 4 9 4 9 9 9 9 9 
p55: 9831 0.018889s
8 0 0 0 9 0 16 14 0 6 0 8 2 5 5 10 0 0 17 0 
18 18 4 4 18 4 4 4 4 4 4 18 18 18 4 18 6 6 6 14 6 6 6 14 12 14 12 6 6 6 6 14 14 6 6 6 6 6 6 7 7 7 0 7 7 0 0 0 0 0 0 0 7 7 7 7 7 7 7 7 11 11 13 11 13 11 11 7 11 9 9 11 9 11 18 13 9 13 9 9 13 15 15 15 15 15 15 15 15 15 15 18 18 18 18 18 18 18 18 18 
p56: 23560 0.101612s
8 0 10 8 7 9 7 5 9 5 6 8 9 3 5 4 6 3 7 10 5 6 5 8 8 9 4 9 12 5 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 29 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 25 4 0 7 8 13 11 5 14 28 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 12 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 2 10 19 
p57: 31400 0.095312s
8 0 9 8 9 10 0 6 8 5 6 7 11 3 4 4 6 4 8 13 6 6 0 8 9 8 4 13 13 4 
18 19 2 27 2 12 15 27 27 28 4 28 23 23 28 18 3 20 24 27 18 16 5 24 10 18 27 19 29 5 19 19 4 16 27 12 20 8 24 21 18 9 12 4 8 19 3 21 19 14 24 16 24 16 8 12 11 9 18 7 4 0 7 20 13 11 5 14 28 25 7 12 19 9 23 23 20 5 8 16 23 0 9 25 29 20 4 2 27 7 28 19 25 25 5 3 27 12 0 28 28 15 11 18 4 0 4 24 18 3 19 29 27 12 12 8 28 25 17 8 26 11 17 19 26 16 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 27 28 25 25 5 24 15 27 25 24 17 23 0 8 28 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 28 12 8 28 23 0 21 2 21 19 4 7 12 7 2 10 19 
p58: 52560 0.100661s
8 0 10 8 7 9 7 6 9 5 6 8 9 3 5 4 6 3 7 10 5 6 5 8 8 8 4 9 12 5 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 29 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 14 28 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 12 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 2 10 19 
p59: 37423 0.098905s
9 0 8 8 7 7 7 6 9 6 7 7 9 4 0 5 6 3 7 12 6 8 4 8 8 8 3 10 13 5 
18 19 2 27 2 12 15 27 22 28 4 28 23 3 28 18 3 20 22 27 18 16 5 24 10 18 27 19 29 15 19 19 4 16 27 6 20 8 24 21 18 9 6 29 8 19 13 21 19 0 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 19 28 25 7 12 6 9 23 23 20 23 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 0 3 28 12 0 28 28 15 12 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 9 11 28 19 26 16 2 11 26 17 28 24 11 10 23 9 3 3 28 10 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 21 5 27 5 4 3 21 5 20 19 20 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p60: 23882 0.114702s
8 4 10 6 8 9 7 6 9 5 6 8 9 3 5 4 6 3 7 11 5 6 5 6 8 8 4 9 11 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 1 28 18 1 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 4 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 14 19 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 5 9 3 3 28 14 12 22 12 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 1 21 1 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 2 10 19 
p61: 31853 0.120613s
8 0 9 8 8 9 7 6 9 5 6 9 8 3 5 5 0 3 7 11 5 9 6 8 10 8 4 9 11 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 24 5 24 10 18 27 14 29 2 19 19 4 21 27 6 20 8 24 15 18 9 6 4 8 19 3 21 19 14 24 22 24 21 8 6 11 9 18 7 4 0 7 8 13 11 5 14 19 25 7 12 6 9 23 23 20 5 8 24 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 21 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p62: 52560 0.112531s
8 0 9 8 8 9 7 5 9 5 6 9 8 3 5 4 6 3 7 11 5 7 5 8 8 9 4 9 11 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 4 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 25 4 0 7 8 13 11 5 14 19 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p63: 38116 0.112081s
8 0 9 8 8 9 7 6 9 5 6 9 8 3 5 4 6 3 7 11 5 7 5 8 8 8 4 9 11 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 4 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 14 19 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p64: 23560 0.114875s
8 0 9 8 8 9 7 6 9 5 6 9 8 3 5 4 6 3 7 11 5 7 5 8 8 8 4 9 11 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 4 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 14 19 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p65: 32260 0.123201s
8 0 9 8 8 9 7 6 9 5 6 9 8 3 5 4 6 3 7 11 5 7 5 8 8 8 4 9 11 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 4 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 14 19 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p66: 53882 0.107492s
8 4 10 6 8 9 7 6 9 5 6 8 9 3 5 4 6 3 7 11 5 6 5 6 8 8 4 9 11 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 1 28 18 1 20 22 27 18 16 5 24 10 18 27 14 29 2 19 19 4 16 27 6 20 8 24 21 18 9 6 4 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 14 19 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 5 9 3 3 28 14 12 22 12 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 1 21 1 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 2 10 19 
p67: 36872 0.106884s
9 0 9 7 7 7 7 6 10 7 14 4 10 6 0 4 6 5 8 12 0 7 4 6 10 8 4 9 10 4 
18 19 2 24 2 12 15 27 22 28 4 28 10 13 19 18 3 10 22 0 18 16 5 24 10 18 27 17 29 2 19 6 4 16 27 6 8 8 24 15 18 9 6 26 8 19 13 21 19 10 24 16 24 16 8 6 18 9 18 7 4 0 7 8 13 12 5 10 19 25 7 12 6 9 23 23 10 10 8 24 23 0 9 25 29 13 19 2 27 7 28 6 25 25 0 3 27 12 0 28 28 15 12 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 9 11 17 19 26 16 2 11 26 17 28 24 11 10 23 9 3 3 28 10 12 22 28 25 25 5 24 16 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 21 5 27 5 4 3 21 5 8 19 10 26 2 0 10 29 10 5 21 2 19 12 9 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p68: 23882 0.112131s
8 4 8 6 8 9 7 6 9 5 6 7 10 3 5 5 6 3 7 10 5 7 5 6 8 8 4 9 12 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 1 28 18 1 20 22 27 18 16 5 24 10 18 27 14 29 15 19 19 4 16 27 6 20 8 24 21 18 9 6 4 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 8 13 11 5 14 28 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 12 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 16 2 11 26 17 11 24 11 10 5 9 3 3 28 14 12 22 12 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 1 21 1 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p69: 31682 0.100377s
8 0 8 9 8 9 7 6 8 7 6 7 10 3 5 5 6 3 7 11 6 7 5 7 8 8 0 9 12 5 
18 19 2 22 2 12 15 27 22 28 4 28 23 3 28 18 3 20 22 27 18 16 5 24 10 18 27 14 29 15 19 19 4 16 27 6 20 8 24 21 18 9 6 29 8 19 3 21 19 14 24 16 24 16 8 6 11 9 18 7 4 0 7 20 13 11 5 14 28 25 7 12 6 9 23 23 20 5 8 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 12 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 19 11 28 19 9 16 2 11 9 17 11 24 11 10 23 9 3 3 28 14 12 22 12 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 4 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p70: 51531 0.097615s
8 4 9 6 8 7 7 6 0 8 7 6 10 5 0 4 6 4 7 11 12 7 4 6 9 8 3 10 14 4 
18 19 2 27 2 12 15 27 22 28 4 28 20 1 28 18 1 20 22 27 18 16 5 24 10 18 27 19 29 2 19 19 4 16 27 6 20 20 24 21 18 9 6 4 3 19 13 21 19 28 24 16 24 16 20 6 11 9 18 7 4 0 7 20 13 11 5 19 28 25 7 12 6 9 23 23 20 23 20 16 23 0 9 25 29 20 6 2 27 7 28 6 25 25 0 3 28 12 0 28 28 15 12 18 4 0 4 24 22 3 19 29 27 12 12 9 28 25 17 20 9 11 17 19 26 16 2 11 26 17 28 24 11 10 5 9 3 3 28 10 12 22 12 25 25 5 24 15 27 25 24 17 23 0 13 11 2 15 3 13 13 27 10 24 5 27 5 4 1 21 1 20 19 20 26 2 0 10 29 10 5 21 2 28 12 9 28 23 0 21 2 21 6 4 7 12 7 21 10 19 
p71: 37534 0.104833s
8 0 10 8 8 9 7 6 9 5 6 9 8 3 5 5 0 3 7 10 5 8 6 8 10 8 4 9 12 4 
18 19 2 22 2 12 15 27 22 28 4 28 23 23 28 18 3 20 22 27 18 24 5 24 10 18 27 14 29 2 19 19 4 21 27 6 20 8 24 15 18 9 6 4 8 19 3 21 19 14 24 22 24 21 8 6 11 9 18 7 4 0 7 8 13 11 5 14 28 25 7 12 6 9 23 23 20 5 8 24 23 0 9 25 29 20 6 2 27 7 28 6 25 25 5 3 28 12 0 28 28 15 11 18 4 0 4 24 22 3 19 29 27 12 12 8 28 25 17 8 26 11 28 19 26 21 2 11 26 17 11 24 11 10 23 9 3 3 28 14 12 22 11 25 25 5 24 15 27 25 24 17 23 0 8 11 2 15 3 13 13 27 10 0 5 27 5 4 3 21 5 20 19 14 26 2 0 10 29 10 5 21 2 19 12 8 28 23 0 21 2 21 6 4 7 12 7 2 10 19 

改进

禁忌搜索表现得不太好,改进的方案是引入长期记忆分散搜索(Diversification)。如果在当前搜索区域进行了一定次数的搜索不能发现更好的解,就要采用长期记忆,从新的解开始搜索。在长期记忆中,频率起着非常重要的作用,使用频率的目的就是通过了解同样的选择在过去做了多少次来重新指导局部选择。当在非禁忌移动中找不到可以改进的解时用长期记忆更有效。

两种方案的对比

两种方法都是在局部搜索的基础上改进的,都能接受差解。模拟退火以一定的概率接受差解,而禁忌搜索当解被禁时,就不得不接受差解中最好的解。采用这样的方式,可以跳出局部最优。
可以看出,模拟退火法比基本的禁忌搜索法的表现要好,用时更短。可能是我禁忌搜索的一些策略没用好。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Here is a basic implementation of CVRP in Python using the Google OR-Tools library: ```python from ortools.constraint_solver import routing_enums_pb2 from ortools.constraint_solver import pywrapcp def create_data_model(): """Stores the data for the problem.""" data = {} data['distance_matrix'] = [ [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502], [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594], [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278], [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514], [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400], [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 810], [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1016], [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468], [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810], [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 650], [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878], [502, 594, 1278, 514, 400, 810, 1016, 468, 810, 650, 878, 0] ] data['num_vehicles'] = 3 data['vehicle_capacities'] = [100, 100, 100] data['depot'] = 0 return data def print_solution(data, manager, routing, solution): """Prints solution on console.""" total_distance = 0 total_load = 0 for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) plan_output = 'Route for vehicle {}:\n'.format(vehicle_id) route_distance = 0 route_load = 0 while not routing.IsEnd(index): node_index = manager.IndexToNode(index) route_load += data['demands'][node_index] plan_output += ' {} Load({}) -> '.format(node_index, route_load) previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( previous_index, index, vehicle_id) plan_output += ' {} Load({})\n'.format(manager.IndexToNode(index), route_load) plan_output += 'Distance of the route: {}m\n'.format(route_distance) plan_output += 'Load of the route: {}\n'.format(route_load) print(plan_output) total_distance += route_distance total_load += route_load print('Total distance of all routes: {}m'.format(total_distance)) print('Total load of all routes: {}'.format(total_load)) def main(): """Entry point of the program.""" data = create_data_model() manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['depot']) routing = pywrapcp.RoutingModel(manager) def distance_callback(from_index, to_index): """Returns the distance between the two nodes.""" from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) return data['distance_matrix'][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) dimension_name = 'Capacity' routing.AddDimension( transit_callback_index, 0, # no slack 100, # vehicle maximum capacities True, # start cumul to zero dimension_name) capacity_dimension = routing.GetDimensionOrDie(dimension_name) for i, demand in enumerate(data['demands']): index = manager.NodeToIndex(i) capacity_dimension.SetDemand(index, demand) for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) capacity_dimension.CumulVar(index).SetRange(data['vehicle_capacities'][vehicle_id], data['vehicle_capacities'][vehicle_id]) search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION) solution = routing.SolveWithParameters(search_parameters) if solution: print_solution(data, manager, routing, solution) if __name__ == '__main__': main() ``` Note that this is just a basic implementation and can be modified to suit specific requirements and constraints of individual problem instances.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值