整理資料搬運——退火算法Annealing的Java實現

直接上代碼:

package sa;

import java.util.ArrayList;
import java.util.List;

//
// 模擬退火算法解決TSP旅行商問題
//
public class SimulatedAnnealing {

	public static List<City> allCitys = new ArrayList<City>();

    //計算 接受的概率
    public static double acceptanceProbability(int energy, int newEnergy, double temperature) {
        // 如果新的解決方案較優,就接受
        if (newEnergy < energy) {
            return 1.0;
        }
        return Math.exp((energy - newEnergy) / temperature);
    }

	//返回近似的 最佳旅行路徑
	private static Tour sa() {
		// 初始化溫度
        double temp = 10000;

        // 冷卻概率
        double coolingRate = 0.003;

        // 初始化的解決方案
        Tour currentSolution = new Tour();
        currentSolution.generateIndividual();

        System.out.println("Initial solution distance: " + currentSolution.getDistance());

        // 設置當前爲最優的方案
        Tour best = new Tour(currentSolution.getTour());

        // 循環知道系統冷卻
        while (temp > 1) {
            // 生成一個鄰居
            Tour newSolution = new Tour(currentSolution.getTour());

            // 獲取隨機位置
            int tourPos1 = (int) (newSolution.tourSize() * Math.random());
            int tourPos2 = (int) (newSolution.tourSize() * Math.random());

            City citySwap1 = newSolution.getCity(tourPos1);
            City citySwap2 = newSolution.getCity(tourPos2);

            // 交換
            newSolution.setCity(tourPos2, citySwap1);
            newSolution.setCity(tourPos1, citySwap2);

            // 獲得新的解決方案的花費
            int currentEnergy = currentSolution.getDistance();
            int neighbourEnergy = newSolution.getDistance();

            // 決定是否接受新的 方案
            if (acceptanceProbability(currentEnergy, neighbourEnergy, temp) > Math.random()) {
                currentSolution = new Tour(newSolution.getTour());
            }

            // 記錄找到的最優方案
            if (currentSolution.getDistance() < best.getDistance()) {
                best = new Tour(currentSolution.getTour());
            }

            // 冷卻
            temp *= 1-coolingRate;
        }
		return best;
	}

	private static void init() {
		City city = new City(60, 200);
	    allCitys.add(city);
	    City city2 = new City(180, 200);
	    allCitys.add(city2);
	    City city3 = new City(80, 180);
	    allCitys.add(city3);
	    City city4 = new City(140, 180);
	    allCitys.add(city4);
	    City city5 = new City(20, 160);
	    allCitys.add(city5);
	    City city6 = new City(100, 160);
	    allCitys.add(city6);
	    City city7 = new City(200, 160);
	    allCitys.add(city7);
	    City city8 = new City(140, 140);
	    allCitys.add(city8);
	    City city9 = new City(40, 120);
	    allCitys.add(city9);
	    City city10 = new City(100, 120);
	    allCitys.add(city10);
	    City city11 = new City(180, 100);
	    allCitys.add(city11);
	    City city12 = new City(60, 80);
	    allCitys.add(city12);
	    City city13 = new City(120, 80);
	    allCitys.add(city13);
	    City city14 = new City(180, 60);
	    allCitys.add(city14);
	    City city15 = new City(20, 40);
	    allCitys.add(city15);
	    City city16 = new City(100, 40);
	    allCitys.add(city16);
	    City city17 = new City(200, 40);
	    allCitys.add(city17);
	    City city18 = new City(20, 20);
	    allCitys.add(city18);
	    City city19 = new City(60, 20);
	    allCitys.add(city19);
	    City city20 = new City(160, 20);
	    allCitys.add(city20);
	}
	
    public static void main(String[] args) {
        // 創建所有的城市城市列表
        init();
        
        //求解TSP問題
        Tour best = sa();
        System.out.println("Final solution distance: " + best.getDistance());
        System.out.println("Tour: " + best);
    }
}

package sa;

public class City {
    int x;
    int y;

    // 生成一個隨機的城市
    public City(){
        this.x = (int)(Math.random()*200);
        this.y = (int)(Math.random()*200);
    }

    public City(int x, int y){
        this.x = x;
        this.y = y;
    }

    public int getX(){
        return this.x;
    }

    public int getY(){
        return this.y;
    }

    // 計算兩個城市之間的距離
    public double distanceTo(City city){
        int xDistance = Math.abs(getX() - city.getX());
        int yDistance = Math.abs(getY() - city.getY());
        double distance = Math.sqrt( (xDistance*xDistance) + (yDistance*yDistance) );

        return distance;
    }

    @Override
    public String toString(){
        return getX()+", "+getY();
    }
}

package sa;

import java.util.ArrayList;
import java.util.Collections;

public class Tour{

    // 保持城市的列表
    private ArrayList tour = new ArrayList<City>();
    // 緩存距離
    private int distance = 0;

    // 生成一個空的路徑
    public Tour(){
        for (int i = 0; i < SimulatedAnnealing.allCitys.size(); i++) {
            tour.add(null);
        }
    }

    // 複製路徑
    public Tour(ArrayList tour){
        this.tour = (ArrayList) tour.clone();
    }

    public ArrayList getTour(){
        return tour;
    }

    // Creates a random individual
    public void generateIndividual() {
        // Loop through all our destination cities and add them to our tour
        for (int cityIndex = 0; cityIndex < SimulatedAnnealing.allCitys.size(); cityIndex++) {
          setCity(cityIndex, SimulatedAnnealing.allCitys.get(cityIndex));
        }
        // 隨機的打亂路徑
        Collections.shuffle(tour);
    }

    // 獲取一個城市
    public City getCity(int tourPosition) {
        return (City)tour.get(tourPosition);
    }

    public void setCity(int tourPosition, City city) {
        tour.set(tourPosition, city);
        // 重新計算距離
        distance = 0;
    }

    // 獲得當前距離的 總花費
    public int getDistance(){
        if (distance == 0) {
            int tourDistance = 0;
            for (int cityIndex=0; cityIndex < tourSize(); cityIndex++) {
                City fromCity = getCity(cityIndex);
                City destinationCity;
                if(cityIndex+1 < tourSize()){
                    destinationCity = getCity(cityIndex+1);
                }
                else{
                    destinationCity = getCity(0);
                }
                tourDistance += fromCity.distanceTo(destinationCity);
            }
            distance = tourDistance;
        }
        return distance;
    }

    // 獲得當前路徑中城市的數量
    public int tourSize() {
        return tour.size();
    }

    @Override
    public String toString() {
        String geneString = "|";
        for (int i = 0; i < tourSize(); i++) {
            geneString += getCity(i)+"|";
        }
        return geneString;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章