r"""Double Radius Node Labeling, as introduced in `Link Prediction Based on Graph Neural Networks `__. This function computes the double radius node labeling for each node to mark nodes' different roles in an enclosing subgraph, given a target link.
(g, src, dst)
| 3799 | |
| 3800 | |
| 3801 | def double_radius_node_labeling(g, src, dst): |
| 3802 | r"""Double Radius Node Labeling, as introduced in `Link Prediction |
| 3803 | Based on Graph Neural Networks <https://arxiv.org/abs/1802.09691>`__. |
| 3804 | |
| 3805 | This function computes the double radius node labeling for each node to mark |
| 3806 | nodes' different roles in an enclosing subgraph, given a target link. |
| 3807 | |
| 3808 | The node labels of source :math:`s` and destination :math:`t` are set to 1 and |
| 3809 | those of unreachable nodes from source or destination are set to 0. The labels |
| 3810 | of other nodes :math:`l` are defined according to the following hash function: |
| 3811 | |
| 3812 | :math:`l = 1 + min(d_s, d_t) + (d//2)[(d//2) + (d%2) - 1]` |
| 3813 | |
| 3814 | where :math:`d_s` and :math:`d_t` denote the shortest distance to the source and |
| 3815 | the target, respectively. :math:`d = d_s + d_t`. |
| 3816 | |
| 3817 | Parameters |
| 3818 | ---------- |
| 3819 | g : DGLGraph |
| 3820 | The input graph. |
| 3821 | src : int |
| 3822 | The source node ID of the target link. |
| 3823 | dst : int |
| 3824 | The destination node ID of the target link. |
| 3825 | |
| 3826 | Returns |
| 3827 | ------- |
| 3828 | Tensor |
| 3829 | Labels of all nodes. The tensor is of shape :math:`(N,)`, where |
| 3830 | :math:`N` is the number of nodes in the input graph. |
| 3831 | |
| 3832 | Example |
| 3833 | ------- |
| 3834 | >>> import dgl |
| 3835 | |
| 3836 | >>> g = dgl.graph(([0,0,0,0,1,1,2,4], [1,2,3,6,3,4,4,5])) |
| 3837 | >>> dgl.double_radius_node_labeling(g, 0, 1) |
| 3838 | tensor([1, 1, 3, 2, 3, 7, 0]) |
| 3839 | """ |
| 3840 | adj = g.adj_external(scipy_fmt="csr") |
| 3841 | src, dst = (dst, src) if src > dst else (src, dst) |
| 3842 | |
| 3843 | idx = list(range(src)) + list(range(src + 1, adj.shape[0])) |
| 3844 | adj_wo_src = adj[idx, :][:, idx] |
| 3845 | |
| 3846 | idx = list(range(dst)) + list(range(dst + 1, adj.shape[0])) |
| 3847 | adj_wo_dst = adj[idx, :][:, idx] |
| 3848 | |
| 3849 | # distance to the source node |
| 3850 | ds = sparse.csgraph.shortest_path( |
| 3851 | adj_wo_dst, directed=False, unweighted=True, indices=src |
| 3852 | ) |
| 3853 | ds = np.insert(ds, dst, 0, axis=0) |
| 3854 | # distance to the destination node |
| 3855 | dt = sparse.csgraph.shortest_path( |
| 3856 | adj_wo_src, directed=False, unweighted=True, indices=dst - 1 |
| 3857 | ) |
| 3858 | dt = np.insert(dt, src, 0, axis=0) |
nothing calls this directly
no test coverage detected