matlab解一个点到三十个点的最短距离 用MATLAB怎么算一个点到其他七个点最短距离
matlab\u4e00\u70b9\u5230\u51e0\u4e2a\u70b9\u6700\u77ed\u8ddd\u79bb\u7a0b\u5e8f\u9996\u5148\u7f16\u5199\u51fd\u6570\u7684.m\u6587\u4ef6\u5982\u4e0b\uff1a
\u3000\u3000function f=myfun(x)
\u3000\u3000f=3*sqrt((x(1)-3)^2+(x(2)-4)^2)+11*sqrt((x(1)-1)^2+(x(2)-7)^2)+5*sqrt((x(1)-9)^2+(x(2)-3)^2);
\u3000\u3000end
\u3000\u3000%\u5c06\u70b9\uff08x\uff0cy\uff09\u770b\u6210\u4e8c\u7ef4\u5411\u91cf\u5982x=[1 2]\uff0c\u5176\u4e2dx\uff081\uff09\u3001x\uff082\uff09\u5206\u522b\u5bf9\u5e94\u6a2a\u7eb5\u5750\u6807\u3002
\u7136\u540e\u5728\u547d\u4ee4\u7a97\u53e3\u8f93\u5165\uff1a
\u3000\u3000x0=[0,0];
\u3000\u3000[x,fval]=fminsearch(@myfun,x0)
\u3000\u3000%x0\u4e3a\u521d\u59cb\u503c\uff0c\u53ef\u81ea\u7531\u8bbe\u5b9a\u3002
\u3000\u3000%myfun\u4e3a\u76ee\u6807\u51fd\u6570\u3002
\u3000\u3000%fval:\u8fd4\u56de\u76ee\u6807\u51fd\u6570\u5728\u6700\u4f18\u89e3x\u70b9\u7684\u51fd\u6570\u503c\u3002
\u3000\u3000%x\u4e3a\u6700\u5c0f\u503c\u3002
\u6700\u540e\u8fd0\u884c\u7ed3\u679c\u5982\u56fe\uff1a
clear;
clc;
x=rand(7,1);
y=rand(7,1);
dist=@(var) sum(sqrt((var(1)-x).^2+(var(2)-y).^2));%var(1)=x;var(2)=y
var0=rand(2,1);
[var,minDistance,exitflag]=fminunc(dist,var0)
plot(x,y,'o','markerfacecolor','r','markersize',6);
hold on;
plot(var(1),var(2),'p','markerfacecolor','g')
for i=1:7
plot([var(1),x(i)],[var(2),y(i)],':');
end
兄弟,你的问题可以归结为所有距离之和的最小值问题。我推导了一下,并且给写了代码
function ABC
clc;
clear;
close all;
global R
R=[42.37 19.30
54.48 91.96
52.80 28.87
18.51 55.09
8.17 91.93
46.41 9.00
3.06 25.77
43.50 42.70
55.79 57.77
63.88 89.95
3.42 21.82
70.99 96.70
16.93 43.40
59.34 78.48
60.81 52.52
77.24 33.13
5.63 43.16
85.47 71.79
38.43 91.62
39.96 89.00
32.54 13.47
55.54 11.99
29.54 89.35
36.61 65.31
34.90 4.03
63.02 50.47
66.44 89.45
99.21 38.57
94.44 29.21
35.03 23.40 ];
x0 = [-5; -5]; % Make a starting guess at the solution
options = optimoptions('fsolve','Display','iter','Jacobian','on'); % Option to display output
[x,fval] = fsolve(@GetFJ,x0,options) % Call solver
figure;
hold on;
grid on;
N=length(R(:,1));
for i=1:N
plot([x(1) R(i,1)],[x(2) R(i,2)],'.-');
end
end
function [F J]= GetFJ( Rx )
global R
F=zeros(2,1);
J=zeros(2,2);
N=length(R(:,1));
for i=1:N
dist = norm(Rx'-R(i,:),2);
if( dist < 1E-9 )
continue;
end
F(1) = F(1) + (Rx(1)-R(i,1))/dist;
F(2) = F(2) + (Rx(2)-R(i,2))/dist;
J(1,1)=J(1,1)-(Rx(1)-R(i,1))*(Rx(1)-R(i,1))/dist^3+1/dist;
J(1,2)=J(1,2)-(Rx(1)-R(i,1))*(Rx(2)-R(i,2))/dist^3;
J(2,1)=J(2,1)-(Rx(1)-R(i,1))*(Rx(2)-R(i,2))/dist^3;
J(2,2)=J(2,2)-(Rx(2)-R(i,2))*(Rx(2)-R(i,2))/dist^3+1/dist;
end
end
计算结果:
x =
47.9324808518899
51.177556034619
fval =
-1.39904476892383e-10
1.05504605052431e-10
画图
这是一个求解“点到多点最短路径”的问题,可以使用图论算法中的Dijkstra算法或者A*算法来解决。由于只有30个点,使用Dijkstra算法就可以得到最短路径。具体实现步骤如下:
定义一个二维数组存储所有点之间的距离,使用无穷大表示两点不连通。
- const int INF = 1e9;
- double dist[30][30] = {
- {0},
- {INF, 0},
- {INF, INF, 0}, // ... 省略剩下的行和列,初始化为INF};
- const int INF = 1e9;
double dist[30][30] = {
{0},
{INF, 0},
{INF, INF, 0},
// ... 省略剩下的行和列,初始化为INF
}; 根据给定的点坐标,计算出所有点之间的距离,更新距离数组。
- for (int i = 0; i < 30; i++) {
- for (int j = i+1; j < 30; j++) {
- double dx = points_x[i] - points_x[j];
- double dy = points_y[i] - points_y[j];
- double dz = points_z[i] - points_z[j];
- double dis = sqrt(dx*dx + dy*dy + dz*dz);
- dist[i][j] = dist[j][i] = dis;
- }
- }
- for (int i = 0; i < 30; i++) {
for (int j = i+1; j < 30; j++) {
double dx = points_x[i] - points_x[j];
double dy = points_y[i] - points_y[j];
double dz = points_z[i] - points_z[j];
double dis = sqrt(dx*dx + dy*dy + dz*dz);
dist[i][j] = dist[j][i] = dis;
}
} 使用Dijkstra算法求解给定点到其他所有点的最短路径。
- int src = 0; // 源点
- double shortest_path[30]; // 存储最短路径长度
- int predecessor[30]; // 存储路径上前驱结点
- bool visited[30] = {false}; // 存储结点是否已经访问
- for (int i = 0; i < 30; i++) {
- shortest_path[i] = INF;
- }
- shortest_path[src] = 0;
- for (int i = 0; i < 30; i++) {
- int u = -1;
- double shortest = INF;
- for (int j = 0; j < 30; j++) {
- if (!visited[j] && shortest_path[j] < shortest) {
- u = j;
- shortest = shortest_path[j];
- }
- }
- if (u == -1) {
- break;
- }
- visited[u] = true;
- for (int v = 0; v < 30; v++) {
- if (!visited[v] && dist[u][v] != INF && shortest_path[u] + dist[u][v] < shortest_path[v]) {
- shortest_path[v] = shortest_path[u] + dist[u][v];
- predecessor[v] = u;
- }
- }
- }
- int src = 0; // 源点
double shortest_path[30]; // 存储最短路径长度
int predecessor[30]; // 存储路径上前驱结点
bool visited[30] = {false}; // 存储结点是否已经访问
for (int i = 0; i < 30; i++) {
shortest_path[i] = INF;
}
shortest_path[src] = 0;
for (int i = 0; i < 30; i++) {
int u = -1;
double shortest = INF;
for (int j = 0; j < 30; j++) {
if (!visited[j] && shortest_path[j] < shortest) {
u = j;
shortest = shortest_path[j];
}
}
if (u == -1) {
break;
}
visited[u] = true;
for (int v = 0; v < 30; v++) {
if (!visited[v] && dist[u][v] != INF && shortest_path[u] + dist[u][v] < shortest_path[v]) {
shortest_path[v] = shortest_path[u] + dist[u][v];
predecessor[v] = u;
}
}
} 打印出给定点到其他所有点的最短路径长度和前驱结点,并绘制路径图。
- for (int i = 0; i < 30; i++) { if (i != src) { printf("Shortest path from %d to %d: %.2f
", src, i, shortest_path[i]); printf("Path:"); int j = i; while (j != src) { printf(" %d", j); - j = predecessor[j];
- } printf(" %d
", src); - }
- }
function y=func(x)
a=[42.37 19.30
54.48 91.96
52.80 28.87
18.51 55.09
8.17 91.93
46.41 9.00
3.06 25.77
43.50 42.70
55.79 57.77
63.88 89.95
3.42 21.82
70.99 96.70
16.93 43.40
59.34 78.48
60.81 52.52
77.24 33.13
5.63 43.16
85.47 71.79
38.43 91.62
39.96 89.00
32.54 13.47
55.54 11.99
29.54 89.35
36.61 65.31
34.90 4.03
63.02 50.47
66.44 89.45
99.21 38.57
94.44 29.21
35.03 23.40];
a=a';
X=repmat(x,1,30);
y=sum(sum((a-X).^2).^0.5);
将以上内容写入m文件。
在命令窗口输入:
fminsearch('func',[16.93;43.40])
后面两项数字随意写,不要太离谱就行,我选的是30组中的一组。
最后输出结果(x,y) =( 47.9325,51.1775)。
这是近似解,从计算数学的角度来讲,它就是理论解
建议用优化方法解决。这里有一个非常类似例子,可以参考。
“一个点到他们所有点路径最短”有些模糊。例子中是让最远点(因为中心点不可能离所有点一样近,肯定有近有远)的路径最短,而且用的距离是city-block距离。
如果您要求其它的优化目标的话请再提出。
绛旓細n = 10; % n 涓殢鏈虹偣rg = [1 10]; % 闅忔満鐐瑰潗鏍囪寖鍥碅 = randint(n,2,rg);m = [5 5]; % 瀹氱偣D = sqrt((A(:,1)-m(1)).^2+(A(:,2)-m(2)).^2);D = sort(D)
绛旓細鏈涓夊崄涓淇″彿(鏁扮粍),鏈夐暱鏈夌煭(淇″彿闀垮害鏈煡),闇瑕佷竴璧疯鍏ヤ互鍚庤繘琛屽悗缁搷浣,鎬庝箞鍔炪 淇″彿鍚庨潰涓嶈兘琛ラ浂,鍥犱负淇″彿缁撳熬鎯呭喌鏈煡,琛ラ浂鍙兘浼氳浼や俊鍙枫俠eedrill | 娴忚2284 娆 |涓炬姤 鎴戞湁鏇村ソ鐨勭瓟妗堟帹鑽愪簬2017-12-16 14:11:55 鏈浣崇瓟妗 浣跨敤鍏冭優鏁扮粍cell灏卞ソ浜嗐傚a = [1 2 3]; b = [4 5 6 7 8]...
绛旓細鍙傝 K鏉¤矾绠楁硶娴嬭瘯绋嬪簭 Dijkstra绠楁硶姹傛渶鐭矾寰勶細Dijkstra绠楁硶鏄吀鍨嬫渶鐭矾绠楁硶锛岀敤浜庤绠涓涓鑺傜偣鍒板叾浠栨墍鏈夎妭鐐圭殑鏈鐭矾寰勩備富瑕佺壒鐐规槸浠ヨ捣濮嬬偣涓轰腑蹇冨悜澶栧眰灞傛墿灞曪紝鐩村埌鎵╁睍鍒扮粓鐐逛负姝侱ijkstra绠楁硶鑳藉緱鍑烘渶鐭矾寰勭殑鏈浼樿В锛屼絾鐢变簬瀹冮亶鍘嗚绠楃殑鑺傜偣寰堝锛屾墍浠ユ晥鐜囦綆銆侱ijkstra绠楁硶鏄緢鏈変唬琛ㄦх殑鏈鐭矾...
绛旓細鐢变綘缁欑殑鐭╅樀A涓洓涓厓绱犵煡鏈5涓偣锛屾寜浣犵殑鎰忔濓紝鏋勯犺繖5涓偣鐨勯偦鎺ョ煩闃礎1;A1=zeros(5,5);A1(1,2)=5;A1(2,3)=7;A1(3,4)=8;A1(4,5)=9;A1=A1+A1';A1(find(A1==0))=inf;鐢╢lody绠楁硶姹備换鎰忎袱鐐圭殑璺濈锛屾瀯鎴愮煩闃礎2锛宖lody绠楁硶鐨matlab绋嬪簭鑷繁缃戜笂鍘绘悳锛岀户缁笅闈㈢殑 A2=[10 5 ...
绛旓細鍙互浣跨敤 MATLAB 涓殑 plot 鍑芥暟鍜 text 鍑芥暟瀹炵幇杩欎釜浠诲姟銆傞鍏堬紝灏嗗洓涓《鐐瑰潗鏍囧瓨鍌ㄥ埌涓涓 4 琛 2 鍒楃殑鐭╅樀涓細coords = [64.1657, 60.7061; 68.9571, 60.7061; 68.9571, 65.055; 64.1657, 65.055];鐒跺悗锛屼娇鐢 plot 鍑芥暟灏嗚繖浜涚偣缁樺埗鍑烘潵锛歱lot(coords(:,1), coords(:,2), 'o'...
绛旓細妤间笂鐨勬柟娉曟尯楂樻繁鐨勶紝浣嗘槸鎴戝疄楠屼簡銆傚彂鐜版湁鈥滄紡缃戜箣楸尖濄傛垜灏嗘垜鍔炴硶鍜屼粬鐨勫姣斾簡涓涓嬶紝濡備笅鍥撅細鍙互鐪嬪嚭锛岀敤妤间笂鐨勬柟娉曡В锛岃鍧愭爣涓100鐨勶紝瀵瑰簲鐨勫垪鍧愭爣鍙湁13,14涓涓偣銆傝屼簨瀹炰笂锛屾湁10,11,12,13,14鍏5涓偣銆傝岀涓琛屽彧鏈(1,1)銆(1,2)涓や釜鐐癸紝浜嬪疄涓婏紝鏈1鍒5鍏5涓偣 涓嶆绗竴琛...
绛旓細5 Total solver iterations: 18 Variable Value Reduced Cost X 5.000000 0.1526587E-08 Y 12.00000 0.2565410E-07 锛5,12锛夊垎鍒埌涔涓偣璺濈鐨勫拰鏈灏
绛旓細閭d箞骞抽潰鍐呬竴鐐瑰埌杩欑偣鐨勮窛绂讳箣鍜岀殑骞虫柟涓 L^2=(x-x2)^2+(x-x2)^2+鈥︹+(y-y1)^2+(y-y2)^2+鈥︹︽眰瀹冪殑鏈鍊煎氨鏄眰瀹冪殑涓や釜鍋忓鏁伴兘涓洪浂鐨勭偣銆傝繖鏍峰彲寰楀埌 x=(x1+x2+鈥︹+xn)/n y=(y1+y2+鈥︹+yn)/n 浠庤繖涓棶棰樺彲浠ョ湅鍑猴紝瀵逛簬涓涓闂鐨勬暟瀛﹀垎鏋愭槸鏈涓昏鐨勶紒绁濅綘瀛︿範...
绛旓細r=mean(d(cc));tt=0:360;plot(cc(1)+r*cosd(tt),cc(2)+r*sind(tt),'k-.');hold off axis equal axis([0 6 0 6]);title(['鍦嗗績(' num2str(cc(1)) ',' num2str(cc(2)) ') 鍗婂緞' num2str(r)]);绋嬪簭鐢ㄩ殢鏈烘暟浜х敓浜51涓偣 浠ヤ笅鏄煇娆¤繍琛岀殑缁撴灉 ...