避圈法随机求解出无向完全图的一棵生成树

避圈法得到生成树

% date:202037% Author:Chauncy_xu
clc;
clear all;
%% 避圈法求解最小生成树
G = [0,1,1,1,1;
     1,0,1,1,1;
     1,1,0,1,1;
     1,1,1,0,1;
     1,1,1,1,0];
 [Num,~]=size(G);
%% 准备工作
Tree = zeros(Num);  %生成树,也是用其邻接矩阵表达的
Num_e=((nnz(G))/2);%图的边的数目 
                    %nnz函数可以直接返回矩阵中的非0元素个数
j = 0;%用来控制最小生成树的边的数目
%% 开始
for i=1:Num_e %对所有的边进行遍历
    if j<(Num-1) %算法的终止条件是边数等于定点数-1
    %% 步骤一:选边G(a,b)
        ch=0;
        while ch==0
            a = ceil(rand()*Num); %随机产生顶点a的位置
            b = ceil(rand()*Num); %随机产生顶点b的位置
            if b==a               %进行修正
                if a==1
                    b = 2;
                else
                    b = b-1;
                end
            end
            if Tree(a,b)==0
                ch=1;
            end
        end
     %% 步骤二: T = T + e(a,b)
     Tree(a,b) = 1;
     Tree(b,a) = 1;
     %% 步骤三:检查是否有环出现
     flag = 0; % 标志flag为0表示没有环出现
     P = zeros(2,Num_e);%创建一个两行Num_e列的矩阵
                        %所有元素赋初值为0
     y = 0;
     for i=1:Num
         for v=(i+1:Num)
             if Tree(i,v)~=0
                 y=y+1;
                 P(1,y)=i;
                 P(2,y)=v;
             end
         end
     end
     for y=1:Num_e
         if P(1,y)<P(2,y)
             for k=(y+1):Num_e
                 if P(1,k)==P(2,y)
                     P(1,k)=P(1,y);
                 elseif P(2,k)==P(2,y)
                     P(2,k)=P(1,y);
                 end
             end
             P(2,y)=P(1,y);
         elseif P(2,y)<P(1,y)
             for k=(y+1):Num_e
                 if P(1,k)==P(1,y)
                     P(1,k)=P(2,y);
                 elseif P(2,k)==P(1,y)
                     P(2,k)=P(2,y);
                 end
             end
             P(1,y)=P(2,y);
         elseif (P(1,y)+P(2,y))~=0
             flag =1;%出现一个环
             break;
         end
     end
     if flag==1
         Tree(a,b)=0;
         Tree(b,a)=0;
     else
         j=j+1;
     end
    else %如果条件|E|=|V|-1成立
        Tree %#ok<NOPTS>
        break
    end
end
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用求解带权最小生成的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #define MAXVEX 100 // 中顶点个数的最大值 #define MAXEDGE 100 // 中边数的最大值 typedef struct { int u, v; // 边的两个顶点 int weight; // 边的权重 } Edge; typedef struct { int vex[MAXVEX]; // 顶点集合 Edge edge[MAXEDGE]; // 边集合 int num_vex, num_edge; // 顶点数和边数 } Graph; int find(int *parent, int f) { while (parent[f] > 0) { f = parent[f]; } return f; } void miniSpanTree_Kruskal(Graph G) { int i, n, m; int parent[MAXVEX]; // 用于存储每个节点的父节点 Edge edge[MAXEDGE]; // 用于存储最小生成的边集合 n = G.num_vex; m = G.num_edge; // 将所有边按照权值从小到大排序 for (i = 0; i < m; i++) { edge[i] = G.edge[i]; } for (i = 0; i < n; i++) { parent[i] = 0; } // 依次将每条边加入生成中 for (i = 0; i < m; i++) { int n1 = find(parent, edge[i].u); int n2 = find(parent, edge[i].v); // 如果这条边不会形成环路,则将其加入生成中 if (n1 != n2) { parent[n1] = n2; printf("%d %d %d\n", edge[i].u, edge[i].v, edge[i].weight); } } } int main() { Graph G; int i; scanf("%d %d", &G.num_vex, &G.num_edge); for (i = 0; i < G.num_edge; i++) { scanf("%d %d %d", &G.edge[i].u, &G.edge[i].v, &G.edge[i].weight); } miniSpanTree_Kruskal(G); return 0; } ``` 以上代码中的miniSpanTree_Kruskal函数实现了的主要逻辑,通过find函数来判断每条边是否会形成环路,如果不会,则将其加入生成中。 当然,您也可以根据需要使用破圈来实现求解带权最小生成的算

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值