liurenchaxin/engines/celestial_map.py

162 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# celestial_map.py
import networkx as nx
import matplotlib.pyplot as plt
class CelestialMap:
"""
基于“差序格局”思想,构建一个描绘产业链上下游“引力关系”的图模型。
“差序格局”是中国社会学家费孝通提出的概念,指社会关系像水波纹一样,
由自己这个中心推出去,一层层地变淡。
在这个模型中:
- 恒星 (Star): 代表产业链的核心或最上游的公司/板块,是引力中心。
- 行星 (Planet): 代表与核心紧密相关的公司/板块,围绕恒星运转。
- 卫星 (Satellite): 代表更下游或关联度更弱的公司/板块,围绕行星运转。
引力 (Gravity): 代表实体间的影响力或情绪传导强度,距离越远,引力越弱。
"""
def __init__(self):
self.graph = nx.DiGraph()
def add_entity(self, name, entity_type, **kwargs):
"""
添加一个天体实体。
:param name: 实体名称 (e.g., 'NVIDIA')
:param entity_type: 实体类型 ('star', 'planet', 'satellite')
:param kwargs: 其他属性 (e.g., market_cap, sector)
"""
self.graph.add_node(name, entity_type=entity_type, **kwargs)
def establish_influence(self, source, target, gravity_strength=1.0, relationship_type='supply_chain'):
"""
在两个实体间建立影响关系(引力)。
差序格局的体现:引力强度(gravity_strength)默认为1.0
当从恒星 -> 行星 -> 卫星传递时,可以通过计算路径权重来体现引力的衰减。
:param source: 施加影响的实体名称
:param target: 受到影响的实体名称
:param gravity_strength: 基础引力强度 (1.0 / 距离)
:param relationship_type: 关系类型 (e.g., 'supply_chain', 'competitor', 'capital')
"""
if source not in self.graph:
raise ValueError(f"Source entity '{source}' not found in the map.")
if target not in self.graph:
raise ValueError(f"Target entity '{target}' not found in the map.")
# 使用 1/gravity_strength 作为边的权重,模拟距离
# 强引力 = 低权重 = 短距离
distance = 1.0 / gravity_strength
self.graph.add_edge(source, target, weight=distance, relationship=relationship_type)
def get_influence_path(self, start_node, end_node):
"""
计算两个实体间的最短(最强)影响路径。
:param start_node: 路径起点
:param end_node: 路径终点
:return: 路径节点列表和总路径长度(总距离)
"""
try:
path = nx.shortest_path(self.graph, source=start_node, target=end_node, weight='weight')
length = nx.shortest_path_length(self.graph, source=start_node, target=end_node, weight='weight')
return path, length
except nx.NetworkXNoPath:
return None, float('inf')
def get_downstream_entities(self, start_node, max_depth=None):
"""
获取一个实体的所有下游受影响实体。
:param start_node: 起点实体
:param max_depth: 搜索的最大深度(层级)
:return: 下游实体列表
"""
if start_node not in self.graph:
return []
return list(nx.dfs_preorder_nodes(self.graph, source=start_node, depth_limit=max_depth))
def visualize(self, layout='spring'):
"""
将星图可视化。
"""
pos = None
if layout == 'spring':
pos = nx.spring_layout(self.graph, k=0.9)
elif layout == 'kamada_kawai':
pos = nx.kamada_kawai_layout(self.graph)
elif layout == 'circular':
pos = nx.circular_layout(self.graph)
else:
pos = nx.spring_layout(self.graph)
node_colors = []
for node in self.graph.nodes(data=True):
if node[1]['entity_type'] == 'star':
node_colors.append('yellow')
elif node[1]['entity_type'] == 'planet':
node_colors.append('skyblue')
elif node[1]['entity_type'] == 'satellite':
node_colors.append('lightgreen')
else:
node_colors.append('gray')
edge_labels = nx.get_edge_attributes(self.graph, 'relationship')
plt.figure(figsize=(14, 10))
nx.draw(self.graph, pos, with_labels=True, node_size=3000, node_color=node_colors, font_size=10, font_weight='bold', arrowsize=20)
nx.draw_networkx_edge_labels(self.graph, pos, edge_labels=edge_labels, font_color='red')
plt.title("Celestial Map of Industry Influence (差序格局)")
plt.show()
if __name__ == '__main__':
# --- 示例构建一个AI芯片产业链的“差序格局”图 ---
# 1. 初始化星图
industry_map = CelestialMap()
# 2. 添加实体 (恒星、行星、卫星)
industry_map.add_entity('NVIDIA', 'star', sector='Semiconductors')
industry_map.add_entity('TSMC', 'planet', sector='Manufacturing')
industry_map.add_entity('ASML', 'planet', sector='Equipment')
industry_map.add_entity('Supermicro', 'planet', sector='Servers')
industry_map.add_entity('Apple', 'satellite', sector='Consumer Electronics')
industry_map.add_entity('Tesla', 'satellite', sector='Automotive')
industry_map.add_entity('OpenAI', 'satellite', sector='AI Research')
# 3. 建立影响关系 (引力)
# 恒星 -> 行星 (强引力)
industry_map.establish_influence('NVIDIA', 'TSMC', gravity_strength=0.9, relationship_type='chip_design')
industry_map.establish_influence('NVIDIA', 'Supermicro', gravity_strength=0.8, relationship_type='hardware_demand')
industry_map.establish_influence('ASML', 'TSMC', gravity_strength=0.9, relationship_type='euv_machines')
# 行星 -> 卫星 (中等引力)
industry_map.establish_influence('TSMC', 'Apple', gravity_strength=0.7, relationship_type='chip_supply')
industry_map.establish_influence('Supermicro', 'OpenAI', gravity_strength=0.6, relationship_type='server_supply')
industry_map.establish_influence('NVIDIA', 'Tesla', gravity_strength=0.5, relationship_type='ai_chip_supply') # 直接影响
# 4. 分析与查询
print("--- 情绪传导路径分析 ---")
path, total_distance = industry_map.get_influence_path('ASML', 'Apple')
if path:
print(f"'ASML''Apple' 的最强影响路径: {' -> '.join(path)}")
# 总距离越大,代表关系越疏远,影响力衰减越多
print(f"总影响距离 (1/gravity): {total_distance:.2f}")
path, total_distance = industry_map.get_influence_path('NVIDIA', 'OpenAI')
if path:
print(f"'NVIDIA''OpenAI' 的最强影响路径: {' -> '.join(path)}")
print(f"总影响距离 (1/gravity): {total_distance:.2f}")
print("\n--- 下游影响范围查询 ---")
downstream = industry_map.get_downstream_entities('NVIDIA', max_depth=2)
print(f"'NVIDIA' 在两层关系内的所有下游影响实体: {downstream}")
# 5. 可视化
industry_map.visualize(layout='kamada_kawai')