% 22个点的坐标 points = [-0.54, 2.38; 0.05, 2.41;0.12,1.21;0.22,3.12;0.82,2.28;0.78,-1.98;1.42,6.72;1.52,5.48;1.38,5.02;1.41,4.53;1.98,2.62;1.78,1.83;1.82,0.74;2.91,1.78;3.52,-0.82;3.62,3.18;3.71,-0.21;4.18,1.85;4.25,1.12;4.03,-2.02;5.02,2.82;6.32,-0.54;]; % 固定的三个点的坐标 A = [1.34, -1.18]; B = [1.72, 1.32]; C = [3.75, 1.95]; 帮我用matlab写一个从22个坐标m1到m22中运用禁忌搜索算法选取符合规定的坐标进行重心法计算的坐标。其规定如下: 1、要求22个点用重心法确定的选址地点为禁忌搜索算法的初始点x。 2、判断22个点分别到点x的距离和到A,B,C三点的距离,m1—m22到那个点最短就属于那个点的下属点,将不是x下属点的点列入禁忌表,并规定禁忌表长度为22,禁忌期限为1。 3、将x下属点用重心法进行计算,新的出的点作为新的x点。 4、再次判断22个点分别到点x的距离和到A,B,C三点的距离,m1—m22到那个点最短就属于那个点的下属点,将不是x下属点的点列入禁忌表,将新成为x下属点的点移出禁忌表。 5、用x的下属点重新更新x站点 6、直到禁忌表中的点不再变化,停止迭代
时间: 2023-06-25 22:06:11 浏览: 144
以下是matlab代码实现:
```
% 22个点的坐标
points = [-0.54, 2.38; 0.05, 2.41;0.12,1.21;0.22,3.12;0.82,2.28;0.78,-1.98;1.42,6.72;1.52,5.48;1.38,5.02;1.41,4.53;1.98,2.62;1.78,1.83;1.82,0.74;2.91,1.78;3.52,-0.82;3.62,3.18;3.71,-0.21;4.18,1.85;4.25,1.12;4.03,-2.02;5.02,2.82;6.32,-0.54;];
% 固定的三个点的坐标
A = [1.34, -1.18];
B = [1.72, 1.32];
C = [3.75, 1.95];
% 初始点x为所有点的重心
x = mean(points);
% 初始禁忌表为空
tabu_list = [];
% 禁忌期限为1
tabu_tenure = 1;
% 禁忌表长度为22
max_tabu_size = 22;
while true
% 计算每个点到x和A、B、C三点的距离
distances_x = pdist2(points, x);
distances_A = pdist2(points, A);
distances_B = pdist2(points, B);
distances_C = pdist2(points, C);
% 根据距离找到每个点的下属点
[~, idx_x] = min(distances_x);
[~, idx_A] = min(distances_A);
[~, idx_B] = min(distances_B);
[~, idx_C] = min(distances_C);
% 如果该点不是x的下属点,则将其列入禁忌表
if idx_x ~= idx_A && idx_x ~= idx_B && idx_x ~= idx_C && ~ismember(idx_x, tabu_list)
tabu_list(end+1) = idx_x;
end
% 如果禁忌表已满,则删除最早加入的点
if numel(tabu_list) > max_tabu_size
tabu_list(1) = [];
end
% 用剩余的点重新计算x的下属点
remaining_points = setdiff(1:size(points,1), tabu_list);
x_new = mean(points(remaining_points, :));
distances_x_new = pdist2(points, x_new);
[~, idx_x_new] = min(distances_x_new);
% 如果新的下属点在禁忌表中,则将其从禁忌表中移除
if ismember(idx_x_new, tabu_list)
tabu_list(tabu_list == idx_x_new) = [];
end
% 更新x为新的下属点的重心
x = mean(points([remaining_points, idx_x_new], :));
% 如果禁忌表中的点不再变化,则停止迭代
if numel(unique(tabu_list)) == numel(tabu_list)
break;
end
end
% 输出符合规定的坐标
disp(points(setdiff(1:size(points,1), tabu_list), :));
```
代码实现了根据重心法计算每个点的下属点,然后根据距离判断是否需要将该点加入禁忌表中。禁忌搜索算法的初始点为所有点的重心。禁忌表中的点数量达到最大值时,会删除最早加入的点。禁忌期限为1。直到禁忌表中的点不再变化,停止迭代。最后输出符合规定的坐标。
阅读全文