禁忌搜索演算法c
『壹』 哪個大神有時間幫我對VRP問題用禁忌搜索演算法編寫一個lingo或者c語言可以
求最短配送路徑的話 應該是TSP問題吧,不應該是VRP問題。
LINGO能很好地求解這兩類模型,但用的整數規劃原理或動態規劃原理,不能用禁忌搜索。
禁忌搜索,就用C或許能解決。
『貳』 禁忌搜索演算法的其他演算法
禁忌搜索是對人類思維過程本身的一種模擬,它通過對一些局部最優解的禁忌(也可以說是記憶)達到接納一部分較差解,從而跳出局部搜索的目的.
遺傳演算法是基於生物進化的原理發展起來的一種廣為應用的、高效的隨機搜索與優化的方法。其主要特點是群體搜索策略和群體中個體之間的信息交換,搜索不依賴於梯度信息。
螞蟻演算法是群體智能可用於解決其他組合優化問題,比如有n個城市,需要對所有n個城市進行訪問且只訪問一次的最短距離。
『叄』 禁忌搜索演算法的簡介
又名「tabu搜索演算法」
為了找到「全局最優解」,就不應該執著於某一個特定的區域。局部搜索的缺點就是太貪婪地對某一個局部區域以及其鄰域搜索,導致一葉障目,不見泰山。禁忌搜索就是對於找到的一部分局部最優解,有意識地避開它(但不是完全隔絕),從而獲得更多的搜索區間。兔子們找到了泰山,它們之中的一隻就會留守在這里,其他的再去別的地方尋找。就這樣,一大圈後,把找到的幾個山峰一比較,珠穆朗瑪峰脫穎而出。
當兔子們再尋找的時候,一般地會有意識地避開泰山,因為他們知道,這里已經找過,並且有一隻兔子在那裡看著了。這就是禁忌搜索中「禁忌表(tabu list)」的含義。那隻留在泰山的兔子一般不會就安家在那裡了,它會在一定時間後重新回到找最高峰的大軍,因為這個時候已經有了許多新的消息,泰山畢竟也有一個不錯的高度,需要重新考慮,這個歸隊時間,在禁忌搜索裡面叫做「禁忌長度(tabu length)」;如果在搜索的過程中,留守泰山的兔子還沒有歸隊,但是找到的地方全是華北平原等比較低的地方,兔子們就不得不再次考慮選中泰山,也就是說,當一個有兔子留守的地方優越性太突出,超過了「best so far」的狀態,就可以不顧及有沒有兔子留守,都把這個地方考慮進來,這就叫「特赦准則(aspiration criterion)」。這三個概念是禁忌搜索和一般搜索准則最不同的地方,演算法的優化也關鍵在這里。
『肆』 禁忌搜索演算法的介紹
禁忌(Tabu Search)演算法是一種亞啟發式(meta-heuristic)隨機搜索演算法1,它從一個初始可行解出發,選擇一系列的特定搜索方向(移動)作為試探,選擇實現讓特定的目標函數值變化最多的移動。為了避免陷入局部最優解,TS搜索中採用了一種靈活的「記憶」技術,對已經進行的優化過程進行記錄和選擇,指導下一步的搜索方向,這就是Tabu表的建立。
『伍』 c++ 求禁忌搜索演算法與遺傳演算法結合的代碼
//個體編碼方案:十進制的數列,1至26代表A至Z
//交配方法:使用整數編碼的交配規則的常規交配法,
//變異方法 :使用基於次序的變異,隨機的產生兩個變異位,然後交換這兩個變異位上的基因
//新種群構成方法:輪盤賭法進行篩選
//演算法結束條件:種群不再發生變化時停止
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<cmath>
#include<time.h>
#define random(x) (rand()%x)//隨機整數
#define initial {0,2,11,1,8,16,5,19,12,4,15,17,6,18,14,9,7,3,10,13}//隨機初值
using namespace std;
//參數
int city_number;
double pm = 0.92;
double initiall = 280;//種群數量
double length_table[26][26];
double pc = 0.02;
struct node
{
char name;
int num;
double x;
double y;
};
struct answer
{
int i;
int jie[26];// 十進制的數列,1至26代表A至Z
double length;
};
double f(int* x)
{
double fi = 0;
for(int i = 0; i < city_number-1; i++)
{
fi = fi + length_table[x[i]][x[i+1]];
}
fi = fi + length_table[x[city_number-1]][x[0]];
return fi;
}
double p(double fi,double fj,double t)
{
double P = exp(-(fj-fi)/t);
return P;
}
int main(int argc,char*argv[])
{
time_t tm; time(&tm);
int flag1 = tm;
int cities;
ifstream in(argv[1]);
in >> cities;
city_number = cities;
node* nodes = new node[city_number];
for(int i = 0; i < cities; i++)
{
in >> nodes[i].name >> nodes[i].x >> nodes[i].y;
nodes[i].num = i;
}
//cout << cities<<endl;
//for(int i = 0; i < cities; i++)
// cout <<nodes[i].name <<" "<< nodes[i].x <<" "<< nodes[i].y<<endl;
int i,j;
for(i = 0; i < cities; i++)
{
length_table[i][i] = (double)INT_MAX;
for(j = i+1; j < cities; j++)
{
length_table [i][j] = length_table[j][i] =sqrt(
(nodes[i].x - nodes[j].x) * (nodes[i].x - nodes[j].x) +
(nodes[i].y - nodes[j].y) * (nodes[i].y - nodes[j].y) );
//cout << length_table [i][j]<<endl;
}
}
ofstream out(argv[2]);
///////////////////////////////////////////////////////////初始設定
double t= initiall;//種群數量
int* temp = new int[cities]; answer* Ans1 = new answer;//群體
answer* Ans2 = new answer;//種群
int text[20] = initial;
int* son1 = new int[cities];
int* son2 = new int[cities];
for(int i = 0; i < cities; i++) {
temp[i] = i; Ans1->jie[i] = temp[i];
Ans2->jie[i] = text[i];
//cout << Ans2->jie[i]<<endl;
}
Ans1->length = f(Ans1->jie);
Ans2->length = f(Ans2->jie);
if(cities<15)Ans2->length =10000;
//cout << Ans2->length;
Ans1->i = random(cities);
//cout <<Ans1->i<<endl;
int pre_length = 0;
//
while(Ans1->length!=pre_length)//種群不再發生變化時停止
{
time(&tm);
double fenmu = 0;//輪盤賭法進行選擇
for(int i = 0; i < cities*cities; i++)
{
fenmu = fenmu + 1/Ans1->length;
}
int j1 = 0;double s1 = 0;int r1 = rand();
while(s1*32767<=r1) { s1 = s1 + (1/Ans1->length)/fenmu; j1++; }
int j2 = 0;double s2 = 0;int r2 = rand();
while(s2*32767<=r2) { s2 = s2 + (1/Ans1->length)/fenmu; j2++; }
if(tm-flag1>270)break;
pre_length = Ans1->length;
for(int i = 0; i < 100*cities; i++)//
{
int j = random(cities);
int text = temp[Ans1->i]; temp[Ans1->i] = temp[j]; temp[j] = text;
double length = f(temp);//f(j)
if(length < Ans1->length)
{
Ans1->i = j;
for(int l = 0; l < cities; l++)
Ans1->jie[l] = temp[l];
Ans1->length = length;
}
else if(p(length,Ans1->length,t)*32767 > rand())
{
Ans1->i = j;
for(int l = 0; l < cities; l++)
Ans1->jie[l] = temp[l];
Ans1->length = length;
}
}
t = t * pm;int point = random(cities);
//使用整數編碼的交配規則的常規交配法
for(int z = 0;z < point;z++) { son1[z] = Ans1->jie[z]; son2[z] = Ans1->jie[z]; }
int text1 = point;int text2 = point;int flag = 0;
for(int x = 0;x < cities;x++)
{
flag =0;
for(int c = 0;c< point;c++)
{
if(Ans1->jie[x]==son1[c])flag=1;
}
if(flag==0){ son1[text1] = Ans1->jie[x]; text1++; }
}
for(int x = 0;x < cities;x++)
{
flag =0;
for(int c = 0;c< point;c++)
{
if(Ans1->jie[x]==son2[c])flag=1;
}
if(flag==0){ son2[text2] = Ans1->jie[x]; text2++; }
}
if(Ans1->length<Ans2->length)
{
for(int m = 0; m < cities; m++)
Ans2->jie[m] = Ans1->jie[m];
Ans2->length = Ans1->length;
}
}
for(int l = 0; l < cities; l++)
{
out << char(Ans2->jie[l]+65)<<" ";
}
out <<Ans2->length<<endl;
return 0;
}
『陸』 跪求 用禁忌搜索演算法解組合優化,5個城市走一遍最優路徑,有沒有C或c++的源代碼
http://www.pudn.com/downloads114/sourcecode/math/detail477511.html
http://wenku..com/view/8de9ac5d3b3567ec102d8aa1.html
你自己改一下吧
『柒』 請問關於禁忌搜索演算法
禁忌(TabuSearch)演算法是一種亞啟發式(meta-heuristic)隨機搜索演算法[1],它從一個初始可行解出發,選擇一系列的特定搜索方向(移動)作為試探,選擇實現讓特定的目標函數值變化最多的移動。為了避免陷入局部最優解,TS搜索中採用了一種靈活的「記憶」技術,對已經進行的優化過程進行記錄和選擇,指導下一步的搜索方向,這就是Tabu表的建立。Tabu表中保存了最近若干次迭代過程中所實現的移動的反方向移動,凡是處於Tabu表中的移動,在當前迭代過程中是不允許實現的,這樣可以避免演算法重新訪問在最近若干次迭代過程中已經訪問過的解群,從而防止了循環,幫助演算法擺脫局部最優解。另外,為了盡可能不錯過產生最優解的「移動」,TS搜索還採用「釋放准則」的策略。
『捌』 禁忌搜索演算法源代碼
禁忌搜索法:使用一個禁忌表,記錄下不允許搜索的元素。在後面的搜索中,根據禁忌表來決定如何處理當前元素。用在約瑟夫環中,我們可以用一個數組記錄下已經出圈的人的編號,這樣再數數時,可以根據禁忌表來判斷此人是否還在圈內。
#define N 100
void yuesefu1(int data[],int result[],int sum,int k)
{
int i=0,j=0,count=0;
int n;
while(count<sum)
{
for(n=0;n<count;n++)/*根據禁忌表判斷此人是否還在圈內*/
if(result[n]==data[i])
break;
if(n>=count)/*若此人還在圈內*/
j++;
if(j==k)
{
result[count++]=data[i];/*把出圈的人的編號存入禁忌表*/
j=0;
}
i++;
if(i==sum)
i=0;
}
}
void main()
{
int data[N];
int result[N]={0};
int i,j,total,k;
printf("\nPlease input the number of every people.\n");
for(i=0;i<N;)
{
int input;
scanf("%d",&input);
if(input==0)
break;
for(j=0;j<i;j++)
if(data[j]==input)
break;
if(j>=i&&input>0)
{
data[i]=input;
i++;
}
else
printf("\nData error.Re-input:");
}
total=i;
printf("\nYou have input:\n");
for(i=0;i<total;i++)
{
if(i%10==0)
printf("\n");
printf("%4d",data[i]);
}
printf("\nPlease input a number to count:");
scanf("%d",&k);
yuesefu1(data,result,total,k);
printf("\nThe sequence is:\n");
for(i=0;i<total;i++)
printf("%d ",result[i]);
『玖』 禁忌搜索演算法的主要思想和特徵
禁忌演算法是一種亞啟發式隨機搜索演算法1,它從一個初始可行解出發,選擇一系列的特定搜索方向(移動)作為試探,選擇實現讓特定的目標函數值變化最多的移動。為了避免陷入局部最優解,TS搜索中採用了一種靈活的「記憶」技術,對已經進行的優化過程進行記錄和選擇,指導下一步的搜索方向,這就是Tabu表的建立。 禁忌搜索是對人類思維過程本身的一種模擬,它通過對一些局部最優解的禁忌(也可以說是記憶)達到接納一部分較差解,從而跳出局部搜索的目的.