Reference to GPT and my own ideas, my code is as follows:
% 问题一:旅游费用2000元,尽可能多地游览景点
% 景点信息(省市,景点名称,最短停留时间,门票费用)
data = {'安徽','黄山市黄山',7,230;
'湖北','武汉市黄鹤楼',2,80;
'陕西','西安市秦始皇兵马俑',2,150;
'江西','九江市庐山',7,180;
'浙江','舟山市普陀山',6,200};
N = size(data,1); % 景点数目
% 构造距离矩阵(假设城市间距离为10倍于景点间距离)
dis = zeros(N+1,N+1);
for i = 1:N
for j = 1:N
if i == j
dis(i,j) = 0;
else
dis(i,j) = 10*rand+50; % 随机生成50~60之间的距离
end
end
end
dis(N+1,:) = dis(1,:); % 将最后一行赋值为第一行,表示回到起点
dis(:,N+1) = dis(:,1); % 将最后一列赋值为第一列,表示回到起点
t = data(:,3); % 最短停留时间
C = data(:,4); % 门票费用
Tmax = 20; % 最长旅行时间
Cmax = 2000; % 最大旅行费用
% 遗传算法参数设置
PopSize = 100; % 种群大小
MaxGen = 500; % 最大迭代次数
Pc = 0.8; % 交叉概率
Pm = 0.01; % 变异概率
% 初始化种群
Pop = zeros(PopSize,N); % 种群矩阵
for i = 1:PopSize
Pop(i,:) = randperm(N); % 随机初始化
end
% 遗传算法主程序
Fit = zeros(PopSize,1); % 适应度值矩阵
for Gen = 1:MaxGen
% 评估适应度值
for i = 1:PopSize
Fit(i) = fitness(Pop(i,:),dis,t,C,Tmax,Cmax);
end
% 选择
SelPop = selection(Pop,Fit);
% 交叉
CrossPop = crossover(SelPop,Pc);
% 变异
NewPop = mutation(CrossPop,Pm);
% 更新种群
Pop = [SelPop;NewPop];
end
% 选出最优解
[bestFit,index] = min(Fit);
bestRoute = Pop(index,:);
% 输出结果
fprintf('最优路径为:\n');
Code for problem 2:
clear
clc
% 建立景点的距离矩阵,单位为公里
dist_matrix = [ 0, 348, 609, 381, 425; 348, 0, 296, 238, 599; 609, 296, 0, 296, 315; 381, 238, 296, 0, 426; 425, 599, 315, 426, 0];
% 建立省市和景点名称的映射关系
province_city_names = {
'安徽', '黄山市黄山';
'湖北', '武汉市黄鹤楼';
'陕西', '西安市秦始皇兵马俑';
'江西', '九江市庐山';
'浙江', '舟山市普陀山'
};
% 建立景点的最短停留时间,单位为小时
min_stay_time = [7, 2, 2, 7, 6];
% 建立景点的门票价格,单位为元
ticket_price = [230, 60, 150, 150, 150];
% 建立每天的时间安排
time_schedule = [8, 18];
% 建立旅游费用和时间的约束条件
budget = 2000;
max_days = 5;
% 初始化蚁群算法参数
num_ants = 50;
max_iter = 500;
alpha = 1;
beta = 2;
rho = 0.5;
q0 = 0.5;
tau0 = 1;
tau = tau0 * ones(size(dist_matrix));
best_path = zeros(max_iter, size(dist_matrix, 1));
best_dist = inf(max_iter, 1);
% 迭代搜索最优路径
for iter = 1:max_iter
% 每只蚂蚁都从第一个景点出发
current_city = ones(num_ants, 1);
visited = zeros(num_ants, size(dist_matrix, 1));
path = zeros(num_ants, size(dist_matrix, 1));
for i = 1:num_ants
visited(i, current_city(i)) = 1;
path(i, 1) = current_city(i);
end
% 依次选择下一个要访问的景点,直到所有景点都被访问过
for j = 2:size(dist_matrix, 1)
for i = 1:num_ants
unvisited_cities = find(visited(i,:) == 0);
if isempty(unvisited_cities)
continue
end
next_city = ant_choose_next_city(current_city(i), unvisited_cities, tau, alpha, beta, q0, dist_matrix);
path(i, j) = next_city;
visited(i, next_city) = 1;
current_city(i) = next_city;
end
end
% 计算每只蚂蚁的路径长度和花费
path_dist = zeros(num_ants, 1);
path_cost = zeros(num_ants, 1);
for i = 1:num_ants
% 重置蚂蚁的状态
cur_city = start_city;
unvisited_cities = cities;
path = [cur_city];
visited_time = zeros(num_cities, 1);
visited_time(cur_city) = start_time;
% 模拟蚂蚁访问每个城市
for j = 2:num_cities
% 计算城市间信息素浓度和启发因子
p = unvisited_cities.^alpha .* (1./dist(cur_city, unvisited_cities)).^beta;
% 归一化概率
p = p / sum(p);
% 轮盘赌选择下一个城市
next_city = roulette_wheel(p);
% 记录路径和已访问城市
path = [path, next_city];
unvisited_cities = setdiff(unvisited_cities, next_city);
% 更新已访问城市的时间
visited_time(next_city) = max(visited_time(cur_city) + dist(cur_city, next_city), open_time(next_city));
% 更新路径长度和花费
path_dist(i) = path_dist(i) + dist(cur_city, next_city);
path_cost(i) = path_cost(i) + cost(cur_city, next_city);
% 判断是否需要住宿
if visited_time(next_city) > close_time(next_city) || (visited_time(next_city)-visited_time(cur_city)) >= min_stop_time(next_city)
% 选择最近的可用酒店
[hotel_dist, hotel_idx] = min(dist(next_city, hotels));
% 更新路径长度和花费
path_dist(i) = path_dist(i) + hotel_dist;
path_cost(i) = path_cost(i) + hotel_cost;
% 计算最短游览时间
min_time = min(min_visit_time);
% 计算所有城市到达时间
arrive_time = visited_time + visit_time;
% 找到第一个可以离开旅馆的时间
start_time = max(open_time(start_city), visited_time(start_city));
% 初始化出发时间
dep_time = start_time;
% 初始化总路径长度和总花费
total_dist = 0;
total_cost = 0;
% 储存每个城市的离开时间
leave_time = zeros(num_cities, 1);
leave_time(start_city) = dep_time;
% 初始化路径和已访问城市集合
path = [start_city];
visited = zeros(num_cities, 1);
visited(start_city) = 1;
% 循环访问剩余城市
for i = 1:num_cities-1
% 计算当前城市到所有未访问城市的距离
dist_to_unvisited = dist_matrix(path(end),:) .* (1 - visited)';
% 计算当前可达城市的到达时间
arrive_time_unvisited = arrive_time + dist_to_unvisited;
% 找到可以到达时间最早的城市
[~, next_city] = min(arrive_time_unvisited);
% 更新路径和已访问城市集合
path = [path, next_city];
visited(next_city) = 1;
% 计算当前城市到下一个城市的距离和花费
dist = dist_matrix(path(end-1), path(end));
cost = get_cost(start_time, dep_time, dist, min_time, visit_time(path(end)));
% 更新总路径长度和总花费
total_dist = total_dist + dist;
total_cost = total_cost + cost;
% 更新离开时间和到达时间
leave_time(path(end)) = max(open_time(path(end)), dep_time + visit_time(path(end)));
arrive_time(path(end+1:end_cities)) = leave_time(path(end)) + dist_matrix(path(end), path(end+1:end_cities));
% 如果到下一个城市的时间在晚上20:00之后,则需要住宿一晚
if arrive_time(next_city) > close_time(next_city)
% 找到最近的旅馆
[min_hotel_time, hotel_idx] = min(hotel_time(next_city,:));
% 更新当前城市和时间
cur_city = hotels(next_city, hotel_idx);
visited_time(cur_city) = max(visited_time(next_city) + min_hotel_time, open_time(cur_city));
% 计算住宿费用和时间
hotel_cost = hotel_price(next_city, hotel_idx);
hotel_time_spent = visited_time(cur_city) - visited_time(next_city);
hotel_leave_time = visited_time(cur_city) + min_hotel_time;
% 更新总花费和到达时间
total_cost = total_cost + hotel_cost;
leave_time(cur_city) = hotel_leave_time;
arrive_time(next_city:end_cities) = hotel_leave_time + dist_matrix(cur_city, next_city:end_cities);
% 更新路径和已访问城市集合
path = [path, cur_city];
visited(cur_city) = 1;
Code for problem 3
clear all; clc;
%% 景点信息
% 安徽 黄山市黄山 7
% 湖北 武汉市黄鹤楼 2
% 陕西 西安市秦始皇兵马俑 2
% 江西 九江市庐山 7
% 浙江 舟山市普陀山 6
provinces = {'安徽', '湖北', '陕西', '江西', '浙江'};
cities = {'黄山市黄山', '武汉市黄鹤楼', '西安市秦始皇兵马俑', '九江市庐山', '舟山市普陀山'};
durations = [7, 2, 2, 7, 6];
hotel_costs = [150, 80, 80, 150, 120];
ticket_costs = [230, 60, 150, 280, 180];
num_cities = length(cities);
%% 约束条件
total_budget = 2000;
num_days = 5;
max_stay_time = 6;
hotel_cost_limit = 200;
other_cost_limit = 60;
%% 初始化变量
open_time = repmat(8, num_cities, 1); % 各景点开放时间
close_time = repmat(18, num_cities, 1); % 各景点关闭时间
hotel_time = 12; % 入住酒店需要的时间
hotel_idx = num_cities + 1; % 酒店在城市列表中的下标
% 根据每个城市的最短停留时间和开放时间计算出每个城市的最早离开时间
min_leave_time = close_time - durations;
min_leave_time = max(min_leave_time, open_time + durations);
%% 构建邻接矩阵
adj_matrix = zeros(num_cities+1, num_cities+1);
for i = 1:num_cities
for j = 1:num_cities
if i == j
adj_matrix(i,j) = 0;
else
adj_matrix(i,j) = durations(i) + 2; % 假设从一个城市到另一个城市需要2小时的交通时间
end
end
adj_matrix(i, hotel_idx) = hotel_time + 1; % 假设到酒店需要1小时的交通时间
adj_matrix(hotel_idx, i) = hotel_time + 1;
end
%% 定义蚁群算法参数
num_ants = 50;
alpha = 1;
beta = 3;
rho = 0.1;
Q = 1;
num_iterations = 100;
%% 蚁群算法主程序
best_path = [];
best_path_cost = Inf;
for iter = 1:num_iterations
% 初始化信息素矩阵
tau = ones(num_cities+1, num_cities+1);
% 初始化每只蚂蚁的起始城市
start_cities = randi(num_cities, [num_ants, 1]);
% 初始化每只蚂蚁的已访问时间和当前城市
visited_time = zeros(1, num_cities+1);
visited_time(start_cities) = open_time(start_cities);
cur_city = start_cities;
% 开始移动蚂蚁
for i = 1:num_cities-1
next_city = ant_choose_next_city(cur_city, tau, visited_cities, visited_time, hotel_time, open_time, close_time, hotels);
visited_cities(:, next_city) = 1;
path_dist = path_dist + dist(cur_city, next_city)';
path_dist = path_dist + get_city_cost(next_city, visited_time, hotel_time, open_time, close_time, hotels, hotel_cost, other_cost)';
visited_time(next_city) = max(visited_time(cur_city) + path_dist - visited_time(next_city), open_time(next_city));
cur_city = next_city;
end
% 回到起始城市
path_dist = path_dist + dist(cur_city, start_cities)';
visited_time(start_cities) = max(visited_time(cur_city) + path_dist - visited_time(start_cities), open_time(start_cities));
% 更新最优路径和最优路径长度
[min_path_dist, min_idx] = min(path_dist);
if min_path_dist < best_path_cost
best_path = start_cities(min_idx);
for i = 1:num_cities-1
next_city = ant_choose_next_city(best_path(end), tau, visited_cities(min_idx,:), visited_time, hotel_time, open_time, close_time, hotels);
best_path = [best_path, next_city];
visited_time(next_city) = max(visited_time(best_path(end)) + dist(best_path(end), next_city) - visited_time(next_city), open_time(next_city));
end
best_path_cost = min_path_dist;
end
% 更新信息素矩阵
delta_tau = zeros(num_cities+1, num_cities+1);
for i = 1:num_ants
for j = 1:num_cities
delta_tau(visited_cities(i,j), visited_cities(i,j+1)) = delta_tau(visited_cities(i,j), visited_cities(i,j+1)) + Q / path_dist(i);
end
delta_tau(visited_cities(i,end), visited_cities(i,1)) = delta_tau(visited_cities(i,end), visited_cities(i,1)) + Q / path_dist(i);
end
tau = (1 - rho) * tau + delta_tau;
end
% 输出结果
fprintf('最优路径为:\n');
for i = 1:length(best_path)
fprintf('%d -> ', best_path(i));
end
fprintf('%d\n', best_path(1));
fprintf('最优路径长度为:%f\n', best_path_cost);