2021“MINIEYE杯”中国大学生算法设计超级联赛(5)Random Walk 2(推式子+矩阵逆+矩阵乘)

Random Walk 2

【2.4】Gauss-Jordan消元法求矩阵的逆
高斯消元求矩阵的逆,伴随单位矩阵一起消元即可。
[ A , I ] → [ I , A − 1 ] [\text A,\text I]\to [\text I,\text A^{-1}] [A,I][I,A1]


在这里插入图片描述
移项变形,后就是个矩阵的逆,为啥赛时不写???草(一种植物)

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll mod=998244353;
const int N=310;
int W[N][N];
ll P[N][N],P0[N][N];
ll I[N][N],A[N][N];
int n;
ll qmi(ll a,ll b)
{
    ll v=1;
    while(b)
    {
        if(b&1) v=v*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return v;
}
void Inv()
{
    for(int c=1,r=1;c<=n;c++)
    {
        int t=r;
        for(int i=c;i<=n;i++)
            if(abs(P[i][c])>abs(P[t][c])) t=i;
        if(P[t][c]==0) continue;
        
        for(int j=1;j<=n;j++) 
        {
            swap(I[t][j],I[r][j]);
            swap(P[t][j],P[r][j]);
        }
        ll inv=qmi(P[r][c],mod-2);
        for(int j=1;j<=n;j++)
        {
            I[r][j]=I[r][j]*inv%mod;
            P[r][j]=P[r][j]*inv%mod;
        }
        for(int i=1;i<=n;i++)
            if(i!=r&&P[i][c]!=0)
            {
                ll v=P[i][c];
                for(int j=1;j<=n;j++)
                {
                    I[i][j]=(I[i][j]-v*I[r][j]%mod+mod)%mod;
                    P[i][j]=(P[i][j]-v*P[r][j]%mod+mod)%mod;
                }
            }
        r++;
    }
    
}
void Mul() // I-1 × P0
{
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) A[i][j]=0;
    
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)   
            for(int k=1;k<=n;k++) 
                A[i][j]=(A[i][j]+I[i][k]*P0[k][j]%mod)%mod;
}
int main()
{
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int Tc=1;
    cin>>Tc;
    while(Tc--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>W[i][j];
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) P[i][j]=P0[i][j]=0,I[i][j]=(i==j);
        
        for(int i=1;i<=n;i++)
        {
            ll tot=0;
            for(int j=1;j<=n;j++) tot+=W[i][j];
            ll inv=qmi(tot,mod-2);
            for(int j=1;j<=n;j++)
            {
                if(i!=j) 
                    P[i][j]=1ll*W[i][j]*inv%mod;
                else 
                    P0[i][j]=1ll*W[i][j]*inv%mod;
            }
            
            for(int j=1;j<=n;j++)
            {
                P[i][j]=mod-P[i][j];
                if(i==j) P[i][j]=1;
            }
        }
        
        Inv();
        Mul();
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cout<<A[i][j]<<" \n"[j==n];
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 好的,我会尽量用通俗易懂的语言来解释链路预测中的Random Walk with Restart算法,并给出具体的代码。 首先,链路预测是指在一张图中,预测两个节点之间是否存在一条边。例如,在社交网络中,我们可以通过链路预测来预测某个人是否与另一个人是朋友关系。 Random Walk with Restart算法是一种基于概率的链路预测算法,其基本思路是在图中随机游走,并不断地重新开始游走,直到找到终点为止。在每次游走过程中,我们都会记录下走过的节点,并计算每个节点被访问的次数。最后,我们可以通过节点被访问的次数来预测两个节点之间是否存在一条边。 下面是使用Python来实现Random Walk with Restart算法的代码: ```python import numpy as np def random_walk_with_restart(G, start_node, end_node, restart_prob=0.5, max_steps=1000): """ G: 输入图 start_node: 起点节点 end_node: 终点节点 restart_prob: 重新开始游走的概率 max_steps: 最大游走步数 """ # 记录访问的节点 visited_nodes = [] # 记录每个节点被访问的次数 node_counts ### 回答2: Random Walk with Restart (RWR) 是一种常用于网络链路预测的方法。RWR方法基于随机游走的思想,通过模拟节点在网络中的随机传播来预测节点之间的关联概率。 具体步骤如下: 1. 构建一个网络图G,节点集为V,边集为E。 2. 初始化一个节点集合S,表示种子节点集合。可以是已有的已知关联节点对。 3. 为每个节点定义一个初始概率向量p,表示每个节点被选择作为种子节点的概率。初始时,S中的节点概率为1,其他节点概率为0。 4. 进行若干次迭代,每次迭代都按照以下步骤计算更新节点的概率: - 对于所有节点v∈V,计算其与S中节点的关联概率:p_new[v] = α * Σ(p[u]/d_out(u)),其中u∈N(v)为节点v的邻居节点,d_out(u)表示节点u的出度。 - 对于所有节点v∈V,更新概率:p[v] = p_new[v] + (1-α) * δ[v],其中δ[v]是节点v是否属于种子节点集合S的指示函数,α为阻尼系数。 5. 根据节点的最终概率向量p,可以计算节点之间的关联概率,例如可以取概率最高的k个节点作为预测的链路。 下面给出一个简单的Python代码示例: ```python import numpy as np import networkx as nx def random_walk_with_restart(G, S, alpha, num_iterations, k): V = G.nodes() p = np.zeros(len(V)) p[list(S)] = 1.0 for _ in range(num_iterations): p_new = np.zeros(len(V)) for v in V: if v in S: p_new[v] = 1.0 else: neighbors = G.neighbors(v) # 获取节点v的邻居节点 for u in neighbors: p_new[v] += p[u] / G.out_degree(u) p = alpha * p_new + (1 - alpha) * p sorted_nodes = np.argsort(p)[::-1] # 根据概率排序 return sorted_nodes[:k] ``` ### 回答3: Random Walk with Restart(RWR)是一种用于链路预测的算法,它通过模拟在网络中随机游走的过程来预测未知的链路。下面是一个使用Python实现RWR算法进行链路预测的代码示例: ```python import numpy as np def random_walk_with_restart(adj_matrix, restart_prob, num_steps): n = adj_matrix.shape[0] # 创建转移概率矩阵 transition_matrix = adj_matrix / np.sum(adj_matrix, axis=1, keepdims=True) # 初始化结果矩阵 result_matrix = np.zeros((n, n)) # 进行多步随机游走 for _ in range(num_steps): result_matrix = (1 - restart_prob) * np.dot(transition_matrix, result_matrix) + restart_prob * adj_matrix return result_matrix def link_prediction(adj_matrix, restart_prob, num_steps): n = adj_matrix.shape[0] # 使用RWR进行链路预测 result_matrix = random_walk_with_restart(adj_matrix, restart_prob, num_steps) # 预测链路存在的概率 link_probability = np.dot(result_matrix, adj_matrix.T) # 获取未知链路的预测结果 link_prediction = link_probability[:n, n:] return link_prediction # 示例数据 adj_matrix = np.array([[0, 1, 0, 1], [1, 0, 1, 1], [0, 1, 0, 0], [1, 1, 0, 0]]) restart_prob = 0.2 num_steps = 10 # 运行链路预测算法 prediction = link_prediction(adj_matrix, restart_prob, num_steps) # 打印预测结果 print("链路预测结果:") for i in range(prediction.shape[1]): for j in range(prediction.shape[0]): if prediction[j, i] > 0.5: print(f"节点 {j} 和节点 {i} 之间有链路存在") ``` 在这个示例代码中,首先定义了一个函数 `random_walk_with_restart`,它用于执行多步随机游走,其中 `adj_matrix` 是邻接矩阵,`restart_prob` 是重启概率,`num_steps` 是游走步数。该函数通过迭代计算转移概率矩阵和结果矩阵来模拟游走的过程。 然后,定义了另一个函数 `link_prediction`,它使用前面的 `random_walk_with_restart` 函数进行链路预测。在函数内部,我们计算了链路存在的概率,并提取了未知链路的预测结果。 最后,我们使用一个示例数据 `adj_matrix` 来运行链路预测算法,并打印出预测的结果。这个示例数据是一个4x4的邻接矩阵,表示了4个节点之间的连接关系。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值