首页 > 编程语言 >Kruscal 算法:按边搜索,整体扫描,一词入选

Kruscal 算法:按边搜索,整体扫描,一词入选

时间:2023-10-18 09:48:46浏览次数:25  
标签:按边 tmp set existed graph min 算法 Kruscal subset

首先是该算法 Intuitive 参考:

https://www.geeksforgeeks.org/kruskals-minimum-spanning-tree-algorithm-greedy-algo-2/

 

数据结构采用的是 Activity on Edge:

 

1. 图的数据输入

# -------------
# -- Kruscal
# -------------

import numpy as np
import pandas as pd


source = [4,1,1,2,2,5,5,7,7,6,6,4]
destiny = [1,2,3,4,5,4,7,4,6,4,3,3]
weight = [1,2,4,3,10,7,6,4,1,8,5,2]

# -- 这个是错误解答: PRIM 用 AOV 试试
tmp_graph = pd.DataFrame()
tmp_graph['source'] = source
tmp_graph['destiny'] = destiny
tmp_graph['weight'] = weight
tmp_graph['num'] = tmp_graph.index
tmp_graph['tag'] = 0

 

2.准备所有函数:SWAP值、找出最小的边、判断顶点是否被选入

# -------------
# -- Kruscal
# -------------

# -- SWAP
def swap_val(a, b):
    tmp = a; a = b; b = tmp;
    return a,b

# -- Minimum - return num
def find_min_weight(g_in):
    # -- renew
    tmp_g = g_in.reset_index(drop=True)
    tmp_min = tmp_g['weight'][0]
    tmp_min_ind = tmp_g['num'][0]
    
    for i in range(1,len(tmp_g)):
        if (tmp_g['weight'][i] < tmp_min):
            tmp_min = tmp_g['weight'][i] 
            tmp_min_ind = tmp_g['num'][i]
    
    return tmp_min, tmp_min_ind

# --- Minimum Edge 
# --- Min Vertex Id when same weighted edge
def find_min_edge(g_in):
    tmp_g = g_in.reset_index(drop=True)
    tmp_min_edge=-1; tmp_edge=-1
    tmp_min_edge_id=-1; tmp_edge_id=-1
    
    for i in range(len(g_in)):
        if i==0:
            tmp_min_edge=int(g_in['weight'][i])
            tmp_min_edge_id=int(g_in['num'][i])
        else:
            tmp_edge=int( g_in['weight'][i] )
            tmp_edge_id=int(g_in['num'][i])
            
            if tmp_edge <tmp_min_edge:
                tmp_min_edge, tmp_edge = swap_val(tmp_min_edge, tmp_edge)
                tmp_min_edge_id = tmp_edge_id
                
        #print(tmp_min_edge, tmp_edge, tmp_min_edge_id, tmp_edge_id)
    return tmp_min_edge_id
    
# --- is_vertex_existed
# -- id in bool out
def is_vertex_existed(v_id_in, v_vec_in):
    is_existed=0
    pos_existed=-1
    for i in range(len(v_vec_in)):
        if v_id_in == v_vec_in[i]:
            is_existed=1
            pos_existed=i
            break
            
    return is_existed, pos_existed
     
# ------ 获取节点向量
tmp_vertex = list(tmp_graph['source']) + list(tmp_graph['destiny'])
tmp_vertex = list(set(tmp_vertex))
print(tmp_vertex)

tmp_graph

 

3. 循环,完成 Kruscal 算法。注意,这里处理的问题包含,连通集问题、回路问题,由于算法本身限制,回路在不属于主要问题,可以由解决连通问题一并解决。

其实,可以解决连通、回路的是并查集,这里为了方便起见,直接用分子集 + TAG 方式解决。

len_remain = len(tmp_graph[tmp_graph.tag==0])  # 未被选入的点
len_mar = len(tmp_graph)
cnt=0

selected_set = pd.DataFrame()
vertex_set=[]
v_subset_1=[]
v_subset_2=[]
is_link_subset=0  # Kruscal 算法,最后一个点加进去之前,已经选入的集合只有两种情况:连通 / 不连通

while(len_remain>0 and cnt>-1 ):
    
    tmp_g_1 = tmp_graph[tmp_graph.tag==0].reset_index(drop=True)

    tmp_id = find_min_edge(tmp_g_1)
    tmp_graph['tag'][tmp_id]=1
    
    tmp_g_2=tmp_graph[tmp_graph.num==tmp_id].reset_index(drop=True)

    dot_1=int(tmp_g_2['source'][0]); 
    dot_2=int(tmp_g_2['destiny'][0]);
    is_existed_1, _ = is_vertex_existed(dot_1, vertex_set)
    is_existed_2, _ = is_vertex_existed(dot_2, vertex_set) 
    
      # --- SUBSET
    is_existed_1_1, _ = is_vertex_existed(dot_1, v_subset_1)
    is_existed_1_2, _ = is_vertex_existed(dot_1, v_subset_2)
    is_existed_2_1, _ = is_vertex_existed(dot_2, v_subset_1)
    is_existed_2_2, _ = is_vertex_existed(dot_2, v_subset_2)  
    subset_tag = 10000 + is_existed_1_1*1000 + is_existed_1_2*100 + is_existed_2_1*10 + is_existed_2_2*1  

    if (is_existed_1==0 or is_existed_2==0):
        if cnt==0:
            selected_set = tmp_g_2
        else:
            selected_set = pd.concat([selected_set, tmp_g_2])
            
        if is_existed_1==0:
            vertex_set.append(dot_1)   
        if is_existed_2==0:
            vertex_set.append(dot_2)               
    else:
          # --- 连接连通集
        if ( (subset_tag == 11001 or subset_tag== 10110) and is_link_subset==0 ):
            is_link_subset=1
            selected_set = pd.concat([selected_set, tmp_g_2])

      # --- subset ---
    if is_existed_1==0 and is_existed_2==0 and cnt>0:
        v_subset_2.append(dot_1)
        v_subset_2.append(dot_2)
    else: 
        if is_existed_1==0:
            v_subset_1.append(dot_1)    
        if is_existed_2==0:
            v_subset_1.append(dot_2)    
                   
    cnt=cnt+1
    len_remain=len(tmp_graph[tmp_graph.tag==0])
    
# --- END: 这种算法一定会少一条边 ---
selected_set = selected_set.reset_index(drop=True)    
selected_set

 

算法筛选结果:

 

算法视觉呈现:

 

 

Prim 算法的解释:

Prim 算法的代码与解释https://www.cnblogs.com/shoelesscai/articles/17765067.html

标签:按边,tmp,set,existed,graph,min,算法,Kruscal,subset
From: https://www.cnblogs.com/shoelesscai/p/17771310.html

相关文章

  • 【算法】万圣节前夕的迷宫挑战
    这一天阳光和煦,小悦将捣蛋的侄子小明送回家后,紧绷的神经终于得以放松。在过去的一周里,小悦以无比的耐心和细心照顾着小明,同时也不忘在编程的道路上引领他迈出第一步。万圣节前夕的一天,书房中的陈设在阳光下显得庄重而温暖,小悦正专心致志地处理着手头的工作。突然,一封邮件如不速之......
  • 2算法
    算法定义:算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。算法的特性:输入、输出:算法具有零个或多个输入。算法至少有一个或多个输出。有穷性:指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的......
  • 离岗睡岗算法除了设置时间之外还需要设置哪些参数-智慧矿山ai算法系列
    在智慧矿山的发展中,离岗睡岗算法已经成为提高矿山安全性和生产效率的重要工具。离岗睡岗算法是一种通过自动识别矿工离岗或睡岗的行为,及时作出报警并采取措施的智能化系统。除了设置时间外,还有其他参数也需要设置。首先,需要设置离岗或睡岗的行为判定规则。这涉及到传感器的选择和配......
  • 文心一言 VS 讯飞星火 VS chatgpt (115)-- 算法导论10.2 8题
    八、用go语言,说明如何在每个元素仅使用一个指针x.np(而不是通常的两个指针next和prev)的下实现双向链表。假设所有指针的值都可视为k位的整型数,且定义x.np=x.nextXORx.prev,即x.nert和x.prev的k位异或。(NIL的值用0表示。)注意要说明获表头所需的信息,并说明如何在该表上......
  • 算法
    算法定义:算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。算法的特性:输入、输出:算法具有零个或多个输入。算法至少有一个或多个输出。有穷性:指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的......
  • 排序算法稳定性分类
    稳定排序算法是指在排序过程中能够保持相等元素的相对顺序不变的排序算法。以下是一些常见的稳定排序算法:1.冒泡排序(BubbleSort)2.插入排序(InsertionSort)3.归并排序(MergeSort)4.计数排序(CountingSort)5.基数排序(RadixSort)6.桶排序(BucketSort)而不稳定排序算法是指在排序过......
  • TensorFlow深度学习——深入理解人工智能算法设计pdf电子版 龙良曲
    TensorFlow深度学习——深入理解人工智能算法设计pdf电子版作者:龙良曲出版年:2020-7-1ISBN:9787302553335连接提取码:poat挺系统的,原理加代码的结合,是我最喜欢的阅读方式,前面对tensorflow的使用算相当细致了,后面实践部分内容广,但是部分内容深浅不一,还得自己找别的资......
  • 克鲁斯卡尔(Kruskal )算法——求最小生成树贪心算法
    克鲁斯卡尔算法是一种用于求解最小生成树问题的贪心算法。最小生成树是一个连通图的生成树,其边的权重之和最小。一、原理克鲁斯卡尔算法的核心思想是按照边的权重从小到大逐渐选择连通图的边,直到所有顶点都被连接为止。在每一步中,选择当前权重最小的边,若该边的两个顶点尚未连接,则......
  • 人工智能算法图解 pdf电子版 2022年
    人工智能算法图解pdf电子版2022年作者:[南非]里沙尔·赫班斯(RishalHurbans)著出版年:2022-1ISBN:9787302594239下栽连接较新的书,看完此书才发现,AI算法并没有想象中的复杂,而是充满趣味性,尤其是蚁群优化算法、粒子群优化算法,原来许多算法都是受大自然的启发而得来的。......
  • TensorFlow全栈开发工程实践——做一个全智全能算法工程师 pdf电子版2023 王艳铭
    TensorFlow全栈开发工程实践——做一个全智全能算法工程师pdf电子版王艳铭出版年: 2023-6ISBN: 9787522615950下栽连接《TensorFlow全栈开发工程实践——做一个全智全能算法工程师》这本书最大的特点就是通俗易懂,全面、详细和实用。与同类书籍的就某一分支流水账式详述、不能突......