没什么意思,结果刚刚揭晓,46分,评价是“算法无特色,表述无重点,代码水平有待提高”,GG,写的太水,大佬莫笑~
赛题:
最强大脑中的收官蜂巢迷宫变态级挑战,相信大家都叹为观止!最强大脑收官战打响后,收视率节节攀升,就连蚁后也不时出题难为一下她的子民们。在动物世界中,称得上活地图的,除了蜜蜂,蚂蚁当仁不让。在复杂多变的蚁巢中, 蚂蚁总是能以最快、最高效的方式游历在各个储藏间(存储食物)。今天,她看完最新一期节目,又发布了一项新任务:小蚁同学,我需要玉米库的玉米,再要配点水果,去帮我找来吧。小蚁正准备出发,蚁后又说:哎呀,回来,我还没说完呢,还有若干要求如下:
1.小蚁同学,你需要尽可能以最少的花费拿到食物(附件图中路线上的数值表示每两个储物间的花费);
2.小蚁同学,你最多只能经过9个储藏间拿到食物(包含起止两个节点,多次通过同一节点按重复次数计算);
3.小蚁同学,你必须经过玉米间,水果间(附件图中标绿色节点);
4.别忘了,食蚁兽也在路上活动呢,一旦与食蚁兽相遇,性命危矣!不过小蚁微信群公告已经公布了敌人信息(附件图中标红色路段);
5.最后,千万别忘了,还有两段路是必须经过的,那里有我准备的神秘礼物等着你呢(附件图中标绿色路段)。
这下小蚁犯难了,这和它们平时找食物的集体活动规则不一样嘛,看来这次需要单独行动了。要怎么选路呢?小蚁经过一番苦思冥想,稿纸堆了一摞,啊,终于找到了!亲爱的同学们,你们能否也设计一种通用的路径搜索算法,来应对各种搜索限制条件,找到一条最优路径,顺利完成蚁后布置的任务呢?
注:
1、蚁巢,有若干个储藏间(附件图中圆圈表示),储藏间之间有诸多路可以到达(各储藏间拓扑图见附件);
2、节点本身通行无花费;
3、该图为无向图,可以正反两方向通行,两方向都会计费,并且花费相同;
4、起止节点分别为附件图中S点和E点。
5、最优路径:即满足限制条件的路径。
算法思路:
重新构图,迪杰斯特拉改进版+优化的蚁群算法,前提对图形进行了预处理,以处理几条必经边连在一起,必经节点和必经边重合的情况,没有写注释,有点凌乱
#include<iostream> #include<queue> #include<vector> #include<fstream> #include<set> #include<algorithm> #include<list> #include<string> #include<iomanip> #include<ctime> using namespace std; #define EPS 1e-8 #define alfa 1.0 //启发因子,信息素的重要程度 double beta = 0.8; //期望因子,城市间距离的重要程度 #define rou 0.4 //信息素残留参数 double Q = 30.0; //总的信 const int MAXN = 2000;//假设最多200个点 const int INF = 100000; int edgenum = 0; int nodes, edges; int startnode, endnode;//出发点,结束点 clock_t start, end; vector<vector<int>>a(MAXN, vector<int>(MAXN, INF)); struct edge { int u; int v; int cost; int next; }e[300000], e1[300000]; struct Node { int index; int value; }; struct Way { int waynodes;//路上的点数 int waycost; vector<int>way; }; int first[MAXN]; int first1[MAXN]; vector<int>mustnodes;//必经节点 vector<int>ismustnode; vector<vector<int>>mustedges;//必经边 vector<int>mustedge; vector<int>father; vector<vector<int>>notedges;//不能过的边 vector<Node>virtualnode; set<int>mustvirtualnode; vector<vector<vector<double>>>tao; void add(int u, int v, int cost) { e[edgenum].u = u; e[edgenum].v = v; e[edgenum].cost = cost; e[edgenum].next = first[u]; int cur = edgenum; first[u] = edgenum++; //cout << "edgenum=" << cur << " u=" << u << " v=" << v<<" next="<<e[cur].next << " first[" << u << "]=" << first[u] << endl; } void copy(edge *e1, edge *e2) { for (int i = 0; i < MAXN; i++)first1[i] = first[i]; for (int i = 0; i < 2000; i++) { *e1 = *e2; e1++; e2++; } } int find(int u, int v) { for (int i = 0; i < edges * 2; i++) { if (e[i].u == u&&e[i].v == v) { return i; } } return -1; } int findmustedges(int u)//判断一个点是否在必经路径上 { for (int i = 0; i < mustedges.size(); i++) { for (int j = 0; j < mustedges[i].size(); j++) { if (mustedges[i][j] == u) { return i; } } } return -1; } int findnodes(vector<Node>&nodes, int &v) { for (int i = 0; i < nodes.size(); i++) { if (nodes[i].value == v)return i; } return -1; } void show(vector<int>&v) { for (int i = 0; i < v.size(); i++) cout << setiosflags(ios::right) << setiosflags(ios::fixed) << setw(4) << v[i]; cout << endl; } void show(vector<vector<int>>&v) { for (int i = 0; i < v.size(); i++) { for (int j = 0; j < v[i].size(); j++)cout << v[i][j] << " "; cout << endl; } } void show(vector<Node>&v) { for (int i = 0; i < v.size(); i++)cout << "index=" << v[i].index << " " << v[i].value << endl; } void GetPath2(int &newindex, int &s, vector<int>&oldtonew, vector<vector<vector<Way>>>&map) { int n = nodes; vector<int>dist(n, INF); vector<int>pdist(n, INF); vector<vector<int>>pre(n, vector<int>(n, -1)); vector<int>path; vector<int>min(n, INF); dist[s] = 0; /*for (int i = first[s]; i != -1; i = e[i].next) { int u = e[i].u; int v = e[i].v; dist[v] = e[i].cost; pre[0][v] = s; }*/ pdist = dist; //m_mincost[0] = dist[t]; int m = 0; //show(dist); while (1) { //cout << "m=" << m << endl; pdist = dist; for (int i = 0; i < n; i++) { for (int k = first[i]; k != -1; k = e[k].next) { int u = e[k].u; int v = e[k].v; //cout << "u=" << u << " v=" << v << endl; if (pdist[v] + e[k].cost < dist[u]) { //cout << "i1=" << u << " j1=" << v << endl; dist[u] = pdist[v] + e[k].cost; pre[m][u] = v; //show(dist); } } if (i != s) { if (s == 0 && i == endnode)break; int index = oldtonew[i]; //cout << "index0=" << index << endl; if (index != -1 && pre[m][i] != -1 && dist[i]<min[i]) { min[i] = dist[i]; //cout << "index=" << index << " value=" << mustgo[index].value << endl; //show(pre); path.push_back(i); int deep = m; for (int j = i; j != -1 && j != s;) { int temp = pre[deep][j]; path.push_back(temp); if (deep != 0)deep = deep - 1; j = temp; } reverse(path.begin(), path.end()); //cout << "cost=" << dist[i] << endl; //show(path); Way temp = { path.size(), dist[i], path }; map[newindex][index].push_back(temp); path.clear(); } } } //show(dist); int count = 0; for (int i = 0; i < n; i++) { if (m != 0 && pdist[i] == dist[i]) { pre[m][i] = pre[m - 1][i]; count++; } if (m == 0)continue; } //for (int i = 0; i < n; i++) //{ // if (i != s) // { // if (s == 0 && i == endnode)break; // int index = oldtonew[i]; // //cout << "index0=" << index << endl; // if (index != -1 && pre[m][i] != -1 && dist[i]<min[i]) // { // min[i] = dist[i]; // //cout << "index=" << index << " value=" << mustgo[index].value << endl; // //show(pre); // path.push_back(i); // int deep = m; // for (int j = i; j != -1 && j != s;) // { // int temp = pre[deep][j]; // path.push_back(temp); // if (deep != 0)deep = deep - 1; // j = temp; // } // reverse(path.begin(), path.end()); // //cout << "cost=" << dist[i] << endl; // //show(path); // Way temp = { path.size(), dist[i], path }; // map[newindex][index].push_back(temp); // path.clear(); // } // } //} if (count == n)break; if (m == n - 1)break; m++; } } void Init(vector<vector<vector<Way>>>&map, vector<Node>&mustgo) { //vector<Node>mustgo(mustnodes.size() + mustedges.size() * 2 + 2); mustedge.clear(); vector<int>oldtonew(nodes, -1); mustedge = oldtonew; ismustnode = oldtonew; int k = 0; mustgo[k].index = startnode; mustgo[k].value = startnode; oldtonew[0] = 0; k++; for (int i = 0; i < mustnodes.size(); i++) { mustgo[k].index = k; mustgo[k].value = mustnodes[i]; oldtonew[mustnodes[i]] = k; ismustnode[mustnodes[i]] = 1; k++; } for (int i = 0; i < mustedges.size(); i++) { mustgo[k].index = k; mustgo[k].value = mustedges[i][0]; oldtonew[mustedges[i][0]] = k; mustedge[mustedges[i][0]] = i; k++; mustgo[k].index = k; mustgo[k].value = mustedges[i][1]; oldtonew[mustedges[i][1]] = k; mustedge[mustedges[i][1]] = i; k++; } mustgo[k].index = k; mustgo[k].value = endnode; oldtonew[endnode] = k; k++; cout << "编号" << endl; for (int i = 0; i < mustgo.size(); i++) { cout << mustgo[i].index << " " << mustgo[i].value << endl; } //cout << "k=" << k << endl; //vector<vector<vector<Way>>>map(k, vector<vector<Way>>(k)); int count = 0; double num = 0, cost = 0; int s = 0; //show(oldtonew); //cout << "father" << endl; //show(ismustnode); //maxdeep(s, mustgo); //GetPath(s, s, maxdeep(s, mustgo)-1, mustgo, map); father = oldtonew; //show(father); for (int i = 0; i < k-1; i++) { int u = mustgo[i].value; int maxnodes = 0; GetPath2(i, u, oldtonew, map); } for (int i = 0; i < k; i++) { for (int j = 0; j < k; j++) { if (i == j)continue; vector<Way>way = map[i][j]; /*if (way.size() == 0) { cout << "i=" << i << " j=" << j << endl; }*/ for (int i0 = 0; i0 < way.size(); i0++) { count++; Way temp = way[i0]; num = num + temp.waycost; //cost = cost + temp.waynodes; //cout << "way cost=" << way[i0].waycost << endl; //show(way[i0].way); } } } double temp = 1.0*num + 1.0*cost; temp = temp / count; cout << "temp=" << temp << endl; beta = 3.0; //return mustgo; } void Init_S(vector<vector<vector<Way>>>&map) { int len = map.size(); vector<vector<vector<double>>>temp(len, vector<vector<double>>(len)); for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { int tlen = map[i][j].size(); vector<double>temp0(tlen, 0.0); temp[i][j] = temp0; } } tao = temp; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { vector<Way>way = map[i][j]; if (way.size()>0) { for (int k = 0; k < way.size(); k++) { tao[i][j][k] = 1.0 / way.size(); if (way[k].way.size() == 2) { int u = way[k].way[0]; int v = way[k].way[1]; int k1 = findmustedges(u); int k2 = findmustedges(v); if (i != j && (k1 == k2) && (k1 != -1 && k2 != -1)) { //cout << "i=" << i << " j=" << j << endl; //cout << "u=" << u << " v=" << v << " k=" << k << endl; tao[i][j][k] = INF; } } } } } } } class Ant { public: int N; int Cost; vector<int>Order; vector<int>Path; vector<int>AllowedCity; vector<int>ChooseIndex; int CurCity; int MovedCityCount; Ant(int N) { this->N = N; this->Init(); } void Init() { Cost = 0; vector<int>_Order; vector<int>_AllowedCity(N, 1); vector<int>_ChooseIndex(N, -1); CurCity = 0; MovedCityCount = 1; Order = _Order; AllowedCity = _AllowedCity; ChooseIndex = _ChooseIndex; Path.clear(); Order.push_back(0); AllowedCity[0] = 0; } }; int choose(vector<double>v) { static int num = 0; srand(unsigned(time(0)) + num); num = rand(); int len = v.size(); vector<double>q(len + 1, 0.0); double sum = 0; int index = 0; for (int i = 0; i < len; i++) { sum = sum + v[i]; } //cout << "sum=" << sum << endl; for (int i = 0; i < len; i++) { v[i] = v[i] * 1.0 / sum; q[i + 1] = q[i] + v[i]; } //for (int i = 0; i < v.size(); i++)cout << v[i] << " "; //cout << endl; double rd = rand() / (RAND_MAX + 1.0); //for (int i = 0; i < q.size(); i++)cout << q[i] << " "; //cout << endl; //cout << rd << endl; while (1) { rd = rand() / (RAND_MAX + 1.0); index = 0; while (q[index] < rd) { index++; } index--; //rd = rand() / (RAND_MAX + 1.0); if (index >= 0)break; } /*while (1) { rd = rand() / (RAND_MAX + 1.0); int low = 0, high = len; while (low < high) { if (q[low] < rd&&rd < q[low + 1])break; int middle = (high - low) / 2 + low; if (rd < q[middle])high = middle; else if (rd > q[middle])low = middle; } low--; index = low; if (index>= 0)break; }*/ return index; } void updatetrial2(vector<vector<vector<Way>>>&map, vector<Ant>&Ants, int &curcost ,int &bestcost, int &maxnode) { static int num1 = 0; srand(unsigned(time(0)) + num1); num1 = rand(); int antsize = Ants.size(); int len = map.size(); vector<vector<vector<double>>>Temptao(len, vector<vector<double>>(len, vector<double>(len, 0.0))); vector<double>pt(Ants.size(), 0.0); //cout << "curcost=" << curcost << " bestcost=" << bestcost << endl; vector<int>could(pt.size(), 0); for (int i = 0; i < Ants.size(); i++) { if (Ants[i].Path.size() <= maxnode) { pt[i] = Ants[i].Path.size()*0.6 + Ants[i].Cost*0.4; pt[i] = 3.0 / pt[i]; could[i] = 1; } else { if (rand() % 2 == 0) { if (Ants[i].Cost <= bestcost) { pt[i] = Ants[i].Path.size()*0.6 + Ants[i].Cost*0.4; pt[i] = 1.0 / pt[i]; could[i] = 1; } } else { if (Ants[i].Cost <= curcost) { pt[i] = Ants[i].Path.size()*0.6 + Ants[i].Cost*0.4; pt[i] = 1.0 / pt[i]; could[i] = 1; } } } } //for (int i0 = 0; i0 < antsize; i0++) //for (int i = 0; i < pt.size(); i++)cout << could[i] << " "; //cout << endl; for (int i0 = 0; i0 < Ants.size(); i0++) { int i = i0; if (could[i] == 0)continue; //i = choose(pt); //cout << "i=" << i << " cost=" << Ants[i].Cost << endl; //cout << "order" << endl; //show(Ants[i].Order); for (int j = 1; j < Ants[i].Order.size(); j++) { int m = Ants[i].Order[j]; int n = Ants[i].Order[j - 1]; //cout << "i=" << i << " j=" << j << endl; //cout << "m=" << m << " n=" << n << endl; vector<Way>way = map[m][n]; //cout << "size=" << way.size() << endl; int index = Ants[i].ChooseIndex[m]; if (way.size()>0) { //for (int k = 0; k < way.size(); k++) { //cout << "update=" << index << endl; Temptao[n][m][index] = Temptao[n][m][index] + Q / (Ants[i].Path.size()*0.0 + Ants[i].Cost*1.0); Temptao[m][n][index] = Temptao[n][m][index]; } } } } //for (int i0 = 0; i0 < Ants.size()/2; i0++) //{ // int i = i0; // i = choose(pt); // //cout << "i=" << i << " cost=" << Ants[i].Cost << endl; // for (int j = 1; j < len; j++) // { // int m = Ants[i].Order[j]; // int n = Ants[i].Order[j - 1]; // //cout << "i=" << i << " j=" << j << endl; // //cout << "m=" << m << " n=" << n << endl; // vector<Way>way = map[m][n]; // //cout << "size=" << way.size() << endl; // int index = Ants[i].ChooseIndex[m]; // if (way.size()>0) // { // //for (int k = 0; k < way.size(); k++) // { // //cout << "update=" << index << endl; // Temptao[n][m][index] = Temptao[n][m][index] + Q / (Ants[i].Path.size()*0.0 + Ants[i].Cost*1.0); // Temptao[m][n][index] = Temptao[n][m][index]; // } // } // } //} //cout << "here update" << endl; double maxconcentration = 0; double a = 0.1; double tmax = 10, tmin = 1; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { vector<Way>way = map[i][j]; if (way.size()>0) { for (int k = 0; k < way.size(); k++) { tao[i][j][k] = tao[i][j][k] * rou + Temptao[i][j][k]; if (way[k].way.size() == 2) { int u = way[k].way[0]; int v = way[k].way[1]; int k1 = mustedge[u]; int k2 = mustedge[v]; if (i != j && (k1 == k2) && (k1 != -1 && k2 != -1)) { tao[i][j][k] = INF; } else { if (tao[i][j][k] >= tmax)tao[i][j][k] = tmax; maxconcentration = maxconcentration>tao[i][j][k] ? maxconcentration : tao[i][j][k]; } } else { if (tao[i][j][k] >= tmax)tao[i][j][k] = tmax; maxconcentration = maxconcentration > tao[i][j][k] ? maxconcentration : tao[i][j][k]; } } } } } //cout << "max=" << maxconcentration << endl; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { for (int k = 0; k < tao[i][j].size(); k++) { if (tao[i][j][k] < 0.1*maxconcentration) { tao[i][j][k] = 0.1*maxconcentration; } } } } } void check(vector<int>&path)//校验程序 { int mustnodesum = mustnodes.size(); int mustedgesum = mustedges.size(); for (int i = 0; i < path.size(); i++) { if (ismustnode[path[i]] != -1) { cout << setiosflags(ios::right) << setiosflags(ios::fixed) << setw(4) << path[i]; mustnodesum--; ismustnode[path[i]] = -1; } } cout << endl; cout << "the number of non visited necessary nodes "<<mustnodesum << endl; if (mustnodesum > 0) { cout << "error path" << endl; return; } int count = 0; for (int i = 0; i < path.size() - 1; i++) { int k1 = mustedge[path[i]]; int k2 = mustedge[path[i + 1]]; if (k1 == k2 && (k1 != -1 && k2 != -1)) { mustedgesum--; mustedge[path[i]] = -1; mustedge[path[i + 1]] = -1; cout << "(" << setiosflags(ios::right) << setiosflags(ios::fixed) << setw(4) << path[i] << setiosflags(ios::right) << setiosflags(ios::fixed) << setw(4) << path[i + 1] << ")"; count++; if (count == 5) { cout << endl; count = 0; } } } cout << "the number of non visited necessary edges " << mustedgesum << endl; //cout << mustedgesum << endl; if (mustedgesum>0)cout << "error path" << endl; return; } void startseacher(vector<vector<vector<Way>>>&map, vector<Ant>&Ants, int &maxnodes, vector<Node>&mustgo) { ofstream fout("result.txt"); vector<int>bestpath, shortpath(1000, 0); vector<int>bestorder, shortorder; int bestcost = INF, shortcost = INF; int bestAnt=-1, shortAnt=-1; int Nc = 0, NcMax = 100; int len = map.size(); int lastbest = 0; int lastshort = 0; int count = 0;//如果解长时间不更新就退出,或者初始化重来 int num = 1; while (1) { cout << "Nc=" << Nc << endl; if (Nc - lastbest > 5 && Nc - lastshort > 5) { count++; cout << "count=" << count << endl; if (count < 3&&nodes<50) { Init_S(map); lastbest = Nc; lastshort = Nc; } else { break; } } //cout << "lastbest=" << lastbest << " lastshort=" << lastshort << endl; for (int i = 0; i < len - 1; i++) { for (int j = 0; j < Ants.size(); j++) { if (Ants[j].MovedCityCount == len)continue; vector<double>pt(len, 0.0); int curcity = Ants[j].CurCity; int to = -1; //cout << "i=" << i << " j=" << j << " curcity=" << curcity << endl; int k1 = mustedge[mustgo[curcity].value]; int tempk = -1; for (int k = 0; k < len; k++) { //cout << "i=" << i << " j=" << j << " k=" << k << endl; if (Ants[j].AllowedCity[k] == 1 && k != len - 1&&Ants[j].MovedCityCount< len-1) { vector<Way>way = map[curcity][k]; double p = 0.0; double length = 0.0, cost = 0.0; int k2 = mustedge[mustgo[k].value]; if (k1 != -1 && k2 != -1 && k2 == k1) { pt[k] = INF; tempk = k; //cout << "curcity=" << curcity << " k=" << k << endl; break; //cout << pt[k] << endl; //getchar(); } if (way.size()>0) { for (int i0 = 0; i0 < tao[curcity][k].size(); i0++)p = p + tao[curcity][k][i0]; for (int i0 = 0; i0 < way.size(); i0++) { length = length + way[i0].waynodes; cost = cost + way[i0].waycost; } length = length*1.0 / way.size(); cost = cost*1.0 / way.size(); length = 0.0*length + 1.0*cost;//每条路径取平均费用 //length = way[0].waynodes*0.0 + way[0].waycost*1.0; if (length < 1)length = 0.5;//因为虚拟边费用为0; pt[k] = pow(p, alfa)*pow(1.0 / length, beta); } } if (k == len - 1 && Ants[j].MovedCityCount == len - 1) { to = len - 1; pt[k] = 1000.0; break; } } while (1) { if (tempk != -1) { to = tempk; break; } to = choose(pt); //cout << "to=" << to << endl; if (Ants[j].AllowedCity[to] == 1 && to != -1)break; cout << "to=" << to << endl; if (to == 0) { cout << "error" << endl; getchar(); exit(-1); } } //cout << "i=" << i << " j=" << j << " to=" << to << endl; Ants[j].Order.push_back(to); vector<Way>way = map[curcity][to]; //cout << "i=" << i << " j="<<j<<" count=" << Ants[j].MovedCityCount << endl; if (way.size()>0) { vector<double>pt(way.size(), 0.0); for (int i0 = 0; i0 < way.size(); i0++) { double tempcost = way[i0].waycost; if (abs(tempcost - 0) < 0.0001)tempcost = 0.5;//因为虚拟边费用为0 pt[i0] = pow(tao[curcity][to][i0], alfa)*pow(1.0 / tempcost, beta); } int index = choose(pt); Ants[j].ChooseIndex[to] = index; //cout << "way" << endl; //show(way[index].way); for (int i0 = 0; i0 < way[index].way.size(); i0++) { int temp = way[index].way[i0]; if (i0>=1 && i0 < way[index].way.size()-1)//看看是否包含了必经边 { int temp1 = temp; int temp2 = way[index].way[i0+1]; int k1 = mustedge[temp1]; int k2 = mustedge[temp2]; //cout << " temp1=" << temp1 << " temp2=" << temp2 << endl; //cout << " k1=" << k1 << " k2=" << k2 << endl; if (k1 != -1 && k2 != -1 && k1 == k2) { //show(father); int k3 = father[temp1]; int k4 = father[temp2]; //cout << " k3=" << k3 << " k4=" << k4 << endl; //if (k3 == 999 || k4 == 999)cout << " k3=" << k3 << " k4=" << k4 << endl; if (Ants[j].AllowedCity[k3] == 1&&k3!=endnode)//该节点不能是尾节点 { Ants[j].AllowedCity[k3] = 0; Ants[j].MovedCityCount++; } if (Ants[j].AllowedCity[k4] == 1 && k4 != endnode)//该节点不能是尾节点 { Ants[j].AllowedCity[k4] = 0; Ants[j].MovedCityCount++; } } } if (i0 >= 1 && i0 < way[index].way.size() - 1)//看看是否包含了必经 { //cout << "temp=" << temp << endl; if (ismustnode[temp] != -1) { int k1 = father[temp]; //cout << " k1=" << k1 << endl; //if (k1 == 999)cout << " k1=" << k1 << endl; if (Ants[j].AllowedCity[k1] == 1&&k1!=endnode)//该节点不能是尾节点 { Ants[j].AllowedCity[k1] = 0; Ants[j].MovedCityCount++; } } } if (temp > endnode)//如果是虚拟点换回去 { int tempindex = findnodes(virtualnode, temp); //cout << "tempindex=" << tempindex << endl; if (tempindex != -1) { temp = virtualnode[tempindex].index; } } Ants[j].Path.push_back(temp); } Ants[j].Cost = Ants[j].Cost + way[index].waycost; } if (Ants[j].AllowedCity[to] == 1) { Ants[j].AllowedCity[to] = 0; Ants[j].MovedCityCount++; } //cout << "i=" << i << " j="<<j<<" count=" << Ants[j].MovedCityCount << endl; Ants[j].CurCity = to; int value = mustgo[to].value;//将节点还原到原图里面 if (mustedge[value] != -1)//如果是必经边 { //cout << "to=" << to << endl; int temp = mustedge[value];//原图所在第几条边 //cout << "temp=" << temp << endl; int i0 = 0; for (i0 = 0; i0 < nodes; i0++) { if (mustedge[i0] == temp&&i0 != value)break;//找到原图里面和value同为一条必经边的点i0 } //cout << "i0=" << i0 << endl; int index = father[i0];//将i0还原到新图 //cout << "index=" << index << endl; if (Ants[j].AllowedCity[index] == 1)//如果未被访问过 { Ants[j].AllowedCity[index] = 0; Ants[j].MovedCityCount++; Ants[j].CurCity = index; Ants[j].Order.push_back(index); Ants[j].ChooseIndex[index] = 0; } } } } for (int i = 0; i < Ants.size(); i++) { vector<int>Order = Ants[i].Order; vector<int>path = Ants[i].Path; vector<int>path0; int tempcost = 0; int cur = -1, next = -1; //cout << "i=" << i << endl; //show(path); for (int j = 0; j < path.size(); ) { //cout << "i=" << i << endl; cur = next; next = path[j]; if (cur != -1 && next != -1) { tempcost = tempcost + a[cur][next]; } int k0 = j; path0.push_back(path[j]); while (k0 < path.size() && path[k0] == path[j])k0++; //cout << "k0=" << k0 << endl; j = k0; } //show(path0); //for (int i = 0; i < path0.size() - 1; i++)tempcost = tempcost + a[path0[i]][path0[i + 1]]; Ants[i].Path.clear(); Ants[i].Path = path0; Ants[i].Cost = tempcost; if (path[path.size() - 1] != endnode) { cout << "cost=" << Ants[i].Cost << endl; /*show(Ants[i].Order); show(path0); getchar();*/ } } int temp0 = INF, temp1 = INF, tempmax = 0; for (int i = 0; i < Ants.size(); i++) { if (temp0>Ants[i].Cost) { temp0 = Ants[i].Cost; bestAnt = i; } if (Ants[i].Path.size() <= maxnodes) { if (Ants[i].Cost < shortcost) { shortcost = Ants[i].Cost; shortorder = Ants[i].Order; shortpath = Ants[i].Path; lastshort = Nc; cout << "shortcost=" << shortcost << endl; } else if (Ants[i].Cost == shortcost) { if (Ants[i].Path.size() < shortpath.size()) { shortcost = Ants[i].Cost; shortorder = Ants[i].Order; shortpath = Ants[i].Path; lastshort = Nc; cout << "shortcost=" << shortcost << endl; } } } if (tempmax<Ants[i].Cost) { tempmax = Ants[i].Cost; } } if (temp0 < bestcost) { lastbest = Nc; bestcost = temp0; bestorder = Ants[bestAnt].Order; bestpath = Ants[bestAnt].Path; cout << "bestcost=" << bestcost << endl; //show(bestorder); //show(bestpath); } else if (temp0 == bestcost) { if (bestpath.size() > Ants[bestAnt].Path.size()) { lastbest = Nc; bestcost = temp0; bestorder = Ants[bestAnt].Order; bestpath = Ants[bestAnt].Path; cout << "bestcost=" << bestcost << endl; //show(bestpath); } } //cout << "temp0=" << temp0 << " tempmax=" << tempmax << endl; if (num == 1) { Q = (temp0 + tempmax) / 2.0; num++; } //temp0 = temp0 + ceil((tempmax - temp0) / 4); //cout << "temp0=" << temp0 << " tempmax=" << tempmax << endl; updatetrial2(map, Ants, temp0, bestcost,maxnodes); for (int i = 0; i < Ants.size(); i++)Ants[i].Init(); Nc++; } if (1) { cout << "The cheapest way" << endl; cout << "bestcost=" << bestcost << endl; cout << "nodes=" << bestpath.size() << endl; show(bestpath); fout << "The cheapest way" << endl; fout << "bestcost=" << bestcost << endl; fout << "nodes=" << bestpath.size() << endl; int w = 5; if (nodes>=1000)w = 5; else if (nodes >= 100)w = 4; else if (nodes>10)w = 3; else w = 2; for (int i = 0; i < bestpath.size(); i++) { fout << setiosflags(ios::right) << setiosflags(ios::fixed) << setw(w) << bestpath[i]; if ((i + 1) % 20 == 0)fout << endl; } fout << endl; } if (shortpath.size() < 1000) { cout << "shortpath" << endl; cout << "cost=" << shortcost << endl; cout << "nodes=" << shortpath.size() << endl; show(shortpath); fout << "shortpath" << endl; fout << "cost=" << shortcost << endl; fout << "nodes=" << shortpath.size() << endl; int w = 5; if (nodes >= 1000)w = 5; else if (nodes >= 100)w = 4; else if (nodes>10)w = 3; else w = 2; for (int i = 0; i < bestpath.size(); i++) { fout << setiosflags(ios::right) << setiosflags(ios::fixed) << setw(w) << bestpath[i]; if ((i + 1) % 20 == 0)fout << endl; } fout << endl; } else { shortpath = bestpath; shortcost = bestcost; cout << "There is no way to satisfy the restricted vertex number" << endl; cout << "The recommended path:" << endl; cout << "cost=" << shortcost << endl; cout << "nodes=" << shortpath.size() << endl; show(shortpath); fout << "There is no way to satisfy the restricted vertex number" << endl; fout << "The recommended path:" << endl; fout << "cost=" << shortcost << endl; fout << "nodes=" << shortpath.size() << endl; int w = 5; if (nodes >= 1000)w = 5; else if (nodes >= 100)w = 4; else if (nodes>10)w = 3; else w = 2; for (int i = 0; i < bestpath.size(); i++) { fout << setiosflags(ios::right) << setiosflags(ios::fixed) << setw(w) << shortpath[i]; if ((i + 1) % 20 == 0)fout << endl; } fout << endl; } cout << "time=" << (clock() - start)*1.0 / CLOCKS_PER_SEC<<"s" << endl; fout << "time=" << (clock() - start)*1.0 / CLOCKS_PER_SEC<<"s" << endl; //check(shortpath); //check(bestpath); fout.close(); } void main() { string s; while (1) { start = clock(); vector<vector<int>>_a(MAXN, vector<int>(MAXN, INF)); edgenum = 0; a = _a; memset(first, -1, sizeof(first)); memset(first1, -1, sizeof(first1)); mustedges.clear(); mustnodes.clear();//必经节点 notedges.clear();//不能过的边 virtualnode.clear(); set<int>mustnodeset; cout << "input your map path, if you input quick, the program will exit" << endl; cin >> s; fstream fin(s); startnode = 0; if (s == "quick") { break; } if (!fin.is_open()) { cout << "your path is error" << endl; exit(-1); } int maxnode; while (fin >> nodes >> edges>>maxnode) { start = clock(); //cout << nodes << " " << edges << " " << maxnode << endl; endnode = nodes - 1; vector<vector<int>>v; for (int i = 0; i < edges; i++) { int temp1, temp2, temp3; fin >> temp1 >> temp2 >> temp3; //cout << temp1 << " " << temp2 << " " << temp3 << endl; //vector<int>temp{ temp1, temp2, temp3, 1 }; a[temp1][temp2] = temp3; a[temp2][temp1] = temp3; //v.push_back(temp); } int mustgonodes, mustgoedges; fin >> mustgonodes; for (int i = 0; i < mustgonodes; i++) { int temp; fin >> temp; mustnodeset.insert(temp); } fin >> mustgoedges; set<int>setmustedges; for (int i = 0; i < mustgoedges; i++) { int temp1, temp2; fin >> temp1 >> temp2; //cout << temp1 << " " << temp2 << " " << endl; if (mustnodeset.count(temp1) != 0)mustnodeset.erase(temp1); if (mustnodeset.count(temp2) != 0)mustnodeset.erase(temp2); if (setmustedges.count(temp1) == 0 && setmustedges.count(temp2) == 0) { vector<int>temp = { temp1, temp2 }; mustedges.push_back(temp); setmustedges.insert(temp1); setmustedges.insert(temp2); } else if (setmustedges.count(temp1) == 0 || setmustedges.count(temp2) == 0) { if (setmustedges.count(temp1) != 0 && setmustedges.count(temp2) == 0) { mustvirtualnode.insert(temp1); cout << "temp1=" << temp1 << endl; Node temp = { temp1, nodes }; vector<int>tempv = { nodes, temp2 }; mustedges.push_back(tempv); virtualnode.push_back(temp); a[temp1][nodes] = a[temp1][temp2]; a[nodes][temp1] = a[temp1][nodes]; a[nodes][temp2] = 0; a[temp2][nodes] = 0; nodes++; } if (setmustedges.count(temp2) != 0 && setmustedges.count(temp1) == 0)//temp2重复使用 { mustvirtualnode.insert(temp2); cout << "temp2=" << temp2 << endl; Node temp = { temp2, nodes }; vector<int>tempv = { temp1, nodes }; mustedges.push_back(tempv); virtualnode.push_back(temp); a[temp2][nodes] = a[temp1][temp2]; a[nodes][temp2] = a[temp2][nodes]; a[nodes][temp1] = 0; a[temp1][nodes] = 0; nodes++; cout << "nodes" << endl; } setmustedges.insert(temp2); setmustedges.insert(temp1); } else //两个节点都被使用了 { a[temp1][nodes] = a[temp1][temp2]; a[nodes][temp1] = a[temp1][temp2]; Node tn = { temp1, nodes }; virtualnode.push_back(tn); int temp = nodes; nodes++; a[temp][nodes] = 0; a[nodes][temp] = 0; vector<int>tempv = { temp, nodes }; mustedges.push_back(tempv); a[nodes][temp2] = 0; a[temp2][nodes] = 0; tn = { temp2, nodes }; virtualnode.push_back(tn); nodes++; } } for (set<int>::iterator p = mustnodeset.begin(); p != mustnodeset.end(); p++)mustnodes.push_back(*p); for (int i = 0; i < mustedges.size(); i++) { //cout << mustedges[i][0] << " " << mustedges[i][1] << endl; } int notedgenums; fin >> notedgenums; for (int i = 0; i < notedgenums; i++)//不能走的费用设置为无穷大 { int temp1, temp2; fin >> temp1 >> temp2; //cout << temp1 << " " << temp2 << " " << endl; a[temp1][temp2] = INF; a[temp2][temp1] = INF; } v.clear(); for (int i = 0; i < nodes - 1; i++) { for (int j = i + 1; j < nodes; j++) { if (a[i][j] != INF) { //cout << "here" << endl; add(i, j, a[i][j]); add(j, i, a[i][j]); } } } } int mincost = 0; vector<int>bestorder, bestpath; int newnodes = mustnodes.size() + mustedges.size() * 2 + 2;//新图的节点数目,一个头结点,一个尾节点 vector<Node>mustgo(mustnodes.size() + mustedges.size() * 2 + 2); vector<vector<vector<Way>>>map(newnodes, vector<vector<Way>>(newnodes)); { Init(map, mustgo); Ant ant(map.size()); vector<Ant>ants(map.size()*2/3, map.size()); Init_S(map); startseacher(map, ants, maxnode, mustgo); } fin.close(); } }