自动控制原理——梅森增益公式
from itertools import combinations from collections import defaultdict class SignalFlowGraph: def __init__(self): self.adj = defaultdict(list) self.nodes = set() def add_edge(self, u, v, gain: float): self.adj[u].append((v, gain)) self.nodes.add(u); self.nodes.add(v) # -------- DFS 找前向路径 -------- def _dfs_paths(self, u, t, visited): if u == t: yield [u] return for v, g in self.adj[u]: if v in visited: continue for suf in self._dfs_paths(v, t, visited | {v}): yield [u] + suf def forward_paths(self, s, t): paths = [] for nodes in self._dfs_paths(s, t, {s}): gain = 1.0 for i in range(len(nodes)-1): u, v = nodes[i], nodes[i+1] # 假设没有并联 for vv, g in self.adj[u]: if vv == v: gain *= g break paths.append((nodes, gain)) return paths # -------- 找所有自洽回路 -------- def _dfs_loops(self, start, node, visited, stack): for v, g in self.adj[node]: if v == start: yield stack + [(v,g)] elif v not in visited: yield from self._dfs_loops(start, v, visited | {v}, stack+[(v,g)]) def all_loops(self): loops = [] for n in self.nodes: for loop in self._dfs_loops(n, n, {n}, []): nodes = [n for n,_ in loop] gain = 1.0 for _, g in loop: gain *= g loops.append((nodes, gain)) return loops def delta(self, excluded_nodes=None): if excluded_nodes is None: excluded_nodes=set() loops = [(set(ns), g) for ns,g in self.all_loops() if set(ns).isdisjoint(excluded_nodes)] total = 1.0 for r in range(1, len(loops)+1): term = 0.0 for combo in combinations(loops, r): used=set(); prod=1.0; ok=True for (ns,g) in combo: if not used.isdisjoint(ns): ok=False; break used |= ns; prod *= g if ok: term += prod total = total - term if r%2==1 else total + term return total def mason_gain(self, s, t): num = 0.0 for nodes, pg in self.forward_paths(s, t): num += pg * self.delta(excluded_nodes=set(nodes)) den = self.delta() return num/den # -------- 例子 -------- if __name__ == "__main__": G = SignalFlowGraph() # 举例: R -> A -> B -> C, 并有自回路 A 和外回路 C->R G.add_edge('R','A',2.0) G.add_edge('A','B',3.0) G.add_edge('B','C',4.0) G.add_edge('A','A',-0.5) # 自回路 G.add_edge('C','R',-0.1) # 外回路 print("传递函数数值结果:", G.mason_gain('R','C'))
作者:追梦°
-------------------------------------------
个性签名:生而为人,就要活的好
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
浙公网安备 33010602011771号