一、人工蜂群演算法的介紹
人工蜂群演算法(Artificial Bee Colony, ABC)是由Karaboga於2005年提出的一種新穎的基於群智能的全局優化演算法,其直觀背景來源於蜂群的采蜜行為,蜜蜂根據各自的分工進行不同的活動,並實現蜂群信息的共享和交流,從而找到問題的最優解。人工蜂群演算法屬於群智能演算法的一種。
二、人工蜂群演算法的原理
1、原理
標準的ABC演算法通過模擬實際蜜蜂的采蜜機制將人工蜂群分為3類: 采蜜蜂、觀察蜂和偵察蜂。整個蜂群的目標是尋找花蜜量最大的蜜源。在標準的ABC演算法中,采蜜蜂利用先前的蜜源信息尋找新的蜜源並與觀察蜂分享蜜源信息;觀察蜂在蜂房中等待並依據采蜜蜂分享的信息尋找新的蜜源;偵查蜂的任務是尋找一個新的有價值的蜜源,它們在蜂房附近隨機地尋找蜜源。
假設問題的解空間是。
代碼:
[cpp]view plain
#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<cmath>
#include<fstream>
#include<iomanip>
usingnamespacestd;
constintNP=40;//種群的規模,采蜜蜂+觀察蜂
constintFoodNumber=NP/2;//食物的數量,為采蜜蜂的數量
constintlimit=20;//限度,超過這個限度沒有更新采蜜蜂變成偵查蜂
constintmaxCycle=10000;//停止條件
/*****函數的特定參數*****/
constintD=2;//函數的參數個數
constdoublelb=-100;//函數的下界
constdoubleub=100;//函數的上界
doubleresult[maxCycle]={0};
/*****種群的定義****/
structBeeGroup
{
doublecode[D];//函數的維數
doubletrueFit;//記錄真實的最小值
doublefitness;
doublerfitness;//相對適應值比例
inttrail;//表示實驗的次數,用於與limit作比較
}Bee[FoodNumber];
BeeGroupNectarSource[FoodNumber];//蜜源,注意:一切的修改都是針對蜜源而言的
BeeGroupEmployedBee[FoodNumber];//采蜜蜂
BeeGroupOnLooker[FoodNumber];//觀察蜂
BeeGroupBestSource;//記錄最好蜜源
/*****函數的聲明*****/
doublerandom(double,double);//產生區間上的隨機數
voidinitilize();//初始化參數
doublecalculationTruefit(BeeGroup);//計算真實的函數值
doublecalculationFitness(double);//計算適應值
voidCalculateProbabilities();//計算輪盤賭的概率
voidevalueSource();//評價蜜源
voidsendEmployedBees();
voidsendOnlookerBees();
voidsendScoutBees();
voidMemorizeBestSource();
/*******主函數*******/
intmain()
{
ofstreamoutput;
output.open("dataABC.txt");
srand((unsigned)time(NULL));
initilize();//初始化
MemorizeBestSource();//保存最好的蜜源
//主要的循環
intgen=0;
while(gen<maxCycle)
{
sendEmployedBees();
CalculateProbabilities();
sendOnlookerBees();
MemorizeBestSource();
sendScoutBees();
MemorizeBestSource();
output<<setprecision(30)<<BestSource.trueFit<<endl;
gen++;
}
output.close();
cout<<"運行結束!!"<<endl;
return0;
}
/*****函數的實現****/
doublerandom(doublestart,doubleend)//隨機產生區間內的隨機數
{
returnstart+(end-start)*rand()/(RAND_MAX+1.0);
}
voidinitilize()//初始化參數
{
inti,j;
for(i=0;i<FoodNumber;i++)
{
for(j=0;j<D;j++)
{
NectarSource[i].code[j]=random(lb,ub);
EmployedBee[i].code[j]=NectarSource[i].code[j];
OnLooker[i].code[j]=NectarSource[i].code[j];
BestSource.code[j]=NectarSource[0].code[j];
}
/****蜜源的初始化*****/
NectarSource[i].trueFit=calculationTruefit(NectarSource[i]);
NectarSource[i].fitness=calculationFitness(NectarSource[i].trueFit);
NectarSource[i].rfitness=0;
NectarSource[i].trail=0;
/****采蜜蜂的初始化*****/
EmployedBee[i].trueFit=NectarSource[i].trueFit;
EmployedBee[i].fitness=NectarSource[i].fitness;
EmployedBee[i].rfitness=NectarSource[i].rfitness;
EmployedBee[i].trail=NectarSource[i].trail;
/****觀察蜂的初始化****/
OnLooker[i].trueFit=NectarSource[i].trueFit;
OnLooker[i].fitness=NectarSource[i].fitness;
OnLooker[i].rfitness=NectarSource[i].rfitness;
OnLooker[i].trail=NectarSource[i].trail;
}
/*****最優蜜源的初始化*****/
BestSource.trueFit=NectarSource[0].trueFit;
BestSource.fitness=NectarSource[0].fitness;
BestSource.rfitness=NectarSource[0].rfitness;
BestSource.trail=NectarSource[0].trail;
}
doublecalculationTruefit(BeeGroupbee)//計算真實的函數值
{
doubletruefit=0;
/******測試函數1******/
truefit=0.5+(sin(sqrt(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))*sin(sqrt(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))-0.5)
/((1+0.001*(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))*(1+0.001*(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1])));
returntruefit;
}
doublecalculationFitness(doubletruefit)//計算適應值
{
doublefitnessResult=0;
if(truefit>=0)
{
fitnessResult=1/(truefit+1);
}else
{
fitnessResult=1+abs(truefit);
}
returnfitnessResult;
}
voidsendEmployedBees()//修改采蜜蜂的函數
{
inti,j,k;
intparam2change;//需要改變的維數
doubleRij;//[-1,1]之間的隨機數
for(i=0;i<FoodNumber;i++)
{
param2change=(int)random(0,D);//隨機選取需要改變的維數
/******選取不等於i的k********/
while(1)
{
k=(int)random(0,FoodNumber);
if(k!=i)
{
break;
}
}
for(j=0;j<D;j++)
{
EmployedBee[i].code[j]=NectarSource[i].code[j];
}
/*******采蜜蜂去更新信息*******/
Rij=random(-1,1);
EmployedBee[i].code[param2change]=NectarSource[i].code[param2change]+Rij*(NectarSource[i].code[param2change]-NectarSource[k].code[param2change]);
/*******判斷是否越界********/
if(EmployedBee[i].code[param2change]>ub)
{
EmployedBee[i].code[param2change]=ub;
}
if(EmployedBee[i].code[param2change]<lb)
{
EmployedBee[i].code[param2change]=lb;
}
EmployedBee[i].trueFit=calculationTruefit(EmployedBee[i]);
EmployedBee[i].fitness=calculationFitness(EmployedBee[i].trueFit);
/******貪婪選擇策略*******/
if(EmployedBee[i].trueFit<NectarSource[i].trueFit)
{
for(j=0;j<D;j++)
{
NectarSource[i].code[j]=EmployedBee[i].code[j];
}
NectarSource[i].trail=0;
NectarSource[i].trueFit=EmployedBee[i].trueFit;
NectarSource[i].fitness=EmployedBee[i].fitness;
}else
{
NectarSource[i].trail++;
}
}
}
voidCalculateProbabilities()//計算輪盤賭的選擇概率
{
inti;
doublemaxfit;
maxfit=NectarSource[0].fitness;
for(i=1;i<FoodNumber;i++)
{
if(NectarSource[i].fitness>maxfit)
maxfit=NectarSource[i].fitness;
}
for(i=0;i<FoodNumber;i++)
{
NectarSource[i].rfitness=(0.9*(NectarSource[i].fitness/maxfit))+0.1;
}
}
voidsendOnlookerBees()//采蜜蜂與觀察蜂交流信息,觀察蜂更改信息
{
inti,j,t,k;
doubleR_choosed;//被選中的概率
intparam2change;//需要被改變的維數
doubleRij;//[-1,1]之間的隨機數
i=0;
t=0;
while(t<FoodNumber)
{
R_choosed=random(0,1);
if(R_choosed<NectarSource[i].rfitness)//根據被選擇的概率選擇
{
t++;
param2change=(int)random(0,D);
/******選取不等於i的k********/
while(1)
{
k=(int)random(0,FoodNumber);
if(k!=i)
{
break;
}
}
for(j=0;j<D;j++)
{
OnLooker[i].code[j]=NectarSource[i].code[j];
}
/****更新******/
Rij=random(-1,1);
OnLooker[i].code[param2change]=NectarSource[i].code[param2change]+Rij*(NectarSource[i].code[param2change]-NectarSource[k].code[param2change]);
/*******判斷是否越界*******/
if(OnLooker[i].code[param2change]<lb)
{
OnLooker[i].code[param2change]=lb;
}
if(OnLooker[i].code[param2change]>ub)
{
OnLooker[i].code[param2change]=ub;
}
OnLooker[i].trueFit=calculationTruefit(OnLooker[i]);
OnLooker[i].fitness=calculationFitness(OnLooker[i].trueFit);
/****貪婪選擇策略******/
if(OnLooker[i].trueFit<NectarSource[i].trueFit)
{
for(j=0;j<D;j++)
{
NectarSource[i].code[j]=OnLooker[i].code[j];
}
NectarSource[i].trail=0;
NectarSource[i].trueFit=OnLooker[i].trueFit;
NectarSource[i].fitness=OnLooker[i].fitness;
}else
{
NectarSource[i].trail++;
}
}
i++;
if(i==FoodNumber)
{
i=0;
}
}
}
❷ 用java解決tsp問題用什麼演算法最簡單
package noah;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class TxTsp {
private int cityNum; // 城市數量
private int[][] distance; // 距離矩陣
private int[] colable;//代表列,也表示是否走過,走過置0
private int[] row;//代錶行,選過置0
public TxTsp(int n) {
cityNum = n;
}
private void init(String filename) throws IOException {
// 讀取數據
int[] x;
int[] y;
String strbuff;
BufferedReader data = new BufferedReader(new InputStreamReader(
new FileInputStream(filename)));
distance = new int[cityNum][cityNum];
x = new int[cityNum];
y = new int[cityNum];
for (int i = 0; i < cityNum; i++) {
// 讀取一行數據,數據格式1 6734 1453
strbuff = data.readLine();
// 字元分割
String[] strcol = strbuff.split(" ");
x[i] = Integer.valueOf(strcol[1]);// x坐標
y[i] = Integer.valueOf(strcol[2]);// y坐標
}
data.close();
// 計算距離矩陣
// ,針對具體問題,距離計算方法也不一樣,此處用的是att48作為案例,它有48個城市,距離計算方法為偽歐氏距離,最優值為10628
for (int i = 0; i < cityNum - 1; i++) {
distance[i][i] = 0; // 對角線為0
for (int j = i + 1; j < cityNum; j++) {
double rij = Math
.sqrt(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])
* (y[i] - y[j])) / 10.0);
// 四捨五入,取整
int tij = (int) Math.round(rij);
if (tij < rij) {
distance[i][j] = tij + 1;
distance[j][i] = distance[i][j];
} else {
distance[i][j] = tij;
distance[j][i] = distance[i][j];
}
}
}
distance[cityNum - 1][cityNum - 1] = 0;
colable = new int[cityNum];
colable[0] = 0;
for (int i = 1; i < cityNum; i++) {
colable[i] = 1;
}
row = new int[cityNum];
for (int i = 0; i < cityNum; i++) {
row[i] = 1;
}
}
public void solve(){
int[] temp = new int[cityNum];
String path="0";
int s=0;//計算距離
int i=0;//當前節點
int j=0;//下一個節點
//默認從0開始
while(row[i]==1){
//復制一行
for (int k = 0; k < cityNum; k++) {
temp[k] = distance[i][k];
//System.out.print(temp[k]+" ");
}
//System.out.println();
//選擇下一個節點,要求不是已經走過,並且與i不同
j = selectmin(temp);
//找出下一節點
row[i] = 0;//行置0,表示已經選過
colable[j] = 0;//列0,表示已經走過
path+="-->" + j;
//System.out.println(i + "-->" + j);
//System.out.println(distance[i][j]);
s = s + distance[i][j];
i = j;//當前節點指向下一節點
}
System.out.println("路徑:" + path);
System.out.println("總距離為:" + s);
}
public int selectmin(int[] p){
int j = 0, m = p[0], k = 0;
//尋找第一個可用節點,注意最後一次尋找,沒有可用節點
while (colable[j] == 0) {
j++;
//System.out.print(j+" ");
if(j>=cityNum){
//沒有可用節點,說明已結束,最後一次為 *-->0
m = p[0];
break;
//或者直接return 0;
}
else{
m = p[j];
}
}
//從可用節點J開始往後掃描,找出距離最小節點
for (; j < cityNum; j++) {
if (colable[j] == 1) {
if (m >= p[j]) {
m = p[j];
k = j;
}
}
}
return k;
}
public void printinit() {
System.out.println("print begin....");
for (int i = 0; i < cityNum; i++) {
for (int j = 0; j < cityNum; j++) {
System.out.print(distance[i][j] + " ");
}
System.out.println();
}
System.out.println("print end....");
}
public static void main(String[] args) throws IOException {
System.out.println("Start....");
TxTsp ts = new TxTsp(48);
ts.init("c://data.txt");
//ts.printinit();
ts.solve();
}
}
❸ java中錯誤:沒有為類型 Tsp 定義方法 printBestRoute(),如何改,是在遺傳演算法實現中出現的問題
那就再定義下這個方法就好了吧
❹ 百度上提問:Java上怎樣讀取txt文件里的數據為一個多行兩列的數組,每一個數據由逗號隔開
public voidinit(String filename) throws FileNotFoundException, IOException{
//讀取數據
double[] x;
double[] y;
int num;
String strbuff;
BufferedReader tspdata = newBufferedReader(new InputStreamReader(new FileInputStream(filename)));
strbuff = tspdata.readLine();
int num =Integer.valueOf(strbuff);
// System.out.println(Integer.valueOf(strbuff));
x = new double[num];
y = new double[num];
for (int citys = 0; citys <num; citys++) {
strbuff = tspdata.readLine();
String[] strcol =strbuff.split(",");
x[citys] = Integer.valueOf(strcol[1]);
y[citys] =Integer.valueOf(strcol[2]);
}
}
❺ Java中的一些問題
1.定義變數時至少應指出變數名和類型嗎?
答:必須給出名稱和類型。
2.定義變數時沒有給出初值,該變數可能是無意義的值嗎??
答:類的成員變數會給出默認值,基本數據類型會是0,對象是null。局部變數不可以沒有初始值
3.定義變數同一個類型,多個變數可用逗號分隔嗎?
答:可以。
4.定義變數時必須要給變數初始化嗎??
答:成員變數可以不必初始化,局部變數一定要初始化。
5.定義變數而沒初始化時,該變數與默認值嗎??
答:成員變數有初始值,局部變數沒有
6.字元型變數的默認值為換行符嗎?
答:是
7.布爾型變數的默認值為真嗎?
答:false
8.變數的默認值是可以改變的嗎??
答:可以改變。
❻ java中,主類創建的對象,如何能在其他類中調用急急急!!
主類中創建的public對象,你可以在其他類中通過主類對象名.public對象名訪問,如果是private的話無法訪問,只有你在主類中寫public方法,然後通過方法調用。
❼ 菜鳥在Java 的tsp問題插入一個節點遇到了一個問題
while(temp.next!=null){
if(temp.next.p.distanceTo(p)<minDis){
nearestNode = temp;
}
temp = temp.next;
}
如果我沒看錯的話 temp.next!=null 這句代碼已經執行了指針指向下一個了。當然有可能是我搞錯了。
問題解決了嗎?採納一下我的答案吧。謝謝。
❽ 用java做一個java登錄監控程序,監控當前有多少個session有效,急~~~~
要監控session是否有效,就要變相的拿到session的主動權
比如你可以在頁面寫一個循環請求的ajax(這個循環需要是一個同步的請求)
如果用戶把頁面關掉了,那麼這個ajax所請求的方法也就終止了
你要做的就是在一定的時間內去檢測目標session的最後一次更新時間
❾ 求java上旅遊路線的規劃演算法
這個屬於TSP(旅行商)問題,搜索 旅行商問題 可以找到相關解法的介紹。
❿ 用java解決tsp問題用什麼演算法最簡單
用java解決tsp
package noah;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class TxTsp {
private int cityNum; // 城市數量
private int[][] distance; // 距離矩陣
private int[] colable;//代表列,也表示是否走過,走過置0
private int[] row;//代錶行,選過置0
public TxTsp(int n) {
cityNum = n;
}
private void init(String filename) throws IOException {
// 讀取數據
int[] x;
int[] y;
String strbuff;
BufferedReader data = new BufferedReader(new InputStreamReader(
new FileInputStream(filename)));
distance = new int[cityNum][cityNum];
x = new int[cityNum];
y = new int[cityNum];
for (int i = 0; i < cityNum; i++) {
// 讀取一行數據,數據格式1 6734 1453
strbuff = data.readLine();
// 字元分割
String[] strcol = strbuff.split(" ");
x[i] = Integer.valueOf(strcol[1]);// x坐標
y[i] = Integer.valueOf(strcol[2]);// y坐標
}
data.close();
// 計算距離矩陣
// ,針對具體問題,距離計算方法也不一樣,此處用的是att48作為案例,它有48個城市,距離計算方法為偽歐氏距離,最優值為10628
for (int i = 0; i < cityNum - 1; i++) {
distance[i][i] = 0; // 對角線為0
for (int j = i + 1; j < cityNum; j++) {
double rij = Math
.sqrt(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])
* (y[i] - y[j])) / 10.0);
// 四捨五入,取整
int tij = (int) Math.round(rij);
if (tij < rij) {
distance[i][j] = tij + 1;
distance[j][i] = distance[i][j];
} else {
distance[i][j] = tij;
distance[j][i] = distance[i][j];
}
}
}
distance[cityNum - 1][cityNum - 1] = 0;
colable = new int[cityNum];
colable[0] = 0;
for (int i = 1; i < cityNum; i++) {
colable[i] = 1;
}
row = new int[cityNum];
for (int i = 0; i < cityNum; i++) {
row[i] = 1;
}
}
public void solve(){
int[] temp = new int[cityNum];
String path="0";
int s=0;//計算距離
int i=0;//當前節點
int j=0;//下一個節點
//默認從0開始
while(row[i]==1){
//復制一行
for (int k = 0; k < cityNum; k++) {
temp[k] = distance[i][k];
//System.out.print(temp[k]+" ");
}
//System.out.println();
//選擇下一個節點,要求不是已經走過,並且與i不同
j = selectmin(temp);
//找出下一節點
row[i] = 0;//行置0,表示已經選過
colable[j] = 0;//列0,表示已經走過
path+="-->" + j;
//System.out.println(i + "-->" + j);
//System.out.println(distance[i][j]);
s = s + distance[i][j];
i = j;//當前節點指向下一節點
}
System.out.println("路徑:" + path);
System.out.println("總距離為:" + s);
}
public int selectmin(int[] p){
int j = 0, m = p[0], k = 0;
//尋找第一個可用節點,注意最後一次尋找,沒有可用節點
while (colable[j] == 0) {
j++;
//System.out.print(j+" ");
if(j>=cityNum){
//沒有可用節點,說明已結束,最後一次為 *-->0
m = p[0];
break;
//或者直接return 0;
}
else{
m = p[j];
}
}
//從可用節點J開始往後掃描,找出距離最小節點
for (; j < cityNum; j++) {
if (colable[j] == 1) {
if (m >= p[j]) {
m = p[j];
k = j;
}
}
}
return k;
}
public void printinit() {
System.out.println("print begin....");
for (int i = 0; i < cityNum; i++) {
for (int j = 0; j < cityNum; j++) {
System.out.print(distance[i][j] + " ");
}
System.out.println();
}
System.out.println("print end....");
}
public static void main(String[] args) throws IOException {
System.out.println("Start....");
TxTsp ts = new TxTsp(48);
ts.init("c://data.txt");
//ts.printinit();
ts.solve();
}
}