微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

hasl-hakimi 算法的问题

如何解决hasl-hakimi 算法的问题

我目前正在为类开发一种自定义算法,该算法实现了随机选择节点的 Havel-Hakimi 算法。不幸的是,我遇到了一个难以追踪的逻辑错误(因为我是编程初学者)。如果有人能帮助我发现问题,我将不胜感激。发生的事情是我有时会返回正确的序列,但有时不会

import networkx as nx
import matplotlib.pyplot as plt
import random

def nodes_connected(G,u,v):
    return u in G.neighbors(v)

def hh_graph(seq):
    if not(nx.is_graphical(seq)):
        print("Sequence is not graphical")
    else:
        #Randomly mix the degree sequence
        random.shuffle(seq)
        #Create graph
        G = nx.Graph()
        G.add_nodes_from(range(1,len(seq)+1))
        #Repeat for every node in the sequence
        for i in range(0,len(seq)):
            #j stores number of edges to be added
            j=seq[i]
            #selected node is zeroed
            seq[i]=0
            #Repeat till all edges have been connected
            while j>0:
                k=0
                done=False
                #Repeat till finding a suitable node to connect to
                while k<len(seq) and done==False :
                    #Check to connect to a maximum value node,and avoiding a duplicate connection
                    if seq[k]==max(seq) and nodes_connected(G,i+1,k+1)==False:
                        G.add_edges_from([[i+1,k+1]])
                        seq[k]-=1
                        done=True
                    k+=1
                j-=1
        #Check graph degree sequence to validate results
        degree_sequence = [d for n,d in G.degree()]
        print(f"Graph degree sequence {degree_sequence}")
        #nx.draw_networkx(G)
        #plt.show()

A=[5,4,3,3]
B=[6,2,1,1]
C=[4,1]
hh_graph(A)
hh_graph(B)
hh_graph(C)

我已尝试将重点放在我认为可能存在问题的循环上。我测试了不同的 if 案例和实现,但仍有一半时间无法理解它是如何工作的,而其他时间则不然

提前致谢!

解决方法

Havel-Hakimi 算法要求您在每一步将(当前)最高度节点的边添加到后续最高度节点。为此,您需要在添加每个节点并填充边缘后重新排序列表(至少部分)。您不会选择随机节点(度值)来填充边。

我从您的评论中了解到这是故意的 - 您正在评估 Havel-Hakimi 的变体,其中随机度节点附加到适当的最大剩余度节点。但是,如果相应节点的度数值存在多于 1 的步长,则它们将永远无法通过 seq[k]==max(seq) 测试。在 6,3,2,1,1 的评论示例中,在第一步中选择 3 节点会找到 6,但永远不会找到其他 3

您最好不要像当前那样隐式地使用度数列表位置作为节点 ID;而是让每个条目 [remainingdegree,nodeID] 以便您可以对剩余的度数值进行自由排序。然后你仍然可以从排序列表中随机选择下一个要耗尽的节点,但你会知道去哪里寻找连接它的节点。

然后您可以像这样运行主循环(并且您可以在其中添加“图形”测试):

            G.add_nodes_from(range(1,len(seq)+1))
            # make list of [degree,ID] lists (& sort descending)
            nodeRecs = sorted(([d,i+1] for i,d in enumerate(seq)),reverse=True)
            # Add edges to random node choices until highest degree is zero
            while nodeRecs[0][0] > 0:
                # remove exhausted nodes
                while (nodeRecs[-1][0] == 0):
                    nodeRecs.pop()
                # choose new active node
                addRec = random.choice(nodeRecs)
                # link to high-degree nodes
                for toRec in nodeRecs:
                    if toRec[1] != addRec[1]:
                        G.add_edges_from([[addRec[1],toRec[1]]])
                        toRec[0] -= 1
                        addRec[0] -= 1
                        if addRec[0] == 0: 
                            break
                # Put nodes back into descending degree order
                nodeRecs.sort(reverse=True)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。