平面图中散落10个点,两两配对,共得5条边,计算边的长度和,如何找到长度和最小的配对方案?

平面图中散落10个点,两两配对,共得5条边,计算边的长度和,如何找到长度和最小的配对方案?

用递归遍历吧,9×7×5×3=945种可能,计算量不大。

又写了个动态规划hiahiahia

img


调用

Pnts=randi(100,[10,2]);
disMat=zeros(10,10);
for i=1:10
    for j=1:10
       disMat(i,j)=norm(Pnts(i,:)-Pnts(j,:)); 
    end
end
[connect,totalLen]=dpMatch(disMat)
plot([Pnts(connect(1:5),1),Pnts(connect(6:10),1)]',...
    [Pnts(connect(1:5),2),Pnts(connect(6:10),2)]','k');
hold on
scatter(Pnts(:,1),Pnts(:,2),'filled')

计算结果
connect =

 1     3
 2     7
 5     8
 6     9
 4    10

totalLen =

102.6540

动态规划函数

function [connect,totalLen]=dpMatch(adjMat)
N=size(adjMat,1);      % 点的数目

UK=dec2bin(1:2^(N)-1); % 可行集合
UK=abs(UK(:,1:N))-48;
UK(mod(sum(UK,2),2)~=0,:)=[];

V=inf.*ones(size(UK,1),1); % 记录每个可行组合路长
tPos=find(sum(UK,2)==2);
tSet=UK(tPos,:);
for i=1:size(tSet,1)
    ind=find(tSet(i,:)==1);
    V(tPos(i))=adjMat(ind(1),ind(2));
end

Comb=zeros(size(UK,1),2); % 记录每个可行组合是由哪些组合构成
Comb(tPos,1)=tPos;

% 当前集合
for k=2:round(N/2)
    tListSet=UK(sum(UK,2)==2*k,:);
    for i=1:size(tListSet,1)
        tList=tListSet(i,:);
        tInd=combnk(find(tList),2);
        subNum=size(tInd,1);
        subListSet=repmat(tList,[subNum,1]);
        subListSet(([tInd(:,1);tInd(:,2)]-1).*subNum+...
                    [(1:subNum),(1:subNum)]')=0;
        p2ListSet=repmat(tList,[subNum,1])-subListSet;
        for j=1:subNum
            vInd1=sum(abs(UK-p2ListSet(j,:)),2)==0;
            vInd2=sum(abs(UK-subListSet(j,:)),2)==0;
            v1=V(vInd1);
            v2=V(vInd2);
            tInd2=sum(abs(UK-tList),2)==0;
            if v1+v2<V(tInd2)
                V(tInd2)=v1+v2;
                Comb(tInd2,:)=[find(vInd1),find(vInd2)];
            end  
        end
    end
end
totalLen=V(end);
CombSet=Comb(end,:);
for i=1:(round(N/2)-2)
    tComb=Comb(CombSet(end),:);
    CombSet(end)=[];
    CombSet=[CombSet,tComb];
end
connect=zeros(round(N/2),2);
for i=1:length(CombSet)
    connect(i,:)=find(UK(CombSet(i),:));
end
end

以A~J 10个街区点为例,相当于是一个不考虑顺序的排列组合问题,
共有C(2,10) * C(2,8) * C(2,6) * C(2,4) * C(2,2) / A(5,5) 种组合方法

最短的5条边路径如下图所示:

img

源码可参考:

有帮助请采纳哦~

不想动脑子。。。写了个循环:

img

Pnts=randi(100,[10,2]);


disMat=zeros(10,10);
for i=1:10
    for j=1:10
       disMat(i,j)=norm(Pnts(i,:)-Pnts(j,:)); 
    end
end

Cmn=combnk(1:10,5);
Len=size(Cmn,1);
ClassList2=Cmn(1:Len/2,:);
ClassList1=Cmn(end:-1:(Len/2+1),:);

connect=[];
LenSet=[];
n=1;
for i=1:length(ClassList1)
    tSet1=ClassList1(i,:);
    tSet2=ClassList2(i,:);
    sSet2S=perms(tSet2);
    for j=1:length(sSet2S)
        LenSet(n)=sum(disMat(tSet1+(sSet2S(j,:)-1).*10));
        connect(n,:)=[tSet1,sSet2S(j,:)];
        n=n+1;
    end
end


minIndex=find(LenSet==min(LenSet));
connect=connect(minIndex(1),:);



plot([Pnts(connect(1:5),1),Pnts(connect(6:10),1)]',...
    [Pnts(connect(1:5),2),Pnts(connect(6:10),2)]','k');
hold on
scatter(Pnts(:,1),Pnts(:,2),'filled')