(self)
| 100 | ) |
| 101 | |
| 102 | def process(self): |
| 103 | g = nx.barabasi_albert_graph( |
| 104 | self.num_base_nodes, self.num_base_edges_per_node, self.seed |
| 105 | ) |
| 106 | edges = list(g.edges()) |
| 107 | src, dst = map(list, zip(*edges)) |
| 108 | n = self.num_base_nodes |
| 109 | |
| 110 | # Nodes in the base BA graph belong to class 0 |
| 111 | node_labels = [0] * n |
| 112 | # The motifs will be evenly attached to the nodes in the base graph. |
| 113 | spacing = math.floor(n / self.num_motifs) |
| 114 | |
| 115 | for motif_id in range(self.num_motifs): |
| 116 | # Construct a five-node house-structured network motif |
| 117 | motif_edges = [ |
| 118 | (n, n + 1), |
| 119 | (n + 1, n + 2), |
| 120 | (n + 2, n + 3), |
| 121 | (n + 3, n), |
| 122 | (n + 4, n), |
| 123 | (n + 4, n + 1), |
| 124 | ] |
| 125 | motif_src, motif_dst = map(list, zip(*motif_edges)) |
| 126 | src.extend(motif_src) |
| 127 | dst.extend(motif_dst) |
| 128 | |
| 129 | # Nodes at the middle of a house belong to class 1 |
| 130 | # Nodes at the bottom of a house belong to class 2 |
| 131 | # Nodes at the top of a house belong to class 3 |
| 132 | node_labels.extend([1, 1, 2, 2, 3]) |
| 133 | |
| 134 | # Attach the motif to the base BA graph |
| 135 | src.append(n) |
| 136 | dst.append(int(motif_id * spacing)) |
| 137 | n += 5 |
| 138 | |
| 139 | g = graph((src, dst), num_nodes=n) |
| 140 | |
| 141 | # Perturb the graph by adding non-self-loop random edges |
| 142 | num_real_edges = g.num_edges() |
| 143 | max_ratio = (n * (n - 1) - num_real_edges) / num_real_edges |
| 144 | assert ( |
| 145 | self.perturb_ratio <= max_ratio |
| 146 | ), "perturb_ratio cannot exceed {:.4f}".format(max_ratio) |
| 147 | num_random_edges = int(num_real_edges * self.perturb_ratio) |
| 148 | |
| 149 | if self.seed is not None: |
| 150 | np.random.seed(self.seed) |
| 151 | for _ in range(num_random_edges): |
| 152 | while True: |
| 153 | u = np.random.randint(0, n) |
| 154 | v = np.random.randint(0, n) |
| 155 | if (not g.has_edges_between(u, v)) and (u != v): |
| 156 | break |
| 157 | g.add_edges(u, v) |
| 158 | |
| 159 | g.ndata["label"] = F.tensor(node_labels, F.int64) |
nothing calls this directly
no test coverage detected