1. 程式人生 > >蟻群演算法解TSP問題

蟻群演算法解TSP問題

添加了部分註釋,幾乎沒有改動(引數和城市格式略做改動),原博主的程式碼寫的很容易理解,也是我找到的最短的程式碼了,在此感謝。

程式碼如下:

//蟻群演算法關於簡單的TSP問題求解//
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<time.h>

#define M 13  //螞蟻的數量
#define N 52  //城市的數量
#define R 1000 //迭代次數
#define IN 1  //初始化的資訊素的量
#define MAX 0x7fffffff //定義最大值

struct coordinate
{
	char city[15];  //城市名
	int x;          //城市相對橫座標
	int y;          //城市相對縱座標
}coords[N];

double graph[N][N];   //儲存城市之間的距離的鄰接矩陣,自己到自己記作MAX
double phe[N][N];  //每條路徑上的資訊素的量
double add[N][N];  //代表相應路徑上的資訊素的增量
double yita[N][N]; //啟發函式,yita[i][j]=1/graph[i][j]

int vis[M][N];  //標記已經走過的城市
int map[M][N];  //map[K][N]記錄第K只螞蟻走的路線
double solution[M]; //記錄某次迴圈中每隻螞蟻走的路線的距離
int bestway[N]; //記錄最近的那條路線
double bestsolution=MAX;
int NcMax; //代表迭代次數,理論上迭代次數越多所求的解更接近最優解,最具有說服力
double alpha,betra,rou,Q;

void Initialize(); //資訊初始化
void Inputcoords(FILE *fp); //將檔案中的座標資訊讀入
void GreateGraph(); //根據座標資訊建圖
double Distance(int *p); //計算螞蟻所走的路線的總長度
void Result(); //將結果儲存到out.txt中

void Initialize()//初始化引數和迭代次數
{
	alpha=2; betra=4; rou=0.5; Q=50;
    NcMax=R;
	return ;
}
//從檔案讀入城市座標
void Inputcoords(FILE *fp)
{
	int i;
	int number;
	if(fp==NULL)
	{
		printf("Sorry,the file is not exist\n");
		exit(1);
	}
	else
	{
		for(i=0; i<N; ++i)
		{
			fscanf(fp,"%d,%d,%d,%s",&number,&coords[i].x,&coords[i].y,coords[i].city);
		}
	}
}
//初始化任意兩個城市間的距離
void GreateGraph( )
{
	int i,j;
	double d;
	for(i=0; i<N-1; ++i)
	{
		graph[i][i]=MAX;   //自己到自己標記為無窮大
		for(j=i+1; j<N; ++j)
		{
			d=(double)((coords[i].x-coords[j].x)*(coords[i].x-coords[j].x)+(coords[i].y-coords[j].y)*(coords[i].y-coords[j].y));
			graph[j][i]=graph[i][j]=sqrt(d);
		}
	}
	graph[N-1][N-1]=MAX;
	return ;
}
//計算環路的最小代價
double Distance(int *p)
{
	double d=0;
	int i;
	for(i=0; i<N-1; ++i)
	{
		d+=graph[*(p+i)][*(p+i+1)];
	}
	d+=graph[*(p+i)][*(p)];
	return d;
}
//輸出各個結果
void Result()
{
	FILE *fl;
	int i;
	fl = fopen("out.txt","a");  //將結果儲存在out.txt這個檔案裡面
	fprintf(fl,"%s\n","本次演算法中的各引數如下:");
	fprintf(fl,"alpha=%.3lf, betra=%.3lf, rou=%.3lf, Q=%.3lf\n",alpha,betra,rou,Q);
	fprintf(fl,"%s %d\n","本次演算法迭代次數為:",NcMax);
	fprintf(fl,"%s %.4lf\n","本演算法得出的最短路徑長度為:",bestsolution);
	fprintf(fl,"%s\n","本演算法求得的最短路徑為:");
	for(i=0; i<N; ++i)
		fprintf(fl,"%s →  ",coords[bestway[i]].city);
	fprintf(fl,"%s",coords[bestway[0]].city);
	fprintf(fl,"\n\n\n");
	fclose(fl);
	return ;
}

int main()
{
	int NC=0;//迭代次數
	int i,j,k;
	int s;
	double drand,pro,psum;
	FILE *fp;
	Initialize();
	fp = fopen("coords.txt","r+");
	Inputcoords(fp);
	GreateGraph();
	fclose(fp);
	for(i=0; i<N; ++i)//初始化
	{
		for(j=0; j<N; ++j)
		{
			phe[i][j]=IN; //資訊素初始化
			if(i!=j)
			yita[i][j]=100.0/graph[i][j];  //期望值,與距離成反比
		}
	}
	memset(map,-1,sizeof(map));  //把螞蟻走的路線置空
	memset(vis,0,sizeof(vis));  //0表示未訪問,1表示已訪問
	srand(time(NULL));
	while(NC++<=NcMax)//迭代次數小於等於最大值
	{
		for(k=0; k<M; ++k)
		{
			map[k][0]=(k+NC)%N; //給每隻螞蟻分配一個起點,並且保證起點在N個城市裡
			vis[k][map[k][0]]=1; //將起點標記為已經訪問,第k個螞蟻第1個點標記為訪問。每個螞蟻都有一個map
		}
		s=1;//當前每個螞蟻應該走的第幾個城市,下標從0開始,0是每個螞蟻的起點且已經走過
		while(s<N)
		{
			for(k=0; k<M; ++k)//為第k個螞蟻選擇下一個城市
			{
				psum=0;//Pij(概率)的分母部分,按照公式來計算
				for(j=0; j<N; ++j)
				{
					if(vis[k][j]==0)
					{
						psum+=pow(phe[map[k][s-1]][j],alpha)*pow(yita[map[k][s-1]][j],betra);
					}
				}
				drand=(double)(rand()%5000);
				drand/=5000.0;  //生成一個小於1的隨機數(輪盤隨機)
				pro=0;//累計的概率之和,當和大於隨機數的時候,代表選中當前城市,很形象的模擬
				for(j=0; j<N; ++j)
				{
					if(vis[k][j]==0)
					pro+=pow(phe[map[k][s-1]][j],alpha)*pow(yita[map[k][s-1]][j],betra)/psum;
					if(pro>drand)
					break;
				}
				vis[k][j]=1;  //將走過的城市標記起來(選中j,將j標記)
				map[k][s]=j;  //記錄城市的順序
			}
			s++;
		}//一次迭代完成
		memset(add,0,sizeof(add));
		for(k=0; k<M; ++k)  //計算本次中的最短路徑//
		{
			solution[k]=Distance(map[k]);  //螞蟻k所走的路線的總長度
			if(solution[k]<bestsolution)
			{
				bestsolution=solution[k];
				for(i=0; i<N; ++i)
					bestway[i]=map[k][i];//記錄當前最好的路徑
			}
		}
		for(k=0; k<M; ++k)
		{
			for(j=0; j<N-1; ++j)//計算路徑上資訊素的增量
			{
				add[map[k][j]][map[k][j+1]]+=Q/solution[k];
			}
			add[N-1][0]+=Q/solution[k];//首尾相接
		}
		for(i=0; i<N; ++i)
		{
			for(j=0; j<N; ++j)
			{
				phe[i][j]=phe[i][j]*rou+add[i][j];//更新資訊素
				if(phe[i][j]<0.0001)  //設立一個下界
					phe[i][j]=0.0001;
				else if(phe[i][j]>20)  //設立一個上界,防止啟發因子的作用被淹沒
					phe[i][j]=20;
			}
		}
		memset(vis,0,sizeof(vis));
		memset(map,-1,sizeof(map));
	}

	Result();
	printf("Result is saved in out.txt\n");
	return 0;
}
輸入檔案coords.txt:格式(序號,橫座標,縱座標,城市代號)
0,1,1,a
1,1,2,b
2,1,3,c
3,1,4,d
4,1,5,e
5,1,6,f
6,1,7,g
7,1,8,h
8,1,9,i
9,1,10,j
10,2,11,k
11,7,11,l
12,12,11,m
13,17,11,n
14,22,11,o
15,27,11,p
16,32,11,q
17,37,11,r
18,42,11,s
19,47,11,t
20,52,11,u
21,57,11,v
22,62,11,w
23,67,11,x
24,72,11,y
25,77,11,z
26,82,11,A
27,87,11,B
28,92,11,C
29,97,11,D
30,101,10,E
31,101,9,F
32,101,8,G
33,101,7,H
34,101,6,I
35,101,5,J
36,101,4,K
37,101,3,L
38,101,2,M
39,100,1,N
40,95,1,O
41,90,1,P
42,85,1,Q
43,80,1,R
44,75,1,S
45,70,1,T
46,65,1,U
47,60,1,V
48,55,1,W
49,50,1,X
50,45,1,Y
51,40,1,Z

輸出結果
本次演算法中的各引數如下:
alpha=2.000, betra=4.000, rou=0.500, Q=50.000
本次演算法迭代次數為: 1000
本演算法得出的最短路徑長度為: 217.9515
本演算法求得的最短路徑為:
j →  k →  l →  m →  n →  o →  p →  q →  r →  s →  t →  u →  v →  w →  x →  y →  z →  
A →  B →  C →  D →  E →  F →  G →  H →  I →  J →  K →  L →  M →  N →  O →  P →  Q →  
R →  S →  T →  U →  V →  W →  X →  Y →  Z →  a →  b →  c →  d →  e →  f →  g →  h →  i →  j



相關推薦

演算法TSP問題

添加了部分註釋,幾乎沒有改動(引數和城市格式略做改動),原博主的程式碼寫的很容易理解,也是我找到的最短的程式碼了,在此感謝。 程式碼如下: //蟻群演算法關於簡單的TSP問題求解// #include<stdio.h> #include<std

C++:演算法解決TSP(C++多執行緒版)

TSP問題:旅行商問題,最短迴路。 這裡採用att48資料,鄰接矩陣全部取整數,原資料放在文後。 解決程式碼如下: //#define TEST_INPUT //#define TEST_T //#define TEST_ANT //#define TEST_VALUE #

記一次演算法解決TSP問題

演算法規則 1)範圍 螞蟻觀察到的範圍是一個方格世界,螞蟻有一個引數為速度半徑(一般是3),那麼它能觀察到的範圍就是3*3個方格世界,並且能移動的距離也在這個範圍之內。 2)摺疊環境 螞蟻所在的環境是一個虛擬的世界,其中有障礙物,有別的螞蟻,還有資訊素,資訊素有兩種,一種是找到食物的

演算法解決tsp問題

控制蟻群演算法走向的關鍵是資訊素,資訊素類似遺傳演算法的適應性函式,類似退火演算法的評價函式,影響著其中一隻螞蟻的下一步的選擇。 螞蟻:類似遺傳演算法的染色體,就是一條解,在tsp問題中螞蟻的路徑就是tsp的解。 資訊素:評價函式,與路徑成反比 螞蟻數量:一次迭代有多少隻螞

演算法實現TSP(旅行商)問題(java語言)

旅行商問題,即TSP問題(Traveling Salesman Problem)是數學領域中著名問題之一。假設有一個旅行商人要拜訪N個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而

ACO演算法解決TSP旅行商問題

前言 蟻群演算法也是一種利用了大自然規律的啟發式演算法,與之前學習過的GA遺傳演算法類似,遺傳演算法是用了生物進行理論,把更具適應性的基因傳給下一代,最後就能得到一個最優解,常常用來尋找問題的最優解。當然,本篇文章不會主講GA演算法的,想要了解的同學可以檢視,我的和遺傳演算

演算法原理詳和matlab程式碼

1原理: 螞蟻在尋找食物源的時候,能在其走過的路徑上釋放一種叫資訊素的激素,使一定範圍內的其他螞蟻能夠察覺到。當一些路徑上通過的螞蟻越來越多時,資訊素也就越來越多,螞蟻們選擇這條路徑的概率也就越高,結果導致這條路徑上的資訊素又增多,螞蟻走這條路的概率又增加,生生

旅行商問題TSP演算法Java)

旅行商問題,即TSP問題(Traveling Salesman Problem)是數學領域中著名問題之一。假設有一個旅行商人要拜訪N個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最後要 回到原來出發的城市。路徑的選擇目標是要求得的路徑路程為所有路徑之中

【機器學習】利用演算法求解旅行商(TSP)問題

如果喜歡這裡的內容,你能夠給我最大的幫助就是轉發,告訴你的朋友,鼓勵他們一起來學習。 If you like the content here, you can give me the greatest help is forwarding, tell you

基於演算法求解求解TSP問題(JAVA)

一、TSP問題 TSP問題(Travelling Salesman Problem)即旅行商問題,又譯為旅行推銷員問題、貨郎擔問題,是數學領域中著名問題之一。假設有一個旅行商人要拜訪n個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最後要回到原來出發的

TSP問題中,演算法的應用

1. 蟻群演算法簡介      蟻群演算法(Ant Clony Optimization, ACO)是一種群智慧演算法,它是由一群無智慧或有輕微智慧的個體(Agent)通過相互協作而表現出智慧行為,從而為求解複雜問題提供了一個新的可能性。蟻群演算法最早是由義大利學者Colo

MATLAB演算法TSP詳細註釋

某大神寫的MATLAB蟻群演算法解TSP程式,自己看了好久才看懂,所以加上了更加詳細的註釋,借花獻佛了吧 實現函式 function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=ACATSP(C,NC_max,m

從”眾人拾柴火焰高“看"演算法"如何得最優

一、概述 題目雖然起的很文藝,不過從我對該演算法的理解,蟻群演算法著實有這麼點意思。接下來我將用”土話“幫助大家理解一下該演算法。 蟻群演算法是一種用來尋找優化路徑的概率型演算法。它由Marco Dorigo於1992年在他的博士論文中提出,其靈感來源於螞蟻在尋找食物過

TSP問題及演算法理解與實現

/** * Created by coco on 17-10-20. */ import java.io.*; import java.util.logging.Logger; import static java.util.logging.Logger.getLogger; public class

演算法(詳)python

only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices因為要做數學建模,所以學一下蟻群演算法。在

演算法學習

** 蟻群演算法的基本原理(簡單概括): ** 剛開始螞蟻按照同等概率選擇各條路徑。 螞蟻在經過的路徑下留下資訊素。 短的路徑螞蟻會率先找到食物源,因此資訊素濃度偏大。 由於資訊素的揮發,較長路徑上的資訊素逐漸消失 特點:正反饋;不容易陷入區域

【機器學習筆記35】演算法

【參考資料】 【1】《蟻群演算法原理及其應用》 【2】測試資料: https://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/tsp/att48.tsp.gz 演算法原理(以TSP問題為例) (1)引數初始化。令時間t=0和迴圈次數

演算法matlab

(一)蟻群演算法的由來 蟻群演算法最早是由Marco Dorigo等人在1991年提出,他們在研究新型演算法的過程中,發現蟻群在尋找食物時,通過分泌一種稱為資訊素的生物激素交流覓食資訊從而能快速的找到目標,據此提出了基於資訊正反饋原理的蟻群演算法。 蟻群演算法的基本思想來源於自然界螞

簡單易懂,演算法解決旅行商問題

轉載宣告: 原文把蟻群解決旅行商問題寫的很清楚,只不過本人認為原文中有一些小錯誤,特此更改(文中紅色加粗字型為改正處),程式碼中出現的一些演算法的小問題也進行了更正(比如程式碼中的貪心演算法),程式碼也附在下面,謝謝博主的分享。 1.關於旅行商(TSP)問題及衍化

智慧演算法---演算法

  1 蟻群演算法及其基本思想 蟻群演算法是一種智慧優化演算法,通過蟻群優化求解複雜問題,ACO在離散優化問題方面有比較好的優越性。     基本思想(以旅行商問題為例)       &nbs