最小生成树matlab程序
最小生成树matlab程序

%n表示节点数,A表示弧权矩阵function [I]=MinTree(n,A)k=1; %记录A中不同正数的个数for(i=1:n-1)for(j=i+1:n) %此循环是查找A中所有不同的正数if(A(i,j)>0)x(k)=A(i,j); %数组x记录A中不同的正数kk=1; %临时变量for(s=1:k-1)if(x(k)==x(s))kk=0;break;end;end %排除相同的正数k=k+kk;end;end;endk=k-1 %显示A中所有不同正数的个数for(i=1:k-1)for(j=i+1:k) %将x中不同的正数从小到大排序if(x(j)<x(i))xx=x(j);x(j)=x(i);x(i)=xx;end;end;endT(n,n)=0; %将矩阵T中所有的元素赋值为0q=0; %记录加入到树T中的边数for(s=1:k)if(q==n)break;end %获得最小生成树T, 算法终止for(i=1:n-1)for(j=i+1:n)if (A(i,j)==x(s))T(i,j)=x(s);T(j,i)=x(s); %加入边到树T中TT=T; %临时记录Twhile(1)pd=1; %砍掉TT中所有的树枝for(y=1:n)kk=0;for(z=1:n)if(TT(y,z)>0)kk=kk+1;zz=z;end;end %寻找TT中的树枝if(kk==1)TT(y,zz)=0;TT(zz,y)=0;pd=0;end;end %砍掉TT中的树枝if(pd)break;end;end %已砍掉了TT中所有的树枝pd=0; %判断TT中是否有圈for(y=1:n-1)for(z=y+1:n)if(TT(y,z)>0)pd=1;break;end;end;endif(pd)T(i,j)=0;T(j,i)=0; %假如TT中有圈else q=q+1;end;end;end;end;endT %显示近似最小生成树T, 程序结束。
matlab图论程序算法大全

图论算法matlab实现求最小费用最大流算法的 MATLAB 程序代码如下:n=5;C=[0 15 16 0 00 0 0 13 140 11 0 17 00 0 0 0 80 0 0 0 0]; %弧容量b=[0 4 1 0 00 0 0 6 10 2 0 3 00 0 0 0 20 0 0 0 0]; %弧上单位流量的费用wf=0;wf0=Inf; %wf 表示最大流量, wf0 表示预定的流量值for(i=1:n)for(j=1:n)f(i,j)=0;end;end %取初始可行流f 为零流while(1)for(i=1:n)for(j=1:n)if(j~=i)a(i,j)=Inf;end;end;end%构造有向赋权图for(i=1:n)for(j=1:n)if(C(i,j)>0&f(i,j)==0)a(i,j)=b(i,j); elseif(C(i,j)>0&f(i,j)==C(i,j))a(j,i)=-b(i,j);elseif(C(i,j)>0)a(i,j)=b(i,j);a(j,i)=-b(i,j);end;end;end for(i=2:n)p(i)=Inf;s(i)=i;end %用Ford 算法求最短路, 赋初值for(k=1:n)pd=1; %求有向赋权图中vs 到vt 的最短路for(i=2:n)for(j=1:n)if(p(i)>p(j)+a(j,i))p(i)=p(j)+a(j,i);s( i)=j;pd=0;end;end;endif(pd)break;end;end %求最短路的Ford 算法结束if(p(n)==Inf)break;end %不存在vs 到vt 的最短路, 算法终止. 注意在求最小费用最大流时构造有向赋权图中不会含负权回路, 所以不会出现k=ndvt=Inf;t=n; %进入调整过程, dvt 表示调整量while(1) %计算调整量if(a(s(t),t)>0)dvtt=C(s(t),t)-f(s(t),t); %前向弧调整量elseif(a(s(t),t)<0)dvtt=f(t,s(t));end %后向弧调整量if(dvt>dvtt)dvt=dvtt;endif(s(t)==1)break;end %当t 的标号为vs 时, 终止计算调整量t=s(t);end %继续调整前一段弧上的流fpd=0;if(wf+dvt>=wf0)dvt=wf0-wf;pd=1;end%如果最大流量大于或等于预定的流量值t=n;while(1) %调整过程if(a(s(t),t)>0)f(s(t),t)=f(s(t),t)+dvt; %前向弧调整elseif(a(s(t),t)<0)f(t,s(t))=f(t,s(t))-dvt;end %后向弧调整if(s(t)==1)break;end %当t 的标号为vs 时, 终止调整过程t=s(t);endif(pd)break;end%如果最大流量达到预定的流量值wf=0; for(j=1:n)wf=wf+f(1,j);end;end %计算最大流量zwf=0;for(i=1:n)for(j=1:n)zwf=zwf+b(i,j)*f(i,j);end;end%计算最小费用f %显示最小费用最大流图 6-22wf %显示最小费用最大流量zwf %显示最小费用, 程序结束__Kruskal 避圈法:Kruskal 避圈法的MATLAB 程序代码如下:n=8;A=[0 2 8 1 0 0 0 02 0 6 0 1 0 0 08 6 0 7 5 1 2 01 0 7 0 0 0 9 00 1 5 0 0 3 0 80 0 1 0 3 0 4 60 0 2 9 0 4 0 30 0 0 0 8 6 3 0];k=1; %记录A中不同正数的个数for(i=1:n-1)for(j=i+1:n) %此循环是查找A中所有不同的正数if(A(i,j)>0)x(k)=A(i,j); %数组x 记录A中不同的正数kk=1; %临时变量for(s=1:k-1)if(x(k)==x(s))kk=0;break;end;end %排除相同的正数k=k+kk;end;end;endk=k-1 %显示A中所有不同正数的个数for(i=1:k-1)for(j=i+1:k) %将x 中不同的正数从小到大排序if(x(j)<x(i))xx=x(j);x(j)=x(i);x(i)=xx;end;end;endT(n,n)=0; %将矩阵T 中所有的元素赋值为0q=0; %记录加入到树T 中的边数for(s=1:k)if(q==n)break;end %获得最小生成树T, 算法终止for(i=1:n-1)for(j=i+1:n)if(A(i,j)==x(s))T(i,j)=x(s);T(j,i)=x(s); %加入边到树T 中TT=T; %临时记录Twhile(1)pd=1; %砍掉TT 中所有的树枝for(y=1:n)kk=0;for(z=1:n)if(TT(y,z)>0)kk=kk+1;zz=z;end;end %寻找TT 中的树枝if(kk==1)TT(y,zz)=0;TT(zz,y)=0;pd=0;end;end %砍掉TT 中的树枝if(pd)break;end;end %已砍掉了TT 中所有的树枝pd=0; %判断TT 中是否有圈for(y=1:n-1)for(z=y+1:n)if(TT(y,z)>0)pd=1;break;end;end;end if(pd)T(i,j)=0;T(j,i)=0; %假如TT 中有圈else q=q+1;end;end;end;end;endT %显示近似最小生成树T, 程序结束用Warshall-Floyd 算法求任意两点间的最短路.n=8;A=[0 2 8 1 Inf Inf Inf Inf2 0 6 Inf 1 Inf Inf Inf8 6 0 7 5 1 2 Inf1 Inf 7 0 Inf Inf 9 Inf Inf 1 5 Inf 0 3 Inf 8 Inf Inf 1 Inf 3 0 4 6Inf Inf 2 9 Inf 4 0 3Inf Inf Inf Inf 8 6 3 0]; % MATLAB 中, Inf 表示∞D=A; %赋初值for(i=1:n)for(j=1:n)R(i,j)=j;end;end %赋路径初值for(k=1:n)for(i=1:n)for(j=1:n)if(D(i,k)+D(k,j)<D(i,j))D(i,j )=D(i,k)+D(k,j); %更新dijR(i,j)=k;end;end;end %更新rijk %显示迭代步数D %显示每步迭代后的路长R %显示每步迭代后的路径pd=0;for i=1:n %含有负权时if(D(i,i)<0)pd=1;break;end;end %存在一条含有顶点vi 的负回路if(pd)break;end %存在一条负回路, 终止程序end %程序结束利用 Ford--Fulkerson 标号法求最大流算法的MATLAB 程序代码如下:n=8;C=[0 5 4 3 0 0 0 00 0 0 0 5 3 0 00 0 0 0 0 3 2 00 0 0 0 0 0 2 00 0 0 0 0 0 0 40 0 0 0 0 0 0 30 0 0 0 0 0 0 50 0 0 0 0 0 0 0]; %弧容量for(i=1:n)for(j=1:n)f(i,j)=0;end;end %取初始可行流f 为零流for(i=1:n)No(i)=0;d(i)=0;end %No,d 记录标号图 6-19while(1)No(1)=n+1;d(1)=Inf; %给发点vs 标号while(1)pd=1; %标号过程for(i=1:n)if(No(i)) %选择一个已标号的点vifor(j=1:n)if(No(j)==0&f(i,j)<C(i,j)) %对于未给标号的点vj, 当vivj 为非饱和弧时No(j)=i;d(j)=C(i,j)-f(i,j);pd=0;if(d(j)>d(i))d(j)=d(i);endelseif(No(j)==0&f(j,i)>0) %对于未给标号的点vj, 当vjvi 为非零流弧时No(j)=-i;d(j)=f(j,i);pd=0;if(d(j)>d(i))d(j)=d(i);end;end;end;end;endif(No(n)|pd)break;end;end%若收点vt 得到标号或者无法标号, 终止标号过程if(pd)break;end %vt 未得到标号, f 已是最大流, 算法终止dvt=d(n);t=n; %进入调整过程, dvt 表示调整量while(1)if(No(t)>0)f(No(t),t)=f(No(t),t)+dvt; %前向弧调整elseif(No(t)<0)f(No(t),t)=f(No(t),t)-dvt;end %后向弧调整if(No(t)==1)for(i=1:n)No(i)=0;d(i)=0; end;break;end %当t 的标号为vs 时, 终止调整过程t=No(t);end;end; %继续调整前一段弧上的流fwf=0;for(j=1:n)wf=wf+f(1,j);end %计算最大流量f %显示最大流wf %显示最大流量No %显示标号, 由此可得最小割, 程序结束图论程序大全程序一:关联矩阵和邻接矩阵互换算法function W=incandadf(F,f)if f==0m=sum(sum(F))/2;n=size(F,1);W=zeros(n,m);k=1;for i=1:nfor j=i:nif F(i,j)~=0W(i,k)=1;W(j,k)=1;k=k+1;endendendelseif f==1m=size(F,2);n=size(F,1);W=zeros(n,n);for i=1:ma=find(F(:,i)~=0);W(a(1),a(2))=1;W(a(2),a(1))=1;endelsefprint('Please imput the right value of f');endW;程序二:可达矩阵算法function P=dgraf(A) n=size(A,1);P=A;for i=2:nP=P+A^i;endP(P~=0)=1;P;程序三:有向图关联矩阵和邻接矩阵互换算法function W=mattransf(F,f)if f==0m=sum(sum(F));n=size(F,1);W=zeros(n,m);k=1;for i=1:nfor j=i:nif F(i,j)~=0W(i,k)=1;W(j,k)=-1;k=k+1;endendendelseif f==1m=size(F,2);n=size(F,1);W=zeros(n,n);for i=1:ma=find(F(:,i)~=0);if F(a(1),i)==1W(a(1),a(2))=1;elseW(a(2),a(1))=1;endendelsefprint('Please imput the right value of f');endW;第二讲:最短路问题程序一:Dijkstra算法(计算两点间的最短路)function [l,z]=Dijkstra(W)n = size (W,1); for i = 1 :nl(i)=W(1,i);z(i)=0;endi=1;while i<=nfor j =1 :nif l(i)>l(j)+W(j,i)l(i)=l(j)+W(j,i);z(i)=j-1;if j<ii=j-1;endendendi=i+1;end程序二:floyd算法(计算任意两点间的最短距离)function [d,r]=floyd(a)n=size(a,1);d=a;for i=1:nfor j=1:nr(i,j)=j;endendr;for k=1:nfor i=1:nfor j=1:nif d(i,k)+d(k,j)<d(i,j)d(i,j)=d(i,k)+d(k,j);r(i,j)=r(i,k);endendendend程序三:n2short.m 计算指定两点间的最短距离function [P u]=n2short(W,k1,k2)n=length(W);U=W;m=1;while m<=nfor i=1:nfor j=1:nif U(i,j)>U(i,m)+U(m,j)U(i,j)=U(i,m)+U(m,j);endendendm=m+1;endu=U(k1,k2);P1=zeros(1,n);k=1;P1(k)=k2;V=ones(1,n)*inf;kk=k2;while kk~=k1for i=1:nV(1,i)=U(k1,kk)-W(i,kk);if V(1,i)==U(k1,i)P1(k+1)=i;kk=i;k=k+1;endendendk=1;wrow=find(P1~=0);for j=length(wrow):-1:1P(k)=P1(wrow(j));k=k+1;endP;程序四、n1short.m(计算某点到其它所有点的最短距离)function[Pm D]=n1short(W,k)n=size(W,1);D=zeros(1,n);for i=1:n[P d]=n2short(W,k,i);Pm{i}=P;D(i)=d;end程序五:pass2short.m(计算经过某两点的最短距离)function [P d]=pass2short(W,k1,k2,t1,t2)[p1 d1]=n2short(W,k1,t1);[p2 d2]=n2short(W,t1,t2);[p3 d3]=n2short(W,t2,k2);dt1=d1+d2+d3;[p4 d4]=n2short(W,k1,t2);[p5 d5]=n2short(W,t2,t1);[p6 d6]=n2short(W,t1,k2);dt2=d4+d5+d6;if dt1<dt2d=dt1;P=[p1 p2(2:length(p2)) p3(2:length(p3))];elsed=dt1;p=[p4 p5(2:length(p5)) p6(2:length(p6))];endP;d;第三讲:最小生成树程序一:最小生成树的Kruskal算法function [T c]=krusf(d,flag)if nargin==1n=size(d,2);m=sum(sum(d~=0))/2;b=zeros(3,m);k=1;for i=1:nfor j=(i+1):nif d(i,j)~=0b(1,k)=i;b(2,k)=j;b(3,k)=d(i,j);k=k+1;endendendelseb=d;endn=max(max(b(1:2,:)));m=size(b,2);[B,i]=sortrows(b',3);B=B';c=0;T=[];k=1;t=1:n;for i=1:mif t(B(1,i))~=t(B(2,i))T(1:2,k)=B(1:2,i);c=c+B(3,i);k=k+1;tmin=min(t(B(1,i)),t(B(2,i)));tmax=max(t(B(1,i)),t(B(2,i)));for j=1:nif t(j)==tmaxt(j)=tmin;endendendif k==nbreak;endendT;c;程序二:最小生成树的Prim算法function [T c]=Primf(a)l=length(a);a(a==0)=inf;k=1:l;listV(k)=0;listV(1)=1;e=1;while (e<l)min=inf;for i=1:lif listV(i)==1for j=1:lif listV(j)==0 & min>a(i,j)min=a(i,j);b=a(i,j);s=i;d=j;endendendendlistV(d)=1;distance(e)=b;source(e)=s;destination(e)=d;e=e+1;endT=[source;destination]; for g=1:e-1c(g)=a(T(1,g),T(2,g));endc;另外两种程序最小生成树程序1(prim 算法构造最小生成树)a=[inf 50 60 inf inf inf inf;50 inf inf 65 40 inf inf;60 inf inf 52 inf inf 45;...inf 65 52 inf 50 30 42;inf 40 inf 50 inf 70 inf;inf inf inf 30 70 inf inf;...inf inf 45 42 inf inf inf];result=[];p=1;tb=2:length(a);while length(result)~=length(a)-1temp=a(p,tb);temp=temp(:);d=min(temp);[jb,kb]=find(a(p,tb)==d);j=p(jb(1));k=tb(kb(1));result=[result,[j;k;d]];p=[p,k];tb(find(tb==k))=[];endresult最小生成树程序2(Kruskal 算法构造最小生成树)clc;clear;a(1,2)=50; a(1,3)=60; a(2,4)=65; a(2,5)=40;a(3,4)=52;a(3,7)=45; a(4,5)=50; a(4,6)=30;a(4,7)=42; a(5,6)=70;[i,j,b]=find(a);data=[i';j';b'];index=data(1:2,:);loop=max(size(a))-1;result=[];while length(result)<looptemp=min(data(3,:));flag=find(data(3,:)==temp);flag=flag(1);v1=data(1,flag);v2=data(2,flag);if index(1,flag)~=index(2,flag)result=[result,data(:,flag)];endindex(find(index==v2))=v1;data(:,flag)=[];index(:,flag)=[];endresult第四讲:Euler图和Hamilton图程序一:Fleury算法(在一个Euler图中找出Euler环游)注:包括三个文件;fleuf1.m, edf.m, flecvexf.mfunction [T c]=fleuf1(d)%注:必须保证是Euler环游,否则输出T=0,c=0 n=length(d);b=d;b(b==inf)=0;b(b~=0)=1;m=0;a=sum(b);eds=sum(a)/2;ed=zeros(2,eds);vexs=zeros(1,eds+1);matr=b;for i=1:nif mod(a(i),2)==1m=m+1;endendif m~=0fprintf('there is not exit Euler path.\n')T=0;c=0;endif m==0vet=1;flag=0;t1=find(matr(vet,:)==1);for ii=1:length(t1)ed(:,1)=[vet,t1(ii)];vexs(1,1)=vet;vexs(1,2)=t1(ii);matr(vexs(1,2),vexs(1,1))=0;flagg=1;tem=1;while flagg[flagg ed]=edf(matr,eds,vexs,ed,tem); tem=tem+1;if ed(1,eds)~=0 & ed(2,eds)~=0T=ed;T(2,eds)=1;c=0;for g=1:edsc=c+d(T(1,g),T(2,g));endflagg=0;break;endendendendfunction[flag ed]=edf(matr,eds,vexs,ed,tem)flag=1;for i=2:eds[dvex f]=flecvexf(matr,i,vexs,eds,ed,tem);if f==1flag=0;break;endif dvex~=0ed(:,i)=[vexs(1,i) dvex];vexs(1,i+1)=dvex;matr(vexs(1,i+1),vexs(1,i))=0;elsebreak;endendfunction [dvex f]=flecvexf(matr,i,vexs,eds,ed,temp) f=0;edd=find(matr(vexs(1,i),:)==1);dvex=0;dvex1=[];ded=[];if length(edd)==1dvex=edd;elsedd=1;dd1=0;kkk=0;for kk=1:length(edd)m1=find(vexs==edd(kk));if sum(m1)==0dvex1(dd)=edd(kk);dd=dd+1;dd1=1;elsekkk=kkk+1;endendif kkk==length(edd)tem=vexs(1,i)*ones(1,kkk);edd1=[tem;edd];for l1=1:kkklt=0;ddd=1;for l2=1:edsif edd1(1:2,l1)==ed(1:2,l2)lt=lt+1;endendif lt==0ded(ddd)=edd(l1); ddd=ddd+1;endendendif temp<=length(dvex1)dvex=dvex1(temp);elseif temp>length(dvex1) & temp<=length(ded)dvex=ded(temp);elsef=1;endend程序二:Hamilton改良圈算法(找出比较好的Hamilton路)function [C d1]= hamiltonglf(v)%d表示权值矩阵%C表示算法最终找到的Hamilton圈。
fp-tree算法的matlab程序

FP树算法的MATLAB程序示例FP树(频繁模式树)算法是一种用于挖掘频繁模式的数据挖掘算法。
下面是一个基于事实的FP树算法的MATLAB 程序示例:function [frequent_patterns] = fp_tree(data, min_support) % 构建频繁模式树root = create_tree(data);% 获取频繁项集frequent_patterns = mine_patterns(root, min_support);endfunction [root] = create_tree(data)root = struct('item', 'null', 'count', 0, 'children', {});% 统计每个项的计数item_counts = containers.Map();for i = 1:length(data)itemset = data{i};for j = 1:length(itemset)item = itemset{j};if isKey(item_counts, item)item_counts(item) = item_counts(item)+ 1;elseitem_counts(item) = 1;endendend% 删除不满足最小支持度的项items = keys(item_counts);for i = 1:length(items)item = items{i};if item_counts(item) < min_supportremove(item_counts, item);endend% 如果没有满足最小支持度的项,返回空树if isempty(keys(item_counts))return;end% 对每个事务中的项按照支持度降序排序for i = 1:length(data)itemset = data{i};[~, sorted_indices] = sort(cellfun(@(x) item_counts(x), itemset), 'descend');data{i} = itemset(sorted_indices);end% 构建树for i = 1:length(data)itemset = data{i};insert_tree(root, itemset, item_counts);endendfunction [] = insert_tree(node, itemset, item_counts)if isempty(itemset)return;enditem = itemset{1};child = find_child(node, item);if isempty(child)child = struct('item', item, 'count', item_counts(item), 'children', {});node.children{end+1} = child;elsechild.count = child.count + item_counts(item);endinsert_tree(child, itemset(2:end), item_counts);endfunction [child] = find_child(node, item)children = node.children;for i = 1:length(children)if strcmp(children{i}.item, item)child = children{i};return;endendchild = [];endfunction [frequent_patterns] = mine_patterns(root, min_support)frequent_patterns = struct('pattern', {}, 'support', []);if isempty(root.children)return;endfor i = 1:length(root.children)child = root.children{i};pattern = {child.item};support = child.count;frequent_patterns(end+1) = struct('pattern', pattern, 'support', support);subtree_data = get_subtree_data(child);subtree_patterns = fp_tree(subtree_data, min_support);frequent_patterns = [frequent_patterns, subtree_patterns];endendfunction [subtree_data] = get_subtree_data(node)subtree_data = {};if isempty(node.children)return;endsubtree_data = cell(1, node.count);for i = 1:length(node.children)child = node.children{i};for j = 1:child.countsubtree_data{j} = [subtree_data{j}, child.item];endendend这是一个简化的FP树算法的MATLAB实现。
数学建模-最小生成树-kruskal算法及各种代码之欧阳史创编

kruskal算法及代码---含伪代码、c代码、matlab、pascal等代码K r u s k a l算法每次选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。
注意到所选取的边若产生环路则不可能形成一棵生成树。
K r u s k a l算法分e 步,其中e 是网络中边的数目。
按耗费递增的顺序来考虑这e 条边,每次考虑一条边。
当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。
目录Kruskal算法1.算法定义举例描述Kruskal算法的代码实现1.伪代码C代码实现matlab代码实现pascal代码实现Kruskal算法1.算法定义举例描述Kruskal算法的代码实现1.伪代码C代码实现matlab代码实现pascal代码实现算法定义克鲁斯卡尔算法假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。
之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。
依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
举例描述克鲁斯卡尔算法(Kruskal's algorithm)是两个经典的最小生成树算法的较为简单理解的一个。
这里面充分体现了贪心算法的精髓。
大致的流程可以用一个图来表示。
这里的图的选择借用了Wikipedia上的那个。
非常清晰且直观。
首先第一步,我们有一张图,有若干点和边如下图所示:第一步我们要做的事情就是将所有的边的长度排序,用排序的结果作为我们选择边的依据。
Kruskal算法寻找最小树的matlab程序

Kruskal算法寻找最小树的matlab程序function tree=kruskal(d) %矩阵d为无向图的权矩阵,且是对称矩阵N=size(d,1);k=0; %记录图中边的条数I=max(max(d)); %I作为无穷大edge=zeros(N*(N-1)/2,3);%用于存储图中所有的边,边的条数最多为n*(n-1)/2for i=1:N-1 %因为权矩阵是对称阵,所以只用上三角矩阵。
for j=i+1:Nif d(i,j)<Ik=k+1;edge(k,1)=i;edge(k,2)=j;edge(k,3)=d(i,j);endendendedge=edge(1:k,:); %删除多余的行。
o_edge=edge; %用于存储排序后的边及边的端点。
for i=1:k-1 %用选择排序法进行升序排序for j=i+1:kif o_edge(i,3)>o_edge(j,3)temp=o_edge(i,:);o_edge(i,:)=o_edge(j,:);o_edge(j,:)=temp;endendendtree=zeros(N-1,3); %用于存放最小树中的边及边的端点,最小树中的边数为节点数减1 tree(1:2,:)=o_edge(1:2,:); %两条边一定不能构成圈,所以前面最小的两条边一定在最小树中。
line=3;for i=3:kif line==N %如果line=N说明tree矩阵已填满,最小树已经找到,跳出循环break;elseif line<Nif isempty(find(tree(:,1:2)==o_edge(i,1), 1))||isempty(find(tree(:,1:2)==o_edge(i,2), 1))%判断tree中已经确定的的所有边中的节点是否和新增加的边的两个端点都重复,若新边的两个端点不都重复,则为真%直接说明新边符合条件,加入tree中。
离散数学大作业——编程实现最小生成树

离散数学大作业——编程实现最小生成树学院:电子工程学院班级:021051学号:*********名:***一、最小生成树概念:设G=(V,E)是无向连通带权图,即一个网络。
E中每条边(v,w)的权为c[v,w]。
所有生成树G’上各边权的总和最小的生成树称为G的最小生成树。
二、prim算法(贪心思想)设图G =(V,E),其生成树的顶点集合为U。
1.把v0放入U。
2.在所有u∈U,v∈V-U的边(u,v)∈E中找一条最小权值的边,加入生成树。
3.把2找到的边的v加入U集合。
如果U集合已有n个元素,则结束,否则继续执行2其算法的时间复杂度为O(n^2)三、程序源代码# include<stdio.h># include<malloc.h># define m 6# define n 11 typedef struct {int i,tag;char s;}vertice;typedef struct {int a,b,tag;int weight;}edge;vertice v[m];edge e[n];void inititate();void sort();void chuli();int biaoji( edge *s); void print();void main() {inititate();sort();chuli();print();}void inititate() {int i;printf("输入图的%d个顶点:\n",m);for(i=0;i<m;i++) {v[i].i=i+1;v[i].tag=0;scanf("%c",&v[i].s);getchar();}printf("\n输入%d条边的两端顶点及权:\n",n);for(i=0;i<n;i++) {scanf("%d %d %d",&e[i].a,&e[i].b,&e[i].weight);e[i].tag=0;}}int biaoji( edge *s) {int i,j;i=s->a;j=s->b;if(v[i].tag==0 || v[j].tag==0) {v[i].tag=1;v[i].tag=1;s->tag=1;return 1;}return 0;}void print() {int i,j=0;printf("\n最小生成树的边为:\n");for(i=0;i<n&&j<m-1;i++)if(e[i].tag==1) {printf("<%d-%d> ",e[i].a,e[i].b);j++;}printf("\n\n");}void sort() {edge s;int i,j;for(i=0;i<n-1;i++) {for(j=i+1;j<n;j++) {if(e[i].weight>e[j].weight) {s=e[i];e[i]=e[j];e[j]=s;}}}}void chuli() {int i,j=0;edge *s;for(i=0;i<n&&j<m;i++) {s=&e[i];if(biaoji(s)==1)j++;}}四、实验结果输入图的6个顶点:1 2 3 4 5 6输入11条边的权及两端顶点:1 2 11 4 61 6 91 3 112 3 22 4 33 5 83 6 74 5 104 6 45 6 5最小生成树的边为:<1-2> <2-3> <2-4> <4-6> <5-6> Press any key to continue。
数学建模-最小生成树-kruskal算法及各种代码

kruskal算法及代码之阳早格格创做---含真代码、c代码、matlab、pascal等代码K r u s k a l算法屡屡采用n- 1条边,所使用的贪婪规则是:从剩下的边中采用一条不会爆收环路的具备最小泯灭的边加进已采用的边的集中中.注意到所采用的边若爆收环路则不可能产死一棵死成树.K r u s k a l算法分e 步,其中e 是搜集中边的数目.按泯灭递加的程序去思量那e 条边,屡屡思量一条边.当思量某条边时,若将其加进到已选边的集中中会出现环路,则将其扬弃,可则,将它选进.目录Kruskal算法1.算法定义举例形貌Kruskal算法的代码真止1.真代码C代码真止matlab代码真止pascal代码真止Kruskal算法1.算法定义举例形貌Kruskal算法的代码真止1.真代码C代码真止matlab代码真止pascal代码真止算法定义克鲁斯卡我算法假设WN=(V,{E}) 是一个含有n 个顶面的连通网,则依照克鲁斯卡我算法构制最小死成树的历程为:先构制一个只含n 个顶面,而边集为空的子图,若将该子图中各个顶面瞅成是各棵树上的根结面,则它是一个含有n 棵树的一个森林.之后,从网的边集E 中采用一条权值最小的边,若该条边的二个顶面分属分歧的树,则将其加进子图,也便是道,将那二个顶面分别地方的二棵树合成一棵树;反之,若该条边的二个顶面已降正在共一棵树上,则不可与,而该当与下一条权值最小的边再试之.依次类推,曲至森林中惟有一棵树,也即子图中含有n-1条边为止.举例形貌克鲁斯卡我算法(Kruskal's algorithm)是二个典范的最小死成树算法的较为简朴明白的一个.那内里充分体现了贪心算法的粗髓.大概的过程不妨用一个图去表示.那里的图的采用借用了Wikipedia上的那个.非常浑晰且曲瞅.最先第一步,咱们有一弛图,有若搞面战边如下图所示:第一步咱们要搞的事务便是将所有的边的少度排序,用排序的截止动做咱们采用边的依据.那里再次体现了贪心算法的思维.资材排序,对付局部最劣的资材举止采用.排序完毕后,咱们率先采用了边AD.那样咱们的图便形成了第二步,正在剩下的变中觅找.咱们找到了CE.那里边的权沉也是5依次类推咱们找到了6,7,7.完毕之后,图形成了那个格式..下一步便是闭键了.底下采用那条边呢?BC大概者EF 吗?皆不是,纵然目前少度为8的边是最小的已采用的边.然而是目前他们已经连通了(对付于BC不妨通过CE,EB去对接,类似的EF不妨通过EB,BA,AD,DF去接连).所以咱们不需要采用他们.类似的BD也已经连通了(那里上图的连通线用白色表示了).末尾便剩下EG战FG了.天然咱们采用了EG.末尾乐成的图便是下图:.到那里所有的边面皆已经连通了,一个最小死成树构修完毕.编写本段Kruskal算法的代码真止真代码MST-KRUSKAL(G,w)C代码真止Copyright (c) 2002,2006 by ctu_85All Rights Reserved.*//* I am sorry to say that the situation of unconnected graph is not concerned */#include "stdio.h"#define maxver 10#define maxright 100int G[maxver][maxver],record=0,touched[maxver][maxver]; int circle=0;intFindCircle(int,int,int,int);int main(){int path[maxver][2],used[maxver][maxver];inti,j,k,t,min=maxright,exsit=0;int v1,v2,num,temp,status=0;restart:printf("Please enter the number of vertex(s) in the graph:\n"); scanf("%d",&num);if(num>maxver||num<0){printf("Error!Pleasereinput!\n");goto restart;}for(j=0;j<num;j++)for(k=0;k<num;k++){if(j==k)G[j][k]=maxright;used[j][k]=1;touched[j][k]=0;}elseif(j<k){re:printf("Please input the right between vertex %d and vertex %d,if no edge exists please input -1:\n",j+1,k+1);scanf("%d",&temp);if(temp>=maxright||temp<-1){printf("Invalid input!\n");goto re;}if(temp==-1)temp=maxright;G[j][k]=G[k][j]=temp;used[j][k]=used[k][j]=0;touched[j][k]=touched[k][j]=0;}for(j=0;j<num;j++){path[j][0]=0;path[j][1]=0;}for(j=0;j<num;j++){status=0;for(k=0;k<num;k++)if(G[j][k]<maxright){status=1;break;}if(status==0)break;}for(i=0;i<num-1&&status;i++) {for(j=0;j<num;j++)for(k=0;k<num;k++)if(G[j][k]<min&&!used[j][k]){v1=j;v2=k;min=G[j][k];}if(!used[v1][v2]){used[v1][v2]=1;used[v2][v1]=1;touched[v1][v2]=1;touched[v2][v1]=1;path[0]=v1;path[1]=v2;for(t=0;t<record;t++)FindCircle(path[t][0],path[t][0],num,path[t][0]); if(circle){/*if a circle exsits,roll back*/circle=0;i--;exsit=0;touched[v1][v2]=0;touched[v2][v1]=0;min=maxright;}else{record++;min=maxright;}}}if(!status)printf("We cannot deal with it because the graph is not connected!\n");else{for(i=0;i<num-1;i++)printf("Path %d:vertex %d tovertex %d\n",i+1,path[0]+1,path[1]+1);}return 1;}intFindCircle(intstart,intbegin,inttimes,int pre) { /* to judge whether a circle is produced*/ inti;for(i=0;i<times;i++)if(touched[begin]==1){if(i==start&&pre!=start){circle=1;return 1;break;}elseif(pre!=i)FindCircle(start,i,times,begin);elsecontinue;}return 1;}matlab代码真止functionKruskal(w,MAX)%此步调为最小收撑树的Kruskal算法真止%w为无背图的距离矩阵,故为对付称矩阵%MAX为距离矩阵中∞的本质输进值%时间:2011年6月22日0:07:53len=length(w); %图的面数edge=zeros(len*(len-1),3); %用于死存图中的边count=1; %图中的边数for i=1:len-1 %循环距离矩阵,记录死存边for j=i+1:lenif w(i,j)~=MAXedge(count,1)=w(i,j);edge(count,2)=i;edge(count,3)=j;count=count+1;endendendedge=edge(1:count-1,:); %去掉无用边[tmp,index]=sort(edge(:,1)); %所有边按降序排序i=3; %本去尝试边数为3条(3条以下无法形成圈,即无需检测)while 1x=findcycle(edge(index(1:i),:),len); %检测那些边是可形成圈if xindex(i)=0; %若形成圈,则将该边对付应的index项标记表记标帜为0,以便与消elsei=i+1; %若不形成圈,则i加1,加进下一边检测endindex=index(index>0); %将形成圈的边从index中与消ifi==lenbreak; %找到切合条件的面数减一条的边,即找到一个最小收撑树endendindex=index(1:len-1); %截短index矩阵,死存前len-1项%%%%%%%%%%%% 截止隐现%%%%%%%%%%%%%s=sprintf('\n\t%s\t%s\t %s\t','边端面','距离','是可正在最小收撑树');fori=1:count-1edge_tmp=edge(i,:);if ~isempty(find(index==i,1))s_tmp=sprintf('\n \t (%d,%d)\t %d\t %s\t',edge_tmp(2),edge_tmp(3),edge_tmp(1),'√');elses_tmp=sprintf('\n \t (%d,%d)\t %d\t %s\t',edge_tmp(2),edge_tmp(3),edge_tmp(1),'×');ends=strcat(s,s_tmp);enddisp(s);endfunctionisfind=findcycle(w,N)%本步调用于推断所给的边是可形成圈:有圈,返回1;可则返回0%w:输进的边的矩阵%N:本图的面数%本理:不竭与消出现次数小于2的端面地方的边,末尾瞅察是可有边留住len=length(w(:,1));index=1:len;while 1num=length(index); %边数p=zeros(1,N); %用于死存各面的出现的次数(一条边对付应二个端面)for i=1:num %统计各面的出现次数p(w(index(i),2))=p(w(index(i),2))+1;p(w(index(i),3))=p(w(index(i),3))+1;endindex_tmp=zeros(1,num); %记录与消出现次数小于2的端面地方的边的边的下标集中discard=find(p<2); %找到出现次数小于2的端面count=0; %记录结余的边数fori=1:num%推断各边是可有仅出现一次端面——不,则记录其序号于index_tmpif ~(~isempty(find(discard==w(index(i),2),1)) ||~isempty(find(discard==w(index(i),3),1)))count=count+1;index_tmp(count)=index(i);endendif num==count %当不边被被与消时,循环停止index=index_tmp(1:count); %革新indexbreak;elseindex=index_tmp(1:count); %革新indexendendif isempty(index) %若末尾剩下的边数为0,则无圈isfind=0;elseisfind=1;endend%% a =[% 0 3 2 3 100 100100% 3 0 2 100 100100 6% 2 2 0 3 100 1 100% 3 100 3 0 5 100 100% 100 100100 5 0 4 6% 100 100 1 100 4 0 5% 100 6 100 6 100 5 0];%% Kruskal(a,100)pascal代码真止{最小死成树的Kruskal算法.Kruskal算法基础思维:屡屡选不属于共一连通分量(包管不死成圈)且边权值最小的顶面,将边加进MST,并将地方的2个连通分量合并,曲到只剩一个连通分量排序使用Quicksort(O(eloge))查看是可正在共一连通分量用Union-Find,屡屡Find战union运算近似常数Union-Find使用rank开收式合并战路径压缩总搀纯度O(eloge)=O(elogv) (果为e<n(n-1)/2)}constmaxn=100;maxe=maxn*maxn;typeedge=recorda,b :integer; //边的2个顶面len :integer; //边的少度end;varedges :array[0..maxe]of edge; //死存所有边的疑息p,r :array[0..maxn]of integer; //p死存i的女亲节面,r用去真止Union-Find的rank开收式n,e :integer; //n为顶面数,e为边数procedure swap(a,b:integer); //接换beginedges[0]:=edges[a];edges[a]:=edges[b];edges[b]:=edges[0];end;procedure quicksort(l,r:integer); //赶快排序varx,i,j :integer;beginx:=edges[random(r-l+1)+l].len;i:=l;j:=r;repeatwhile edges[i].len<x do inc(i);while edges[j].len>x do dec(j);ifi<=j thenbeginswap(i,j);inc(i);dec(j);enduntili>j;if l<j then quicksort(l,j);ifi<r then quicksort(i,r);end;procedureinit;vari :integer;beginassign(input,'g.in');reset(input);readln(n,e);for i:=1 to e do readln(edges[i].a,edges[i].b,edges[i].len); //从文献读进图的疑息for i:=1 to n do p[i]:=i; //初初化并查集randomize;quicksort(1,e); //使用赶快排序将边按权值从小到大排列end;function find(x:integer):integer; //并查集的Find,用去推断2个顶面是可属于一个连通分量beginif x<>p[x] then p[x]:=find(p[x]);find:=p[x]end;procedure union(a,b:integer); //如果不属于且权值最小则将2个顶面合并到一个连通分量vart :integer;begina:=find(a);b:=find(b);if r[a]>r[b] then begin t:=a;a:=b;b:=t end;if r[a]=r[b]then inc(r[a]);p[a]:=b;end;procedure kruskal; //主历程varen :integer; //en为目前边的编号count :integer; //统计举止了频频合并.n-1次合并后便得到最小死成树tot :integer; //统计最小死成树的边权总战begincount:=0;en:=0; tot:=0;while count<n-1 dobegininc(en);with edges[en] dobeginif find(a)<>find(b) thenbeginunion(a,b);writeln(a,'--',b,':',len);inc(tot,len);inc(count);end;end;end;writeln('Total Length=',tot)end;{===========main==========} begininit;kruskal;end.例题详睹vijos p1045 Kerry 的电缆搜集typerec=recordx,y:longint;cost:real;end;varf:array[1..1000000] of rec;s,ans:real;i,n,m,k,dad:longint;father:array[1..1000000] of longint; procedurekp(l,r:longint);vari,j:longint;xx:real;y:rec;begini:=l;j:=r;xx:=f[(i+j) div 2].cost;repeatwhile xx>f[i].cost do inc(i);while xx<f[j].cost do dec(j);ifi<=j thenbeginy:=f[i];f[i]:=f[j];f[j]:=y;inc(i);dec(j);end;untili>j;ifi<r then kp(i,r);if l<j then kp(l,j);end;function find(x:longint):longint; beginif father[x]=x then exit(x);father[x]:=find(father[x]);exit(father[x]);end;procedure union(x,y:longint;j:real); beginx:=find(x);y:=find(y);if x<>y thenbeginfather[y]:=x;ans:=ans+j;inc(k);end;end;beginreadln(s);readln(n);m:=0;while not eof do begininc(m);with f[m] doreadln(x,y,cost); end;if m<n-1 then beginwriteln('Impossible'); exit;end;fori:=1 to n do father[i]:=i;kp(1,m);k:=0;fori:=1 to m dobeginif k=n-1 then break;union(f[i].x,f[i].y,f[i].cost);end;if k<n-1 thenbeginwriteln('Impossible');exit;end;ifans>s then writeln('Impossible') elsewriteln('Need ',ans:0:2,' miles of cable');end.Kruskal算法适用于边稀稀的情形,而Prim算法适用于边稀稀的情形其余最小死成树算法c++代码真止#include <stdio.h>#include <stdlib.h>#include <vector>using namespace std;#define MAXNUM_VERTEX 20 //最多有20个顶面#define MAXNUM_EDGE 21typedefstruct{intv,w;int weight;}Edge;typedefstruct{int vertex[MAXNUM_VERTEX];Edge edge[MAXNUM_EDGE];intnum_vertex,num_edge;}Graph;Graph graph; //声明为齐部变量boolsearch_vertex(intver){for(inti=0; i<graph.num_vertex; i++)if(ver == graph.vertex[i] )return 1;printf("the vertex %d you input is not existed! \n",ver); return 0;}voidcreate_graph(){//输进顶面疑息printf("input the number of vertex in the graph\n");scanf(" %d",&graph.num_vertex);printf("input the vertex of graph,like 1,2\n");for(inti=0; i<graph.num_vertex; i++)scanf(" %d",&graph.vertex[i]);//输进边疑息printf("input the number of edge in the graph\n");scanf(" %d",&graph.num_edge);printf("intput the edge of graph and the weight of line,like 1-2 5\n");for(int j=0; j<graph.num_edge; j++){p1:inta,c,d;char b;scanf(" %d %c %d %d",&a,&b,&c,&d);if(search_vertex(a) && search_vertex(c) ){graph.edge[j].v=a;graph.edge[j].w=c;graph.edge[j].weight=d;}elsegoto p1;}}voidsort_by_weight(){for(inti=1; i<graph.num_edge; i++){Edge temp=graph.edge[i];for(int j=i-1; j>=0 && graph.edge[j].weight>temp.weight; j--) graph.edge[j+1]=graph.edge[j];graph.edge[j+1]=temp;}}/*不相接集处理函数*/inline void makeset(vector<int> & array){for(inti=0; i<array.size(); i++)array[i]=i;}intfindset(vector<int> & parent,inti){if(i != parent[i])i=parent[i];returni;}inline void merge(vector<int> & parent,inti,int j) {parent[i]=j;}/*不相接集处理函数*/voidkruskal(){intnum_ver=graph.num_vertex;int count=0;vector<int> parent_ver;parent_ver.resize(num_ver);/*核心部分是用不相接集中成树*/ makeset(parent_ver);printf("the edge of min tree as follow: \n");for( inti=0; i<num_ver && count<num_ver-1; i++ ) //count 表示合并(merge)的次数num_ver-1次{int m=graph.edge[i].v;int n=graph.edge[i].w;int w=graph.edge[i].weight;if(findset(parent_ver,m) != findset(parent_ver,n)) //当属于分歧的集中时,则将该边增加进树中{printf("(%d %d) %d\n",m,n,w);merge(parent_ver,m,n);count++;}}}voidprint_edge(){printf("the graph you input as follow: \n");for(inti=0; i<graph.num_edge; i++)printf("%d-%d the weightis: %d\n",graph.edge[i].v,graph.edge[i].w,graph.edge[i].weight);}void main(){create_graph();sort_by_weight();print_edge();kruskal();}java代码真止importjava.util.ArrayList;importjava.util.Collections;class Bian implements Comparable // 二面之间的加权边{private intfirst,second;// 表示一条边的二个节面private int value;// 权值publicBian(intfirst,intsecond,int value) {this.first = first;this.second = second;this.value = value;}publicintgetFirst() {return first;}publicintgetSecond() {return second;}publicintgetValue() {return value;}@OverridepublicintcompareTo(Object arg0) {return value > ((Bian) arg0).value 1: (value == ((Bian) arg0).value 0 : -1);}@Overridepublic String toString() {return "Bian [first=" + first + ",second=" + second + ",value="+ value + "]";}}classShuZu {static ArrayList<ArrayList> list = newArrayList<ArrayList>();// 存搁每一个数组中的节面的数组static ArrayList<ArrayList> bianList = newArrayList<ArrayList>();// 对付应存搁数组中的边的数组public static void check(Bian b)// 查看正在哪个数组中{if (list.size() == 0) {ArrayList<Integer> sub = new ArrayList<Integer>();sub.add(b.getFirst());sub.add(b.getSecond());list.add(sub);ArrayList<Bian> bian = new ArrayList<Bian>();bian.add(b);bianList.add(bian);return;}int first = b.getFirst();int shuyu1 = -1;int second = b.getSecond();int shuyu2 = -1;for (inti = 0; i < list.size(); i++)// 查看二个节面分别属于哪个数组{for (int m = 0; m < list.get(i).size(); m++) {if (first == (Integer) list.get(i).get(m))shuyu1 = i;if (second == (Integer) list.get(i).get(m))shuyu2 = i;}}if (shuyu1 == -1 && shuyu2 == -1)// 表示那二个节面皆不需要新加进{ArrayList<Integer> sub = new ArrayList<Integer>();sub.add(b.getFirst());sub.add(b.getSecond());list.add(sub);ArrayList<Bian> bian = new ArrayList<Bian>();bian.add(b);bianList.add(bian);}if (shuyu1 == -1 && shuyu2 != -1)// 表示有一个面已经正在数组中只把另一个加进便不妨了{list.get(shuyu2).add(first);bianList.get(shuyu2).add(b);}if (shuyu2 == -1 && shuyu1 != -1)// 表示有一个面已经正在数组中只把另一个加进便不妨了{list.get(shuyu1).add(second);bianList.get(shuyu1).add(b);}if (shuyu1 == shuyu2 && shuyu1 != -1)// 表述二个正在共一个组中会产死环{}if (shuyu1 != shuyu2 && shuyu1 != -1 && shuyu2 != -1)// 表示二个面正在分歧的组中需要合并{for (inti = 0; i < list.get(shuyu2).size(); i++) {list.get(shuyu1).add(list.get(shuyu2).get(i));}list.remove(shuyu2);for (inti = 0; i < bianList.get(shuyu2).size(); i++) { bianList.get(shuyu1).add(bianList.get(shuyu2).get(i));}bianList.get(shuyu1).add(b);bianList.remove(shuyu2);}}public static void show() {for (inti = 0; i < bianList.get(0).size(); i++) System.out.println(bianList.get(0).get(i));}}public class Test {public static void main(String[] args) { ArrayList<Bian> l = new ArrayList<Bian>(); l.add(new Bian(1,3,1));l.add(new Bian(1,2,6));l.add(new Bian(1,4,5));l.add(new Bian(2,3,5));l.add(new Bian(2,5,3));l.add(new Bian(3,4,5));l.add(new Bian(3,5,6));l.add(new Bian(3,6,4));l.add(new Bian(4,6,2));l.add(new Bian(5,6,6));Collections.sort(l);// for(inti = 0 ;i<l.size();i++)// System.out.println(l.get(i)); for (inti = 0; i < l.size(); i++) ShuZu.check(l.get(i));ShuZu.show();}}。
shortestpathtree matlab 函数

shortestpathtree matlab 函数矩阵中的所有节点之间都有一些路径连接着。
某些路径可能是直接的,而有些可能需要经过其他节点。
寻找从一个节点到另一个节点的最短路径是图论中一个经典的问题。
在 MATLAB 中,可以使用 shortestpathtree 函数来解决这个问题。
首先,让我们了解一下最短路径树(Shortest Path Tree)是什么。
最短路径树是一个有向图,它以某个源节点为根节点,并将所有其他节点连接到根节点的最短路径。
最短路径树通常用于网络中的路由选择和通信网络中的拓扑控制。
在 MATLAB 中,你可以使用 shortestpathtree 函数来计算具有有向边的有向图的最短路径树。
这个函数采用一个邻接矩阵作为输入,并返回一个有向图的最短路径树。
邻接矩阵是一个 N×N 的矩阵,其中 N 是图中节点的数量。
邻接矩阵的第 i 行第 j 列的元素表示从节点 i 到节点 j 是否有一条边。
如果有边连接,则该元素的值为非零,否则为零。
在有向图中,边是有方向的,所以邻接矩阵是对称的。
为了使用 shortestpathtree 函数,我们首先需要创建一个邻接矩阵。
我们可以使用 MATLAB 中的矩阵操作来实现这一点。
例如,我们可以使用 zeros 函数创建一个全零矩阵,然后使用索引操作将适当的元素设置为非零值,从而表示边的存在。
例如,假设我们有一个图,其中有四个节点,从节点 1 到节点 3 有一条权重为2 的边,从节点 1 到节点 4 有一条权重为 5 的边,从节点 2 到节点 3 有一条权重为 1 的边,从节点 2 到节点 4 有一条权重为 3 的边。
我们可以通过以下方式创建邻接矩阵:matlabadjacency_matrix = zeros(4);adjacency_matrix(1, 3) = 2;adjacency_matrix(1, 4) = 5;adjacency_matrix(2, 3) = 1;adjacency_matrix(2, 4) = 3;现在我们已经创建了邻接矩阵,我们可以使用 shortestpathtree 函数来计算最短路径树。
最小生成树matlab实现

primclear all;close all;Graph1;%调用Graph1M文件,产生图1的邻接矩阵%Graph2;%调用Graph2M文件,产生图2的邻接矩阵len=length(graph_adjacent);%求图中有多少个顶点k=sprintf('please input the point where you want to start ,do rem ember it must be between 1 and %d ',len);start_point=input(k);%输入最小生成树产生起点while((start_point<=0)|(start_point>len))%如果输入的结点位置不合法即:小于等于零,或大于结点数,则重新输入disp('bad positon,please input again!');start_point=input(k);end;%************************************下面完成prim算法************** **************%相关变量初始设置tree=zeros(len-1,2);%用于保存选入最小生成树的边lowcost=zeros(1,len);%用来保存集合V-U与集合U中顶点的最短边权值,lowcost [v]=0表示顶点v已经%加入最小生成树中adjvex=zeros(1,len);%用来保存依附于该边在集合U中的节点,U集合为生成最小生成树的辅助集合,%首先U={start_point},之后依次确定为把最小生成树的一边的另一节点加入U%依次下去,直到图的全部顶点都在U中能找到lowcost=graph_adjacent(start_point,:);%lowcost(i)的值为节点i与start _point的权值;adjvex=start_point.*ones(1,len);%adjvex中所有元素的值都为初始节点%以下循n-1次,用于找出最小生成树的len-1条边for i=1:len-1k=lowcost>0;%k为一逻辑数组,它和lowcost同维,对于每一个位置i1lowcos t(i)>0则k(i)=1%否则k(i)=0;稍候将用这个数组进行辅助寻址cost_min=min(lowcost(k));%找出lowcost中除0外的最小值index=find(lowcost==cost_min);%找出此最小值在lowcost中的下标,即找到相应的节点index=index(1);%因为最小值的下标可能不止一个,这里取第一个下标进行处理 lowcost(index)=0;%表明该节点已经加入了最小生成树中tree(i,:)=[adjvex(index),index];%对lowcost和adjvex进行更新for j=1:lenif lowcost(j)>graph_adjacent(j,index);lowcost(j)=graph_adjacent(j,index);adjvex(j)=index;endendend;%*************************结果显示模块***************************** *******s=0;for ii=1:len-1k=sprintf('最小生成树第%d条边:(%d,%d),权值为%d',ii,tree(ii,1),tr ee(ii,2),graph_adjacent(tree(ii,1),tree(ii,2)));%格式化字符串%disp(k);%显示%disp(' ');%空一行s=s+graph_adjacent(tree(ii,1),tree(ii,2)); %求最小生成树的代价end%显示最小生成树的代价disp('最小生成树的总代价为:')disp(s);kruskalclear all;close all;Graph11;%调用以邻接矩阵储存的图所在的M文件%Graph22;len=length(graph_adjacent);%计算图中的顶点数temp=graph_adjacent;%将原图内容拷贝到temp中,以防对原图做改动superedge=zeros(len-1,2);%用于保存生成最小生成树的边i=1;%指向superedge的下标for j=1:lentag(j)=j;%关联标志初始化,将每个顶点的关联标志设为其本身end;%以下的循环完成kruskal算法while(superedge(len-1,1)==0)[Y,I]=sort(temp);%将temp的每列按从小到大排序,数组Y保存temp 排序后的结果,I中保存相应结果对应的在temp中的下标cost_min=min(Y(1,:));%找出权值最小的边index=find(Y(1,:)==cost_min);%找出权值最小的边对应的顶点index=index(1);%一条边对应两个节点,且不同的边的权值可能一样,这里为了方便处理人为规定了顺序,取标号最小的顶点进行处理anotherpoint=I(1,index);%找到该边对应的另一个顶点%将该边对应的权值修改为最大,防止该边在下次循环中再次被选为最优边temp(index,anotherpoint)=100;temp(anotherpoint,index)=100;if(tag(anotherpoint)~=tag(index))%当两个点不属于一个连通集时,这两个点之间的边为最小生成树的边superedge(i,:)=[index,anotherpoint];%将其加入最小生成树的边集中i=i+1;%下标加1%下面的语句的作用是将两个连通分支变成一个连通分支,即tag值一样for j=1:len%以index的tag值为标准if((tag(j)==tag(anotherpoint))&(j~=anotherpoint))%遍搜tag数组,先将和anotherpoint tag值一样的点的tag值变为index的tag值tag(j)=tag(index);endendtag(anotherpoint)=tag(index);%将anotherpoint的tag值变为in dex的tag值endend%*************************结果显示模块**************************** ********s=0;for ii=1:len-1k=sprintf('最小生成树第%d条边:(%d,%d),权值为%d',ii,superedge(ii,1),superedge(ii,2),graph_adjacent(superedge(ii,1),superedge(ii,2)));%格式化字符串%disp(k);%显示%disp(' ');%空一行s=s+graph_adjacent(superedge(ii,1),superedge(ii,2)); %求最小生成树的代价end%显示最小生成树的代价disp('最小生成树的总代价为:')disp(s);。
模型建立与算法构造:基于Prim算法构造最小生成树

模型建立与算法构造:基于Prim算法构造最小生成树作者:李琳赵娟虎建勋来源:《科教导刊·电子版》2019年第12期摘要最小生成树有许多重要的应用。
例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。
这就需要找到带权的最小生成树。
本文通过使用Matlab软件进行编程实现了用Prim算法构造最小生成树的分析运算。
本程序可以方便地处理层次分析法下较大的运算量,解决层次分析法的效率问题,提高计算机辅助决策的时效性。
其中建立了有效的基于Prim算法的数学模型并验证了模型的合理性和科学准确性。
利用MATLAB、EXCEL、SPSS13.0 for windows等软件,实现了高效、准确的研究。
关键词模型 atlab软件算法构造中图分类号:TP312 文献标识码:A1建立结构模型1.1最小生成树相关概念连通图:任意两个结点之间都有一个路径相连。
生成树(Spannirng Tree):连通图的一个极小的连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。
最小生成树(Minimum Spannirng Tree):连通图的最小代价的生成树(各边的权值之和最小)。
最小生成树即对于连通的带权图(连通网)G,其生成树也是带权的。
生成树T各边的权值总和称为该树的权,记作:这里:TE表示T的边集,w(u,v)表示边(u,v)的权。
权最小的生成樹称为G的最小生成树(Minimum SpannirngTree)。
最小生成树可简记为MST。
1.2 Prim算法实现Prim算法是一种贪心算法,将全部的顶点划分为2个集合,每次总在2个集合之间中找最小的一条边,局部最优最终达到全局最优,这正是贪心的思想。
在无向加权图中,n个顶点的最小生成树有n-1条边,这些边使得n个顶点之间可达,且总的代价最小。
matlab 普里姆算法

matlab 普里姆算法普里姆算法是一种最小生成树算法,用于求解给定图的最小生成树。
该算法基于贪心策略,每次选择当前已选中的点集到未选中的顶点集中距离最近的一条边,将该边所连接的点加入到已选中的点集中。
在实现普里姆算法时,我们需要使用一个优先队列用于存储当前已选中的点集到未选中的顶点集中的边,以及每个顶点到已选中的点集中最小距离。
在每次选取最小距离的边时,我们将该边所连接的点加入到已选中的点集中,并将该点与未选中的点集中的所有点之间的距离加入到优先队列中,同时更新已选中的点集到未选中的顶点集中的最小距离。
该过程重复进行,直到所有的顶点都已经被加入到已选中点集中,最终得到的图就是原图的最小生成树。
下面是使用matlab实现普里姆算法的示例代码:function MST = prim_algorithm(graph)% graph为邻接矩阵,MST为最小生成树的邻接矩阵表示n = size(graph, 1); % 获取图中节点数key = Inf(1,n); % 存储每个顶点与已选中点集的最小距离mst = zeros(n, n); % 存储最小生成树的邻接矩阵表示visited = false(1,n); % 存储每个顶点是否已加入到已选中点集中pq = PriorityQueue(n); % 创建优先队列start = 1; % 从任意一个顶点开始寻找最小生成树key(start) = 0; % 起始点距离已选中点集的最小距离为0pq.insert(start, 0); % 将起始点加入到优先队列中while ~pq.isempty() % 当优先队列非空时进行迭代[u, cost] = pq.deleteMin(); % 选取距离已选中点集最近的边visited(u) = true; % 将选中的顶点加入到已选中点集中if u ~= start % 将当前边加入到最小生成树的邻接矩阵中mst(parent(u), u) = cost;mst(u, parent(u)) = cost;endfor v = 1:n % 更新与已选点集中每个顶点的最小距离if ~visited(v) && graph(u,v) < key(v)parent(v) = u;key(v) = graph(u,v);if pq.contains(v)pq.updatePriority(v, key(v));elsepq.insert(v, key(v));endendendendMST = mst;end该代码中借助matlab的优先队列类PriorityQueue实现了优先队列的功能,其中包括了队列插入、队列删除、队列是否为空、队列中是否包含某元素以及队列中某元素优先级的更新等方法。
Matlab中求解最小生成树

数学建模——Matlab中求解最小生成树关键词:Matlab、最小生成树、破圈法、避圈法、运筹学要求:选择一道编程题自己独立完成,必须自己编写源代码,不能从网上下载。
先编写算法的通用程序,然后以例子运行,论文内容包括程序代码、程序说明、例子运行结果,最终程序文件连同论文一起发至e-mail,便于老师运行程序是否正确。
编程使用C或MATLAB。
选择题目:编写实现生成树、最小生成树的程序(包括避圈法、破圈法)。
题目分析:本题要求编写实现生成树、最小生成树的程序,首先来了解一下关于关于生成树的概念:1、树的概念:树是无向图的特殊情况,即对于一个N个节点的无向图,其中只有N-1条边,且图中任意两点间有且只有一条路径,即图中不存在环,这样的图称为树。
2、生成树的概念:对于一个无向连通图G=(V,E),其中V代表顶点,E代表边,对它做一次遍历,每个节点经过一次,那么图中的N个节点再加上遍历过程中经过的N-1条边所构成的子图就是图G的一个生成树。
3、最小生成树的概念:对于一个无向连通图G=(V,E),给它的每条边(u,v)赋一个权值w(u,v)。
若图G 的生成树不止一个,那么其中包含的N-1条边的权值之和的最小的生成树就是图G的最小生成树。
4、关于运筹学中最小生成树有2种不错的算法,即避圈法和破圈法,下面来看一下求解最小生成树的算法:先看一下图示法表示的最小生成树:<1>避圈法求解上面无向带权连通图的基本步骤是:每步从未选的边中选取边e,使它与已选边不构成圈,且e是未选边中的最小权边,直到选够n-1条边为止。
<2>破圈法基本思想如下:(1) 每次从图中选取任意一个圈, 然后去掉该圈中权值最大的边(如果存在多条相同权值的最大边,可以任意选择一条去掉即可) 使之不构成圈.(2) 重复上述过程. 直到图中不再含圈且所有顶点均包含在图中为止, 就构成最小生成树.它的算法图解如下:5、我们在用matlab程序求解最小生成树的时候需要用到无向图的邻接矩阵,首先来了解一下邻接矩阵的概念。
Matlab中避圈法求解最小生成树

end
end
P(2,y)=P(1,y);
elseif P(2,y)<P(1,y)
for l=(y+1):m
%准备工作
T=zeros(n); %最小生成树的加权邻接矩阵
WW=W;
for i=1:n
for j=1:n
if W(i,j)==inf WW(i,j)=0;
end
end
end
m=((nnz(WW))/2); %图的边线的数目
%编程工具Matlab;程序名称MST_k.m.
%这是一个通过避圈法求解连通带权图的最小生成树的程序.
n=input('请输入图的顶点数目:n= ')
W=input('请输入图的加权邻接矩阵:[W(1,1),..,W(1,n);..;W(n,1),..,W(n,n)]=')
%用W(i,i)="inf" 代替 "=0"
end
W(a,b)=inf;
else %如果条件|E|=|V|-1成立
MST=T;
input('这个图的最小生成树的加权邻接矩阵是:')
MST
break
end
Байду номын сангаас
end
if j<(n-1) %如果条件|E|<|V|-1成立
input('这个图没有最小生成树.')
end
j=0; %最小生成树的边线的数目
%主要步骤
for i=1:m %被选择边线的数目
2023五一杯数学建模b题matlab代码

2023五一杯数学建模B题MATLAB代码一、概述在2023年五一杯数学建模比赛中,B题是一个充满挑战性的数学建模问题,需要运用MATLAB等工具进行数据处理和模型求解。
本文将针对该题目展开讨论,介绍相应的MATLAB代码。
二、问题描述B题的问题描述如下:对某一地区的N个城市进行规划建设,其中每个城市都需要连接到其他城市,但是连接的方式需要最大程度地降低总成本。
现有每个城市之间建设高速公路的成本数据,问题要求设计出一种最优的高速公路规划方案。
三、MATLAB代码展示1. 数据处理首先需要载入城市之间的成本数据,假设成本数据保存在一个名为cost_matrix的N*N矩阵中。
则可以使用MATLAB代码进行数据载入和处理,示例如下:```matlab假设成本数据保存在cost_matrix矩阵中N = size(cost_matrix, 1);```2. 模型求解需要设计一个数学模型来求解最优的高速公路规划方案。
这里可以采用最小生成树算法(Minimum Spanning Tree,MST)来解决问题。
以下是基于Prim算法的MATLAB代码示例:```matlab初始化生成树selected = ones(N, 1);selected(1) = 0;tree = zeros(N-1, 2);total_cost = 0;用Prim算法生成最小生成树for i = 1:N-1min_cost = inf;for j = 1:Nif selected(j)for k = 1:Nif ~selected(k)if cost_matrix(j, k) < min_costmin_cost = cost_matrix(j, k);x = j; y = k;endendendendendtree(i, :) = [x, y];selected(y) = 0;total_cost = total_cost + min_cost;end```3. 结果展示可以将生成的最小生成树结果进行可视化展示,以便于分析和进一步优化。
(图论)matlab模板程序

第一讲:图论模型程序一:可达矩阵算法%根据邻接矩阵A〔有向图〕求可达矩阵P〔有向图〕function P=dgraf<A>n=size<A,1>;P=A;for i=2:nP=P+A^i;endP<P~=0>=1; %将不为0的元素变为1P;程序二:无向图关联矩阵和邻接矩阵互换算法F表示所给出的图的相应矩阵W表示程序运行结束后的结果f=0表示把邻接矩阵转换为关联矩阵f=1表示把关联矩阵转换为邻接矩阵%无向图的关联矩阵和邻接矩阵的相互转换function W=incandadf<F,f>if f==0 %邻接矩阵转换为关联矩阵m=sum<sum<F>>/2; %计算图的边数n=size<F,1>;W=zeros<n,m>;k=1;for i=1:nfor j=i:nif F<i,j>~=0W<i,k>=1; %给边的始点赋值为1W<j,k>=1; %给边的终点赋值为1k=k+1;endendendelseif f==1 %关联矩阵转换为邻接矩阵m=size<F,2>;n=size<F,1>;W=zeros<n,n>;for i=1:ma=find<F<:,i>~=0>;W<a<1>,a<2>>=1; %存在边,则邻接矩阵的对应值为1 W<a<2>,a<1>>=1;endelsefprint<'Please imput the right value of f'>;W;程序三:有向图关联矩阵和邻接矩阵互换算法%有向图的关联矩阵和邻接矩阵的转换function W=mattransf<F,f>if f==0 %邻接矩阵转换为关联矩阵m=sum<sum<F>>;n=size<F,1>;W=zeros<n,m>;k=1;for i=1:nfor j=i:nif F<i,j>~=0 %由i发出的边,有向边的始点W<i,k>=1; %关联矩阵始点值为1W<j,k>=-1; %关联矩阵终点值为-1k=k+1;endendendelseif f==1 %关联矩阵转换为邻接矩阵m=size<F,2>;n=size<F,1>;W=zeros<n,n>;for i=1:ma=find<F<:,i>~=0>; %有向边的两个顶点if F<a<1>,i>==1W<a<1>,a<2>>=1; %有向边由a<1>指向a<2>elseW<a<2>,a<1>>=1; %有向边由a<2>指向a<1>endendelsefprint<'Please imput the right value of f'>;endW;第二讲:最短路问题程序0:最短距离矩阵W表示图的权值矩阵D表示图的最短距离矩阵%连通图中各项顶点间最短距离的计算function D=shortdf<W>%对于W<i,j>,若两顶点间存在弧,则为弧的权值,否则为inf;当i=j时W<i,j>=0 n=length<W>;m=1;while m<=nfor i=1:nfor j=1:nif D<i,j>>D<i,m>+D<m,j>D<i,j>+D<i,m>+D<m,j>; %距离进行更新 endendendm=m+1;endD;程序一:Dijkstra算法〔计算两点间的最短路〕function [l,z]=Dijkstra<W>n = size <W,1>;for i = 1 :nl<i>=W<1,i>;z<i>=0;endi=1;while i<=nfor j =1 :nif l<i>>l<j>+W<j,i>l<i>=l<j>+W<j,i>;z<i>=j-1;if j<ii=j-1;endendendi=i+1;end程序二:floyd算法〔计算任意两点间的最短距离〕function [d,r]=floyd<a>n=size<a,1>;d=a;for i=1:nfor j=1:nr<i,j>=j;endendr;for k=1:nfor i=1:nfor j=1:nif d<i,k>+d<k,j><d<i,j>d<i,j>=d<i,k>+d<k,j>; r<i,j>=r<i,k>;endendendend程序三:n2short.m 计算指定两点间的最短距离function [P u]=n2short<W,k1,k2>n=length<W>;U=W;m=1;while m<=nfor i=1:nfor j=1:nif U<i,j>>U<i,m>+U<m,j>U<i,j>=U<i,m>+U<m,j>;endendendm=m+1;endu=U<k1,k2>;P1=zeros<1,n>;k=1;P1<k>=k2;V=ones<1,n>*inf;kk=k2;while kk~=k1for i=1:nV<1,i>=U<k1,kk>-W<i,kk>;if V<1,i>==U<k1,i>P1<k+1>=i;kk=i;k=k+1;endendendk=1;wrow=find<P1~=0>;for j=length<wrow>:-1:1P<k>=P1<wrow<j>>;k=k+1;endP;程序四、n1short.m<计算某点到其它所有点的最短距离> function[Pm D]=n1short<W,k>n=size<W,1>;D=zeros<1,n>;for i=1:n[P d]=n2short<W,k,i>;Pm{i}=P;D<i>=d;end程序五:pass2short.m<计算经过某两点的最短距离> function [P d]=pass2short<W,k1,k2,t1,t2>[p1 d1]=n2short<W,k1,t1>;[p2 d2]=n2short<W,t1,t2>;[p3 d3]=n2short<W,t2,k2>;dt1=d1+d2+d3;[p4 d4]=n2short<W,k1,t2>;[p5 d5]=n2short<W,t2,t1>;[p6 d6]=n2short<W,t1,k2>;dt2=d4+d5+d6;if dt1<dt2d=dt1;P=[p1 p2<2:length<p2>> p3<2:length<p3>>]; elsed=dt1;p=[p4 p5<2:length<p5>> p6<2:length<p6>>]; endP;d;第三讲:最小生成树程序一:最小生成树的Kruskal算法function [T c]=krusf<d,flag>if nargin==1n=size<d,2>;m=sum<sum<d~=0>>/2;b=zeros<3,m>;k=1;for i=1:nfor j=<i+1>:nif d<i,j>~=0b<1,k>=i;b<2,k>=j;b<3,k>=d<i,j>;k=k+1;endendendelseb=d;endn=max<max<b<1:2,:>>>;m=size<b,2>;[B,i]=sortrows<b',3>;B=B';c=0;T=[];k=1;t=1:n;for i=1:mif t<B<1,i>>~=t<B<2,i>>T<1:2,k>=B<1:2,i>;c=c+B<3,i>;k=k+1;tmin=min<t<B<1,i>>,t<B<2,i>>>; tmax=max<t<B<1,i>>,t<B<2,i>>>; for j=1:nif t<j>==tmaxt<j>=tmin;endendendif k==nbreak;endendT;c;程序二:最小生成树的Prim算法function [T c]=Primf<a>l=length<a>;a<a==0>=inf;k=1:l;listV<k>=0;listV<1>=1;e=1;while <e<l>min=inf;for i=1:lif listV<i>==1for j=1:lif listV<j>==0 & min>a<i,j>min=a<i,j>;b=a<i,j>;s=i;d=j;endendendendlistV<d>=1;distance<e>=b;source<e>=s;destination<e>=d;e=e+1;endT=[source;destination];for g=1:e-1c<g>=a<T<1,g>,T<2,g>>;endc;第四讲:Euler图和Hamilton图程序一:Fleury算法〔在一个Euler图中找出Euler环游〕注:包括三个文件;fleuf1.m, edf.m, flecvexf.mfunction [T c]=fleuf1<d>%注:必须保证是Euler环游,否则输出T=0,c=0n=length<d>;b=d;b<b==inf>=0;b<b~=0>=1;m=0;a=sum<b>;eds=sum<a>/2;ed=zeros<2,eds>;vexs=zeros<1,eds+1>;matr=b;for i=1:nif mod<a<i>,2>==1m=m+1;endendif m~=0fprintf<'there is not exit Euler path.\n'>T=0;c=0;endif m==0vet=1;flag=0;t1=find<matr<vet,:>==1>;for ii=1:length<t1>ed<:,1>=[vet,t1<ii>];vexs<1,1>=vet;vexs<1,2>=t1<ii>;matr<vexs<1,2>,vexs<1,1>>=0;flagg=1;tem=1;while flagg[flagg ed]=edf<matr,eds,vexs,ed,tem>;tem=tem+1;if ed<1,eds>~=0 & ed<2,eds>~=0T=ed;T<2,eds>=1;c=0;for g=1:edsc=c+d<T<1,g>,T<2,g>>;endflagg=0;break;endendendendfunction[flag ed]=edf<matr,eds,vexs,ed,tem>flag=1;for i=2:eds[dvex f]=flecvexf<matr,i,vexs,eds,ed,tem>;if f==1flag=0;break;endif dvex~=0ed<:,i>=[vexs<1,i> dvex];vexs<1,i+1>=dvex;matr<vexs<1,i+1>,vexs<1,i>>=0;elsebreak;endendfunction [dvex f]=flecvexf<matr,i,vexs,eds,ed,temp> f=0;edd=find<matr<vexs<1,i>,:>==1>;dvex=0;dvex1=[];ded=[];if length<edd>==1dvex=edd;elsedd=1;dd1=0;kkk=0;for kk=1:length<edd>m1=find<vexs==edd<kk>>;if sum<m1>==0dvex1<dd>=edd<kk>;dd=dd+1;dd1=1;elsekkk=kkk+1;endendif kkk==length<edd>tem=vexs<1,i>*ones<1,kkk>;edd1=[tem;edd];for l1=1:kkklt=0;ddd=1;for l2=1:edsif edd1<1:2,l1>==ed<1:2,l2>lt=lt+1;endendif lt==0ded<ddd>=edd<l1>;ddd=ddd+1;endendendif temp<=length<dvex1>dvex=dvex1<temp>;elseif temp>length<dvex1> & temp<=length<ded>dvex=ded<temp>;elsef=1;endend程序二:Hamilton改良圈算法〔找出比较好的Hamilton路〕function [C d1]= hamiltonglf<v>%d表示权值矩阵%C表示算法最终找到的Hamilton圈.%v =[ 51 67;37 84;41 94;2 99;18 54;4 50;24 42;25 38;13 40;7 64;22 60;25 62;18 40;41 26];n=size<v,1>;subplot<1,2,1>hold on;plot <v<:,1>,v<:,2>,'*'>; %描点for i=1:nstr1='V';str2=num2str<i>;dot=[str1,str2];text<v<i,1>-1,v<i,2>-2,dot>; %给点命名endplot <v<:,1>,v<:,2>>;%连线plot<[v<n,1>,v<1,1>],[v<n,2>,v<1,2>]>;for i =1:nfor j=1:nd<i,j>=sqrt<<v<i,1>-v<j,1>>^2+<v<i,2>-v<j,2>>^2>;endendd2=0;for i=1:nif i<nd2=d2+d<i,i+1>;elsed2=d2+d<n,1>;endendtext<10,30,num2str<d2>>;n=size<d,2>;C=[linspace<1,n,n> 1];for nnn=1:20C1=C;if n>3for m=4:n+1for i=1:<m-3>for j=<i+2>:<m-1>if<d<C<i>,C<j>>+d<C<i+1>,C<j+1>><d<C<i>,C<i+1>>+d<C<j>,C<j+1>>>C1<1:i>=C<1:i>;for k=<i+1>:jC1<k>=C<j+i+1-k>;endC1<<j+1>:m>=C<<j+1>:m>;endendendendelseif n<=3if n<=2fprint<'It does not exist Hamilton circle.'>; elsefprint<'Any cirlce is the right answer.'>;endendC=C1;d1=0;for i=1:nd1=d1+d<C<i>,C<i+1>>;endd1;endsubplot<1,2,2>;hold on;plot <v<:,1>,v<:,2>,'*'>; %描点for i=1:nstr1='V';str2=num2str<i>;dot=[str1,str2];text<v<i,1>-1,v<i,2>-2,dot>; %给点命名endv2=[v;v<1,1>,v<1,2>];plot<v<C<:>,1>,v<C<:>,2>,'r'>;text<10,30,num2str<d1>>;第五讲:匹配问题与算法程序一:较大基础匹配算法function J=matgraf<W>n=size<W,1>;J=zeros<n,n>;while sum<sum<W>>~=0a=find<W~=0>;t1=mod<a<1>,n>;if t1==0t1=n;endif a<1>/n>floor<a<1>/n>t2=floor<a<1>/n>+1;elset2=floor<a<1>/n>;endJ<t1,t2>=1,J<t2,t1>=1;W<t1,:>=0;W<t2,:>=0;W<:,t1>=0;W<:,t2>=0;endJ;程序二:匈牙利算法〔完美匹配算法,包括三个文件fc01,fc02,fc03〕function [e,s]=fc01<a,flag>if nargin==1flag=0;endb=a;if flag==0cmax=max<max<b>'>;b=cmax-b;endm=size<b>;for i =1:m<1>b<i,:>=b<i,:>-min<b<i,:>>;endfor j=1:m<2>b<:,j>=b<:,j>-min<b<:,j>>;endd=<b==0>;[e,total]=fc02<d>;while total~=m<1>b=fc03<b,e>;d=<b==0>;[e,total]=fc02<d>;endinx=sub2ind<size<a>,e<:,1>,e<:,2>>;e=[e,a<inx>];s=sum<a<inx>>;function [e,total]=fc02<d>total=0;m=size<d>;e=zeros<m<1>,2>;t=sum<sum<d>'>;nump=sum<d'>;while t~=0[s,inp]=sort<nump>;inq=find<s>;ep=inp<inq<1>>;inp=find<d<ep,:>>;numq=sum<d<:,inp>>;[s,inq]=sort<numq>;eq=inp<inq<1>>;total=total+1;e<total,:>=[ep,eq];inp=find<d<:,eq>>;nump<inp>=nump<inp>-1;nump<ep>=0;t=t-sum<d<ep,:>>-sum<d<:,eq>>+1;d<ep,:>=0*d<ep,:>;d<:,eq>=0*d<:,eq>;endfunction b=fc03<b,e>m=size<b>;t=1;p=ones<m<1>,1>;q=zeros<m<1>,1>;inp=find<e<:,1>~=0>;p<e<inp,1>>=0;while t~=0tp=sum<p+q>;inp=find<p==1>;n=size<inp>;for i=1:n<1>inq=find<b<inp<i>,:>==0>;q<inq>=1;endinp=find<q==1>;n=size<inp>;for i=1:n<1>if all<e<:,2>-inp<i>>==0inq=find<<e<:,2>-inp<i>>==0>;p<e<inq>>=1;endendtq=sum<p+q>;t=tq-tp;endinp=find<p==1>;inq=find<q==0>;cmin=min<min<b<inp,inq>>'>;inq=find<q==1>;b<inp,:>=b<inp,:>-cmin;b<:,inq>=b<:,inq>+cmin;第六讲:最大流最小费用问题程序一:2F算法<Ford-Fulkerson算法>,求最大流%C=[0 5 4 3 0 0 0 0;0 0 0 0 5 3 0 0;0 0 0 0 0 3 2 0;0 0 0 0 0 0 2 0; %0 0 0 0 0 0 0 4;0 0 0 0 0 0 0 3;0 0 0 0 0 0 0 5;0 0 0 0 0 0 0 0 ] function [f wf]=fulkersonf<C,f1>%C表示容量%f1表示当前流量,默认为0%f表示最大流±íʾ×î´óÁ÷%wf表示最大流的流量n=length<C>;if nargin==1;f=zeros<n,n>;elsef=f1;endNo=zeros<1,n>;d=zeros<1,n>;while <1>No<1>=n+1;d<1>=Inf;while <1>pd=1;for <i=1:n>if <No<i>>for <j=1:n>if <No<j>==0 & f<i,j><C<i,j>>No<j>=i;d<j>=C<i,j>-f<i,j>;pd=0;if <d<j>>d<i>>d<j>=d<i>;endelseif <No<j>==0 & f<j,i>>0>No<j>=-i;d<j>=f<j,i>;pd=0;if <d<j>>d<i>>d<j>=d<i>;endendendendendif <No<n>|pd>break;endendif <pd>break;enddvt=d<n>;t=n;while <1>if<No<t>>0>f<No<t>,t>=f<No<t>,t>+dvt;elseif <No<t><0>f<No<t>,t>=f<No<t>,t>-dvt;endif <No<t>==1>for <i=1:n>No<i>=0;d<i>=0;endbreakendt=No<t>;endendwf=0;for <j=1:n>wf=wf+f<1,j>;endf;wf;程序二:Busacker-Gowan算法<求最大流最小费用>%C=[0 15 16 0 0;0 0 0 13 14;0 11 0 17 0;0 0 0 0 8;0 0 0 0 0] %b=[0 4 1 0 0;0 0 0 6 1;0 2 0 3 0;0 0 0 0 2;0 0 0 0 0]%function [f wf zwf]=BGf<C,b>%C表示弧容量矩阵%b表示弧上单位流量的费用%f表示最大流最小费用矩阵%wf最大流量%zwf表示最小费用n=size<C,2>;wf=0;wf0=inf;f=zeros<n,n>;while <1>a=ones<n,n>*inf;for <i=1:n>a<i,i>=0;endfor <i=1:n>for <j=1:n>if<C<i,j>>0 & f<i,j>==0>a<i,j>=b<i,j>;elseif <C<i,j>>0 & f<i,j>==C<i,j>>a<j,i>=-b<i,j>;elseif <C<i,j>>0>a<i,j>=b<i,j>;a<j,i>=-b<i,j>;endendendfor <i=2:n>p<i>=inf;s<i>=i;endfor <k=1:n>pd=1;for <i=2:n>for <j=1:n>if <p<i>>p<j>+a<j,i>>p<i>=p<j>+a<j,i>;s<i>=j;pd=0; endendendif <pd>break;endendif <p<n>==inf>break;enddvt=inf;t=n;while <1>if <a<s<t>,t>>0>dvtt=C<s<t>,t>-f<s<t>,t>;elseif <a<s<t>,t><0>dvtt=f<t,s<t>>;endif <dvt>dvtt>dvt=dvtt;endif <s<t>==1>break;endt=s<t>;endpd=0;if <wf+dvt>=wf0>dvt=wf0-wf;pd=1;endt=n;while <1>if <a<s<t>,t>>0>f<s<t>,t>=f<s<t>,t>+dvt; elseif <a<s<t>,t><0>f<<t>,s<t>>=f<t,s<t>>-dvt; endif <s<t>==1>break;endt=s<t>;endif <pd>break;endwf=0;for <j=1:n>wf=wf+f<1,j>;endendzwf=0;for <i=1:n>for <j=1:n>zwf=zwf+b<i,j>*f<i,j>;endendf;。
最小生成树matlab程序

function [Wt,Pp]=mintree(n,W)%求最小生成树,n为顶点个数,W是权值邻接矩阵,不相邻的用inf表示%Wt是最小生成树的权,Pp(:,1:2)表示最小生成树的两顶点%Pp(:,4)表示最小生成树的序号tmpa=find(W~=inf);[tmpb,tmpc]=find(W~=inf);w=W(tmpa);e=[tmpb,tmpc];[wa,wb]=sort(w);E=[e(wb,:),wa,wb];[nE,mE]=size(E);temp=find(E(:,1)-E(:,2));E=E(temp,:);P=E(1,:);k=length(E(:,1));while rank(E)>0temp1=max(E(1,2),E(1,1));temp2=min(E(1,2),E(1,1));for i=1:kif E(i,1)==temp1E(i,1)=temp2;endif E(i,2)==temp1E(i,2)=temp2;endenda=find(E(:,1)-E(:,2));E=E(a,:);if rank(E)>0P=[P;E(1,:)];k=length(E(:,1));endendWt=sum(P(:,3));Pp=[e(P(:,4),:),P(:,3:4)];for i=1:length(P(:,3))disp(['','e',num2str(P(i,4)),'',...'(v',num2str(P(i,1)),'','v',num2str(P(i,2)),')']);endaxis equal;%画最小生成树hold on[x,y]=cylinder(1,n);xm=min(x(1,:));ym=min(y(1,:));xx=max(x(1,:));yy=max(y(1,:));axis([xm-abs(xm)*,xx+abs(xx)*,ym-abs(ym)*,yy+abs(yy)*]); plot(x(1,:),y(1,:),'ko');for i=1:ntemp=['v',int2str(i)];text(x(1,i),y(1,i),temp);endfor i=1:nEplot(x(1,e(i,:)),y(1,e(i,:)),'b');endfor i=1:length(P(:,4))plot(x(1,Pp(i,1:2)),y(1,Pp(i,1:2)),'r');endtext,,['最小生成树的权为','',num2str(Wt)]);title('红色连线为最小生成树');axis off;hold off;调用此程序要先编写主程序。
最小生成树(MATLAB)

prim算法设置两个集合P和Q,其中P 用于存放G的最小生成树中的顶点,集合Q存放G的最小生成树中的边。
令集合P的初值为P={V1}(假设构造最小生成树时,从顶点V1出发),集合Q的初值为。
Prime算法的思想是,从所有p ∈P,v∈V-P的边中,选取具有最小权值的边pv,将顶点v加入集合P中,将边pv 加入集合Q中,如此不断重复,直到P=V时,最小生成树构造完毕,这时集合Q中包含了最小生成的所有边。
(找最小的权,不连成圈即可)•clc;clear;•M=1000;•a(1,2)=50; a(1,3)=60;•a(2,4)=65; a(2,5)=40;•a(3,4)=52;a(3,7)=45;•a(4,5)=50; a(4,6)=30;a(4,7)=42;•a(5,6)=70;•a=[a;zeros(2,7)];•a=a+a';a(find(a==0))=M;•result=[];p=1;tb=2:length(a);•while length(result)~=length(a)-1•temp=a(p,tb);temp=temp(:);•d=min(temp);•[jb,kb]=find(a(p,tb)==d);•j=p(jb(1));k=tb(kb(1));•result=[result,[j;k;d]];p=[p,k];tb(find(tb==k))=[];•end•result•例、一个乡有7个自然村,其间道路如图所示,要以村为中心建有线广播网络,如要求沿道路架设广播线,应如何架设?Kruskal算法每步从未选的边中选取边e,使它与已选边不构成圈,且e 是未选边中的最小权边,直到选够n-1条边为止。
•clc;clear;•M=1000;•a(1,2)=50; a(1,3)=60;•a(2,4)=65; a(2,5)=40;•a(3,4)=52;a(3,7)=45;•a(4,5)=50; a(4,6)=30;a(4,7)=42;•a(5,6)=70;•[i,j]=find((a~=0)&(a~=M));•b=a(find((a~=0)&(a~=M)));•data=[i';j';b'];index=data(1:2,:);•loop=max(size(a))-1;•result=[];•while length(result)<loop•temp=min(data(3,:));•flag=find(data(3,:)==temp);•flag=flag(1);•v1=data(1,flag);v2=data(2,flag);•if index(1,flag)~=index(2,flag)•result=[result,data(:,flag)];•end•if v1>v2•index(find(index==v1))=v2;•else•index(find(index==v2))=v1;•end•data(:,flag)=[];•index(:,flag)=[];•end•result中国邮递员问题中国邮递员问题也可以表示为:在一个有奇点的连通图中。
最小生成树-数学建模

1
.5
.5 3
1
2
9
.14
5
80
.87
7
.75
.67 4
6
.5 3
.5
1
2
9
.14
5
80
7
.75
.67 4
6
模型结果
机器的分组: {3,9},
.5 3 9
.5
1
2
.14
{1,2,5},
5
{4,6,7,8}。
8
0 7
.75
.67 4
6
你能给出对应于该机器分组
的零件分类吗?
返回
最小生成树问题的0-1规划模型
17]
22 22 17 15 15 16 11 11 10 0;
18] enddata
最小生成树问题的0-1规划模型
19]n=@size(cities); !The model size; 20]! Minimize total distance of the links; 21]min=@sum(link(i,j)|i #ne# j: distance(i,j)*x(i,j)); 22]!There must be an arc out of city 1; 23]@sum(cities(i)|i #gt# 1: x(1,i))>=1; 24]!For city i, except the base (city 1); 25]@for(cities(i) | i #gt# 1 : 26]! It must be entered; 27] @sum(cities(j)| j #ne# i: x(j,i))=1; 28]! level(j)=levle(i)+1, if we link j and i;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
function [Wt,Pp]=mintree(n,W)
%求最小生成树,n为顶点个数,W就是权值邻接矩阵,不相邻的用inf表示%Wt就是最小生成树的权,Pp(:,1:2)表示最小生成树的两顶点
%Pp(:,4)表示最小生成树的序号
tmpa=find(W~=inf);
[tmpb,tmpc]=find(W~=inf);
w=W(tmpa);
e=[tmpb,tmpc];
[wa,wb]=sort(w);
E=[e(wb,:),wa,wb];
[nE,mE]=size(E);
temp=find(E(:,1)-E(:,2));
E=E(temp,:);
P=E(1,:);
k=length(E(:,1));
while rank(E)>0
temp1=max(E(1,2),E(1,1));
temp2=min(E(1,2),E(1,1));
for i=1:k
if E(i,1)==temp1
E(i,1)=temp2;
end
if E(i,2)==temp1
E(i,2)=temp2;
end
end
a=find(E(:,1)-E(:,2));
E=E(a,:);
if rank(E)>0
P=[P;E(1,:)];
k=length(E(:,1));
end
end
Wt=sum(P(:,3));
Pp=[e(P(:,4),:),P(:,3:4)];
for i=1:length(P(:,3))
disp(['','e',num2str(P(i,4)),'',、、、
'(v',num2str(P(i,1)),'','v',num2str(P(i,2)),')']);
end
axis equal;%画最小生成树
hold on
[x,y]=cylinder(1,n);
xm=min(x(1,:));
ym=min(y(1,:));
xx=max(x(1,:));
yy=max(y(1,:));
axis([xm-abs(xm)*0、15,xx+abs(xx)*0、15,ym-abs(ym)*0、15,yy+abs(yy)*0、15]); plot(x(1,:),y(1,:),'ko');
for i=1:n
temp=['v',int2str(i)];
text(x(1,i),y(1,i),temp);
end
for i=1:nE
plot(x(1,e(i,:)),y(1,e(i,:)),'b');
end
for i=1:length(P(:,4))
plot(x(1,Pp(i,1:2)),y(1,Pp(i,1:2)),'r');
end
text(-0、35,-1、2,['最小生成树的权为','',num2str(Wt)]);
title('红色连线为最小生成树');
axis off;
hold off;
调用此程序要先编写主程序。
例:
n=6;
W=inf*ones(6);
W(1,[2,3,4])=[6,1,5];
W(2,[3,5])=[5,3];
W(3,[4,5,6])=[5,6,4];
W(4,6)=2;
W(5,6)=6;
[a,b]=mintree(n,W)
命名为example
在窗口中运行此程序得:
e2(v1v3)
e9(v4v6)
e6(v2v5)
e8(v1v4)
e3(v2v1)
a =
15
b =
1 3 1 2
4 6 2 9
2 5
3 6
3 6
4 8
2 3 5 3。