def sync(self, pk, payload): """Update hg and return new event ids in topological order.""" info = crypto_sign(dumps({c: self.height[h] for c, h in self.can_see[self.head].items()}), self.sk) msg = crypto_sign_open(self.network[pk](self.pk, info), pk) remote_head, remote_hg = loads(msg) new = tuple(toposort(remote_hg.keys() - self.hg.keys(), lambda u: remote_hg[u].p)) for h in new: ev = remote_hg[h] if self.is_valid_event(h, ev): self.add_event(h, ev) if self.is_valid_event(remote_head, remote_hg[remote_head]): h, ev = self.new_event(payload, (self.head, remote_head)) # this really shouldn't fail, let's check it to be sure assert self.is_valid_event(h, ev) self.add_event(h, ev) self.head = h return new + (h,)
def longest_path_in_dag(g: AdjList, w: EdgeWeight, start: Hashable, goal: Hashable) -> Tuple[int, Path]: """ >>> g = {0: [1, 2], 1: [4], 2: [3], 3: [4]} >>> w = {(0, 1): 7, (0, 2): 4, (2, 3): 2, (1, 4): 1, (3, 4): 3} >>> longest_path_in_dag(g, w, 0, 4) (9, [0, 2, 3, 4]) """ g_pred = collections.defaultdict(list) for x, preds in g.items(): for pred in preds: g_pred[pred].append(x) vs = toposort(g) dp = collections.defaultdict(lambda: -1000000) pred = dict() dp[start] = 0 for v in vs: if v == start: continue for v_prev in g_pred.get(v, []): if dp[v] < (newmax := dp[v_prev] + w[v_prev, v]): dp[v] = newmax pred[v] = v_prev