Java 蚁群算法

蚁群算法(Ant Colony Optimization, ACO)是一种仿生智能算法,模仿蚂蚁在寻找食物过程中通过信息素进行路径选择的机制。它在解决组合优化问题,如旅行商问题(TSP)、车辆路径问题(VRP)等,具有较好的效果。以下是一个简单的Java实现,以旅行商问题(TSP)为例,展示如何使用蚁群算法进行路径优化。

步骤概述

  1. 初始化参数:包括蚂蚁数量、信息素挥发因子、信息素初始值、迭代次数等。
  2. 构建解空间:通常使用邻接矩阵表示城市之间的距离。
  3. 蚂蚁路径构建:每只蚂蚁根据信息素和启发式信息选择下一个城市。
  4. 更新信息素:所有蚂蚁完成路径后,根据路径长度更新路径上的信息素。
  5. 迭代:重复上述步骤,直到达到最大迭代次数或满足其他停止条件。

Java代码示例

以下是一个简化的Java实现:

import java.util.*;  
  
public class AntColonyOptimization {  
    private static final int NUM_CITIES = 10; // 城市数量  
    private static final int NUM_ANTS = 30;  // 蚂蚁数量  
    private static final int MAX_ITERATIONS = 1000; // 最大迭代次数  
    private static final double ALPHA = 1.0; // 信息素重要性因子  
    private static final double BETA = 5.0; // 启发式信息重要性因子  
    private static final double EVAPORATION_RATE = 0.5; // 信息素挥发因子  
    private static final double Q = 100.0; // 信息素常量  
  
    private double[][] distanceMatrix; // 城市距离矩阵  
    private double[][] pheromoneMatrix; // 信息素矩阵  
  
    public AntColonyOptimization() {  
        distanceMatrix = new double[NUM_CITIES][NUM_CITIES];  
        pheromoneMatrix = new double[NUM_CITIES][NUM_CITIES];  
        initializeDistanceMatrix();  
        initializePheromoneMatrix();  
    }  
  
    private void initializeDistanceMatrix() {  
        // 示例距离矩阵,这里使用随机值,实际应用中应使用实际距离  
        Random rand = new Random();  
        for (int i = 0; i < NUM_CITIES; i++) {  
            for (int j = 0; j < NUM_CITIES; j++) {  
                distanceMatrix[i][j] = rand.nextDouble() * 100;  
                if (i == j) {  
                    distanceMatrix[i][j] = 0;  
                }  
            }  
        }  
    }  
  
    private void initializePheromoneMatrix() {  
        for (int i = 0; i < NUM_CITIES; i++) {  
            for (int j = 0; j < NUM_CITIES; j++) {  
                pheromoneMatrix[i][j] = 1.0;  
            }  
        }  
    }  
  
    private double calculateTransitionProbability(int currentCity, List<Integer> visitedCities, double[] heuristic) {  
        double sum = 0.0;  
        for (int j = 0; j < NUM_CITIES; j++) {  
            if (!visitedCities.contains(j)) {  
                double pheromone = pheromoneMatrix[currentCity][j];  
                double heuristicValue = heuristic[j];  
                double prob = Math.pow(pheromone, ALPHA) * Math.pow(heuristicValue, BETA);  
                sum += prob;  
            }  
        }  
        for (int j = 0; j < NUM_CITIES; j++) {  
            if (!visitedCities.contains(j)) {  
                double pheromone = pheromoneMatrix[currentCity][j];  
                double heuristicValue = heuristic[j];  
                pheromoneMatrix[currentCity][j] = prob / sum;  
            }  
        }  
        return sum;  
    }  
  
    private double calculateHeuristic(int city) {  
        // 使用距离的倒数作为启发式信息  
        double sum = 0.0;  
        for (int i = 0; i < NUM_CITIES; i++) {  
            if (i != city) {  
                sum += 1.0 / distanceMatrix[city][i];  
            }  
        }  
        return 1.0 / sum;  
    }  
  
    private List<Integer> generateAntPath() {  
        List<Integer> path = new ArrayList<>();  
        boolean[] visited = new boolean[NUM_CITIES];  
        int startCity = new Random().nextInt(NUM_CITIES);  
        path.add(startCity);  
        visited[startCity] = true;  
  
        double[] heuristic = new double[NUM_CITIES];  
        for (int i = 0; i < NUM_CITIES; i++) {  
            heuristic[i] = calculateHeuristic(i);  
        }  
  
        for (int i = 1; i < NUM_CITIES; i++) {  
            int currentCity = path.get(path.size() - 1);  
            List<Integer> candidates = new ArrayList<>();  
            for (int j = 0; j < NUM_CITIES; j++) {  
                if (!visited[j]) {  
                    candidates.add(j);  
                }  
            }  
  
            double[] transitionProbs = new double[candidates.size()];  
            calculateTransitionProbability(currentCity, path, heuristic);  
  
            int nextCityIndex = 0;  
            double rand = new Random().nextDouble();  
            double cumulativeProb = 0.0;  
            for (int j = 0; j < candidates.size(); j++) {  
                cumulativeProb += pheromoneMatrix[currentCity][candidates.get(j)];  
                if (cumulativeProb >= rand) {  
                    nextCityIndex = j;  
                    break;  
                }  
            }  
  
            int nextCity = candidates.get(nextCityIndex);  
            path.add(nextCity);  
            visited[nextCity] = true;  
        }  
  
        // 完成路径,回到起点  
        path.add(startCity);  
  
        return path;  
    }  
  
    private void updatePheromoneMatrix(List<List<Integer>> allPaths) {  
        for (int i = 0; i < NUM_CITIES; i++) {  
            for (int j = 0; j < NUM_CITIES; j++) {  
                pheromoneMatrix[i][j] *= (1 - EVAPORATION_RATE);  
            }  
        }  
  
        for (List<Integer> path : allPaths) {  
            double totalLength = calculatePathLength(path);  
            for (int i = 0; i < path.size() - 1; i++) {  
                int city1 = path.get(i);  
                int city2 = path.get(i + 1);  
                pheromoneMatrix[city1][city2] += Q / totalLength;  
                pheromoneMatrix[city2][city1] += Q / totalLength; // 因为是无向图  
            }  
        }  
    }  
  
    private double calculatePathLength(List<Integer> path) {  
        double length = 0.0;  
        for (int i = 0; i < path.size() - 1; i++) {  
            int city1 = path.get(i);  
            int city2 = path.get(i + 1);  
            length += distanceMatrix[city1][city2];  
        }  
        return length;  
    }  
  
    public void solve() {  
        List<List<Integer>> bestPaths = new ArrayList<>();  
        double bestLength = Double.MAX_VALUE;  
  
        for (int iteration = 0; iteration < MAX_ITERATIONS; iteration++) {  
            List<List<Integer>> allPaths = new ArrayList<>();  
            for (int ant = 0; ant < NUM_ANTS; ant++) {  
                List<Integer> path = generateAntPath();  
                allPaths.add(path);  
                double length = calculatePathLength(path);  
                if (length < bestLength) {  
                    bestLength = length;  
                    bestPaths.clear();  
                    bestPaths.add(path);  
                } else if (length == bestLength) {  
                    bestPaths.add(path);  
                }  
            }  
  
            updatePheromoneMatrix(allPaths);  
  
            if (iteration % 100 == 0) {  
                System.out.println("Iteration " + iteration + ": Best Path Length = " + bestLength);  
            }  
        }  
  
        System.out.println("Best Path Length after " + MAX_ITERATIONS + " iterations: " + bestLength);  
        for (List<Integer> path : bestPaths) {  
            System.out.println("Best Path: " + path);  
        }  
    }  
  
    public static void main(String[] args) {  
        AntColonyOptimization aco = new AntColonyOptimization();  
        aco.solve();  
    }  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值