今天作业汇报完,直接开源!
1.数据准备:
1.1随机初始化版:
初始化城市数量以及维度:
pair<int, int> initial::read_private_i() {
cout << "sizec: " <<this->sizec << endl;
cout << "sizek: " << this->sizek << endl;
int a, b;
a = this->sizec;
b = this->sizek;
return make_pair(a,b);
}
随机初始化城市方位:
int **initial::chengshichushihua() {
int** chengshi = (int**)malloc(initial::sizec* sizeof(int*));
for (int i = 0;i < initial::sizec;i++){
chengshi[i] = (int*)malloc(initial::sizek * sizeof(int));
for (int j = 0;j < initial::sizek;j++){
chengshi[i][j] = getRand(1, 1000);
}
}
this->chengshibiao = chengshi;
return chengshi;
}
返回相应指针,并更新类中的属性
根据随机初始化的城市算与其他城市的距离(假设所有城市之间都能相互到达)
double** initial::get_juli() {
double** juli = (double**)malloc(this->sizec * sizeof(double*));
for (int i = 0;i < this->sizec;i++) {
juli[i] = (double*)malloc(this->sizec * sizeof(double));
for (int j = 0;j < this->sizec;j++) {
if (i == j) {
juli[i][j] = 0;
}
else {
juli[i][j] = sqrt(pow(this->chengshibiao[i][0] - this->chengshibiao[j][0], 2) + pow(this->chengshibiao[i][1] - this->chengshibiao[j][1], 2));
}
}
}
this->len = juli;
return juli;
}
同样也是返回指针
1.2使用kroA100.TSP数据集版:
将.tsp文件转换成.txt文件进行读取:
void teacher_data::read_data() {
string data;
ifstream inf;
inf.open("..\\kroA100.txt");
if (!inf) {
cout << "error" << endl;
}
while (getline(inf, data)) {
string a = data;
int i = 0;
if (a[0] >= '0' && a[0] <= '9') {
while (a[i] != ' ') {
i++;
}
i++;
string b;
while (a[i] != ' ') {
b.push_back(a[i]);
i++;
}
i++;
string c;
while (a[i] >= '0' && a[i] <= '9') {
c.push_back(a[i]);
i++;
}
vector<int> d;
d.push_back(stoi(b));
d.push_back(stoi(c));
this->data.push_back(d);
}
}
/*for (int i = 0;i < 100;i++) {
for (int j = 0;j < 2;j++) {
cout << this->data[i][j];
cout << " ";
}
cout << endl;
}*/
inf.close();
}
计算距离:
double ** teacher_data::jisuanjuli() {
double** juli = (double**)malloc(100 * sizeof(double*));
for (int i = 0;i < 100;i++) {
juli[i] = (double*)malloc(100 * sizeof(double));
for (int j = 0;j < 100;j++) {
if (i == j) {
juli[i][j] = 0;
}
else {
juli[i][j] = sqrt(pow(this->data[i][0] - this->data[j][0], 2) + pow(this->data[i][1] - this->data[j][1], 2));
}
}
}
this->juli_data = juli;
return juli;
}
2.禁忌搜索:
整体流程:
vector<int> jinjisousuo::TSP(int x) {
this->min_len = x;
this->chushihuajie();
this->jisuan();
//this->read_private();
vector<int> ans;
double best = 0;
for (int i = 0;i < this->maxiter;i++) {
this->xunzhaolingyu();
auto p= this->xunzhaolingyuzuiyoujie();
if (p.second == 0) {
i--;
this->op++;
if (op == 7000) {
break;
}
continue;
}
ans = p.first;
best = p.second;
bool jo=this->teshe(best,ans);
if (jo == true) {
jinji(ans);
}
this->op = 0;
cout << "最优解: " << this->min_len<< endl;
}
return this->zuiyoujie;
}
代码进行了优化,只记录有效迭代,无效迭代会直接舍弃
初始化一个解:
void jinjisousuo::chushihuajie() {
for (int i = 0;i < jinjisousuo::sum;i++) {
this->fir.push_back(i);
this->zuiyoujie.push_back(i);
}
}
计算要搜索得领域数量:
void jinjisousuo::jisuan() {
int suml = 0;
for (int i = 1;i < jinjisousuo::sum;i++) {
suml = suml + i;
}
suml = int(suml * 0.002);
jinjisousuo::lingyushuliang = suml;
}
确定领域数量之后进行领域搜索
vector<vector<int>> jinjisousuo::xunzhaolingyu() {
vector<vector<int>> r;
vector<int> l;
int len = this->fir.size();
for (int i = 0;i < len;i++) {
l.push_back(this->fir[i]);
}
for (int i = 0;i <this->lingyushuliang;i++) {
int k = getRand2(0, this->sum-1);
int q = 0;
q= getRand2(0, this->sum-1);
int tmp = l[k];
l[k] = l[q];
l[q] = tmp;
//cout << k << " " << q << endl;
int j = 0;
/*while (j < this->num) {
k = getRand2(0, this->sum - 1);
q = getRand2(0, this->sum - 1);
tmp = l[k];
l[k] = l[q];
l[q] = tmp;
j++;
}*/
r.push_back(l);
}
this->lingyu = r;
return r;
}
计算每个领域集中得最优解:
pair<vector<int>,double> jinjisousuo::xunzhaolingyuzuiyoujie() {
auto l = this->fir;
auto p = this->lingyushuliang;
double min = 100000000000;
for (int i = 0;i < p;i++) {
double j = this->jisuanjuli(lingyu[i]);
if (j < min) {
min = j;
for(int u=0;u<this->fir.size();u++)
l[u] = lingyu[i][u];
}
}
if (min > this->min_len) {
min = 0;
}
//cout << "min: " << min << endl;
return make_pair(l,min);
}
更新禁忌表:
void jinjisousuo::gengxin(vector<int> y) {
if (t == maxt) {
vector<vector<int>>::iterator k = this->tabulist.begin();
this->tabulist.erase(k);
this->tabulist.push_back(y);
}
else {
this->tabulist.push_back(y);
this->t++;
}
}
特赦:
bool jinjisousuo::teshe(int x, vector<int> y) {
if (pteshe(x) == true) {
this->zuiyoujie = y;
this->fir = y;
this->min_len = x;
return true;
}
else {
jinji(y);
return false;
}
}
禁忌操作:
void jinjisousuo::jinji(vector<int> y) {
if (this->panduan_in(y) == false) {
this->fir = y;
this->gengxin(y);
}
}