Python:参考Swendsen-Wang Sampling构建超图

这里的python部分:

利用knn获取k=5时,所有的边和边edges的权重costs 

import numpy as np
from itertools import permutations,combinations
from sklearn.datasets import load_iris
from scipy.spatial.distance import pdist,squareform
import matlab
import matlab.engine
X,y = load_iris(return_X_y=True)
engine = matlab.engine.start_matlab()
N = len(y)
neiNum = 5

dist_list = pdist(X,metric='euclidean')
dist_matrix = squareform(dist_list)
nn_matrix = np.zeros((N,5))
nn_list = []
nn_cost = []
for i in range(N):
    ord_idx = np.argsort(dist_matrix[i])
    neibor = []
    for j in range(neiNum+1):
        if i != ord_idx[j]:
            neibor.append(ord_idx[j])
    neibor = np.array(neibor)
    nn_matrix[i] = neibor

for i in range(N-1):
    for j in range(i,N):
        if i in nn_matrix[j] or j in nn_matrix[i]:
            nn_list.append([i,j])
            nn_cost.append(dist_matrix[i,j])

print(len(nn_list))
print(len(nn_cost))
print(len(nn_matrix))
for i in range(len(nn_list)):
    nn_list[i][0] += 1
    nn_list[i][1] += 1

nn_list = np.array(nn_list)
nn_cost = np.array(nn_cost)
nn_cost = np.vstack(nn_cost)

e = matlab.double(nn_list.tolist())
cost = matlab.double(nn_cost.tolist())
hyperGraph = engine.sws(e,cost,N)

hyperGraph = np.array(hyperGraph)
hyperGraph = hyperGraph.T
print(hyperGraph.shape)
print(hyperGraph)

接下来是:调用Pulak Purkait写的Swendsen-Wang Sampling的matlab代码


% function inds  = sws(e, cost, f, OPTIONS)
function inds  = sws(e, cost, N)


% Follows Swendsen-Wang cut of Barbu and Zhu.
%-------
% Input:
%-------
% e (|E|x2)     : Edges.
% cost (|E|x1)  : Edge costs. 
% f (|V|x1)     : label of the vertices
% OPTIONS       : Options for rcm sampling 

%--------
% Output:
%--------
% inds          : Sampled hyperedges 

% No_Edge = OPTIONS.c; 
% n = OPTIONS.n-1;            % Its a dense hypergrapgh, model is evaluated rest of the points
% lambda = OPTIONS.lambda; 

No_Edge = 200;
n = 5;
lambda = 3;

N = double(N)

% N = length(f);
f = ones(N,1);

csts = cost.^2; 
mn_csts = mean(csts); 
q = exp(-csts./(lambda^2*mn_csts)); % Edge probabilities.


% Sample the connected component.
% Edges that remain 'on' due to same labels.
eon_det = f(e(:,1))==f(e(:,2));
inds = zeros(n, No_Edge);

k = 1;

while (k <= No_Edge)
    % Edges that are turned 'on' stochastically.
    eon_sto = rand(length(q),1)<=q;

    % Either the edge is already 'off' due to different labels, or
    % the edge is turned 'off' stochastically.
    eon = logical(eon_det.*eon_sto);

    % Get current set of connected components.
    Eon = sparse(e(eon,1),e(eon,2),ones(sum(eon),1),N,N);
    Eon = Eon + Eon';   % Make it symmetric.
    [S,C] = graphconncomp(Eon);

    % Pick a connected component R probabilistically.
    q2 = q(eon); 
    w = ones(1,S);
    for s=1:S
        id = find(C==s); 
        if numel(id) < n % Remove small clusters having less than 8 points
            w(s) = 1e-1000;
        else
            [X, Y] = meshgrid(id, id); 
            [vl, idb, idc] = intersect(e(eon, :), [X(:), Y(:)], 'rows'); 
            w(s) = sum(q2(idb))/(numel(idb)); 
    %         w(s) = sum(q(idb))/(numel(id)*nn);
        end
    end
    
    if sum(w) < eps
        continue;
    end
    
    
    for i=1:sum(w>0)
        if k > No_Edge
            return; 
        end
        R = randsample(S,1,true,w);
        % indices of points in cluster k and its size
        inds_k = find(C == R);
        rsmpl = randsample(inds_k, n)';
        flag = 1;
        for kk =1:k-1
            id = double(inds(:, kk) == rsmpl); 
            if sum(id) == n
                flag = 0;
            end
        end
        if flag
            inds(:,k) = rsmpl; 
            k = k+1; 
        end
    end
end

有时间了在用python实现sws

Python 实现超图涉及到一些复杂的数据结构操作以及算法设计,主要步骤可以分为以下几个部分: ### 1. 理解超图的概念 超图(Hypergraph)是一种比标准图更复杂的数学模型,其中边(Edge)可以连接任意数量的顶点(Vertex),而不只是两个。在普通图中,每条边最多只能连接两个顶点;而在超图中,一条边可以连接三个、四个甚至更多的顶点。 ### 2. 数据结构设计 为了在Python中表示超图,我们需要设计一种数据结构来存储顶点和边的信息。可以采用字典或列表作为基本容器。例如: #### 使用字典表示: ```python class Hyperedge: def __init__(self, vertices): self.vertices = frozenset(vertices) # 使用frozenset来保证哈希性和不可变性 class Hypergraph: def __init__(self): self.edges = {} # 添加超边 def add_hyperedge(hypergraph, hyperedge_vertices): hyperedge = Hyperedge(hyperedge_vertices) if hyperedge not in hypergraph.edges: hypergraph.edges[hyperedge] = set() # 初始化对应的顶点集合为空集 # 添加顶点到指定的超边 def add_vertex_to_hyperedge(hypergraph, vertex, hyperedge_vertices): hyperedge = Hyperedge(hyperedge_vertices) if hyperedge in hypergraph.edges: hypergraph.edges[hyperedge].add(vertex) # 检查顶点是否属于某个超边 def is_in_hyperedge(hypergraph, vertex, hyperedge_vertices): return vertex in hyperedge and hyperedge in hypergraph.edges ``` #### 使用列表表示: ```python class Hyperedge: def __init__(self, vertices): self.vertices = list(vertices) class Hypergraph: def __init__(self): self.edges = [] def add_hyperedge(self, hyperedge_vertices): self.edges.append(Hyperedge(hyperedge_vertices)) def add_vertex_to_hyperedge(self, vertex, edge_index): if 0 <= edge_index < len(self.edges): self.edges[edge_index].vertices.append(vertex) def is_in_hyperedge(self, vertex, edge_index): if 0 <= edge_index < len(self.edges): return vertex in self.edges[edge_index].vertices ``` ### 3. 超图的遍历与查询 实现上述结构之后,你可以对超图进行遍历和查询操作。这包括查找特定顶点出现在哪些超边中、查找包含特定集合的顶点的所有超边等。 ### 相关问题: 1. **如何优化超图数据结构以提高效率?** - 可以考虑将顶点和超边转换成键值对的形式,并利用高效的哈希表来存储以加速查询过程。 2. **在实际应用中,超图可以用于解决什么样的问题?** - 超图适用于各种复杂关系网络分析,如社会网络分析、生物信息学、资源分配问题等场景。 3. **Python 中有没有现成的库支持超图构建与操作?** - 目前 Python 并没有提供专门针对超图的现成库,需要自定义实现。但在某些领域相关的库可能会提供类似功能,如 NetworkX 库虽然主要处理简单图,但在一定程度上也可以用于探索复杂关系的初步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeniuHe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值