---
# System prepended metadata

title: TSP問題(使用JAVA)

---

# 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);
        }
    }
```
