2017中兴算法挑战赛

没什么意思,结果刚刚揭晓,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();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值