# TSP問題(使用JAVA)
原代碼:https://github.com/chyhhwen/tsp-java
## 主要
### 設定初始值
```
private void set()
{
chromosomeSize = 8;//幾條染色體
generationSize = 10000;//世代次數
crossoverRate = 0.75;//交配率
crossoverSize = 2; // 交配池大小
mutationRate = 0.1;//突變率
}
```
### 產生城市
```
public void city()
{
Random rand = new Random();
for(int i=0;i<size;i++)
{
int x = rand.nextInt(400)+50;
int y = rand.nextInt(400)+50;
point[i][0] = x;
point[i][1] = y;
}
}
```
### 距離演算
公式:根號(平方(x2-x1)+平方(y2-y1))
```
public void distance()
{
int x[] = new int[2];
int y[] = new int[2];
float ans[] = new float[3];
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
if(i == j)
{
dist[i][j] = 0;
}
else
{
x[0] = point[i][0];
x[1] = point[j][0];
y[0] = point[i][1];
y[1] = point[j][1];
ans[1] = (float) Math.pow(Math.abs(x[0]-x[1]),2);
ans[2] = (float)Math.pow(Math.abs(y[0]-y[1]),2);
ans[0] = (float) Math.sqrt(ans[1]+ans[2]);
dist[i][j] = ans[0];
}
}
}
}
```
### 總距離存取
父距離
```
public float totaldistance(int j)
{
totaldist[j] = 0;
for(int i=0;i<size-1;i++)
{
totaldist[j] += dist[Chromosome[j][i]][Chromosome[j][i+1]];
}
return totaldist[j];
}
```
子距離
```
public float totalChoose(int j)
{
totaldist[j+size] = 0;
for(int i=0;i<size-1;i++)
{
totaldist[j+size] += dist[ChooseChromosome[j][i]][ChooseChromosome[j][i+1]];
}
return totaldist[j+size];
}
```
### 生成染色體
```
public void generateChromosome()
{
for(int i=0;i<chromosomeSize;i++)
{
Vector v = new Vector();
for(int j=0;j<size;j++)
{
v.add(j);
}
int length = v.size();
Random rand = new Random();
for (int j = 0 ; j < length ; j++)
{
int r = rand.nextInt(size - j);
int a = (int)v.get(r);
Chromosome[i][j] = a;
v.remove(r);
}
}
}
```
### 選擇兩組染色體
```
public void selection()//選擇染色體 //選四個dna
{
Vector v = new Vector();
for(int j=0;j<chromosomeSize;j++)
{
v.add(j);
}
int length = crossoverSize*2;
Random rand = new Random();
for (int j = 0 ; j < length ; j++)
{
int r = rand.nextInt(chromosomeSize - j);
int a = (int)v.get(r);
select[j] = a;
v.remove(r);
}
}
```
### 選擇一組染色體
```
public void selectiontwo()//選擇2條染色體
{
Vector v = new Vector();
int length = crossoverSize*2;
for(int j=0;j<length;j++)
{
v.add(j);
}
Random rand = new Random();
for (int j = 0 ; j < crossoverSize ; j++)
{
int r = rand.nextInt(length - j);
int a = (int)v.get(r);
finalselect[j] = a;
v.remove(r);
}
}
```
### 交配
機率交配
```
public void crossover()//交配
{
Random rand = new Random();
if(rand.nextDouble() < crossoverRate)
{
swap( finalselect[0],finalselect[1]);
}
}
```
雙點交換
```
public void swap(int a,int b)
{
Random rand = new Random();
first = rand.nextInt(size);
second = rand.nextInt(size);
Vector father = new Vector();
Vector mother = new Vector();
Vector baby = new Vector();
for (int i=0;i<size;i++)
{
int fa_put = Chromosome[select[finalselect[a]]][i];
father.add(fa_put);
int ma_put = Chromosome[select[finalselect[b]]][i];
mother.add(ma_put);
}
if(first>second)
{
int temp = first;
first = second;
second = temp;
}
int mother_length = mother.size()-1;
int time = 0;
for(int i=first;i<=second;i++)
{
int fa_get = (int) father.get(i);
baby.add(fa_get);
for(int j=0;j<mother_length - time;j++)
{
int ma_get = (int) mother.get(j);
if(ma_get == fa_get)
{
mother.remove(j);
time ++ ;
}
}
}
mother_length = mother.size();
for(int i=0;i<mother_length;i++)
{
int ma_get = (int) mother.get(i);
baby.add(ma_get);
}
for(int i=0;i<size;i++)
{
int ba_get = (int) baby.get(i);
ChooseChromosome[choosetime][i] = ba_get;
}
choosetime ++;
}
```
### 突變
單點交換
```
public void mutation()
{
Random rand = new Random();
for (int i=0;i<choosetime;i++)
{
for(int j=0;j<size;j++)
{
if(rand.nextDouble() < mutationRate)
{
int change = rand.nextInt(size);
int temp = ChooseChromosome[i][j];
ChooseChromosome[i][j] = ChooseChromosome[i][change];
ChooseChromosome[i][j] = temp;
}
}
}
}
```
### 暫存
存取當代所有染色體
```
public void storage(int time)
{
switch (time)
{
case 1:
for (int i=0;i < chromosomeSize;i++)
{
for(int j=0;j < size;j++)
{
Temporary[i][j] = Chromosome[i][j];
}
Temporary[i][size] = (int)totaldistance(i);
}
break;
case 2:
for (int i=0;i < choosetime;i++)
{
for(int j=0;j < size ;j++)
{
Temporary[i+chromosomeSize][j] = ChooseChromosome[i][j];
}
Temporary[i+chromosomeSize][size] = (int)totalChoose(i);
}
break;
default:
System.out.println("ERROR 404");
break;
}
}
```
### 選擇
選擇最好的前幾位
```
public void choose()
{
int length = chromosomeSize+choosetime;
int math[] = new int [length];
for (int i=0;i<length;i++)
{
math[i] = Temporary[i][size];
}
for(int i=0;i<length;i++)
{
for(int j=0;j<length;j++)
{
if (math[j] > math[i])
{
int temp = math[j];
math[j] = math[i];
math[i] = temp;
}
}
}
for (int i=0;i<chromosomeSize;i++)
{
for(int j=0;j<length;j++)
{
if(Temporary[j][size] == math [i])
{
for (int o=0;o<size;o++)
{
Chromosome[i][o] = Temporary[j][o];
}
math[i] = -1;
}
}
}
}
```
## 繪圖
```
public void paint(Graphics g)
{
set();
city();
for(int i=0;i<size;i++)
{
System.out.println("city:" + i +"("+point[i][0]+","+point[i][1]+")");
}
g.setColor(Color.red);
for(int i=0;i<size;i++)
{
g.fillOval(point[i][0],point[i][1],10,10);
try
{
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
distance();
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
System.out.print((int) dist[i][j] + "\t");
}
System.out.println("");
}
generateChromosome();
for (int i=0;i< chromosomeSize;i++)
{
System.out.print("[");
for(int j=0;j<size-1;j++)
{
System.out.print(Chromosome[i][j] + " , ");
}
System.out.println(Chromosome[i][size-1] + "] total:" + totaldistance(i));
}
for(int k=0;k<generationSize;k++)
{
System.out.println("第"+(k+1)+"代");
choosetime = 0;
for(int t =0;t<crossoverSize*2;t++)
{
storage(1);
selection();
selectiontwo();
crossover();
mutation();
storage(2);
}
choose();
distance();
for (int i = 0; i < chromosomeSize; i++)
{
System.out.print("[");
for (int j = 0; j < size - 1; j++)
{
System.out.print(Chromosome[i][j] + " , ");
}
System.out.println(Chromosome[i][size - 1] + "] total:" + totaldistance(i));
}
for(int i=0;i<size-1;i++)
{
g.setColor(Color.blue);
g.drawLine(point[Chromosome[0][i]] [0]+ 5, point[Chromosome[0][i]][1] + 5,
point[Chromosome[0][i+1]][0] + 5, point[Chromosome[0][i+1]][1] + 5);
try {
Thread.sleep(0);
} catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
for(int i=0;i<size-1;i++)
{
g.setColor(Color.white);
g.drawLine(point[Chromosome[0][i]] [0]+ 5, point[Chromosome[0][i]][1] + 5,
point[Chromosome[0][i+1]][0] + 5, point[Chromosome[0][i+1]][1] + 5);
try {
Thread.sleep(0);
} catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
for(int i=0;i<size-1;i++)
{
g.setColor(Color.red);
g.drawLine(point[Chromosome[0][i]] [0]+ 5, point[Chromosome[0][i]][1] + 5,
point[Chromosome[0][i+1]][0] + 5, point[Chromosome[0][i+1]][1] + 5);
try {
Thread.sleep(1);
} catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
try
{
Thread.sleep(1000000);
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
```