如何使用Apache AGE生成带随机值的节点与边?
生成带随机值的节点与边(PostgreSQL实现)
1. 创建并填充随机节点表
首先创建节点表,包含主键、自定义随机属性,再用generate_series和random()批量生成节点:
-- 创建节点表结构 CREATE TABLE nodes ( node_id SERIAL PRIMARY KEY, node_name VARCHAR(50) NOT NULL, random_score NUMERIC(10,2) NOT NULL ); -- 插入100个带随机值的节点 INSERT INTO nodes (node_name, random_score) SELECT 'node_' || gs, -- 生成唯一标识名称 ROUND((random() * 1000)::NUMERIC, 2) -- 生成0-1000的随机数值,保留两位小数 FROM generate_series(1, 100) gs;
如果需要更随机的节点名称,也可以用哈希值生成:
-- 用MD5哈希生成随机字符串节点名 INSERT INTO nodes (node_name, random_score) SELECT substring(md5(random()::TEXT) FROM 1 FOR 8), -- 取哈希前8位作为名称 ROUND((random() * 1000)::NUMERIC, 2) FROM generate_series(1, 100);
2. 创建并生成随机边表
边表需要关联节点主键,可根据需求生成有向/无向边,同时避免自环或重复边:
无向边(无自环、无重复)
-- 创建无向边表,添加唯一约束避免重复边 CREATE TABLE edges ( edge_id SERIAL PRIMARY KEY, start_node INT REFERENCES nodes(node_id), end_node INT REFERENCES nodes(node_id), edge_weight NUMERIC(5,2) NOT NULL, UNIQUE (LEAST(start_node, end_node), GREATEST(start_node, end_node)) ); -- 插入200条有效无向边 INSERT INTO edges (start_node, end_node, edge_weight) SELECT floor(random() * 100) + 1 AS start_node, -- 随机选取1-100的节点ID floor(random() * 100) + 1 AS end_node, ROUND((random() * 100)::NUMERIC, 2) AS edge_weight FROM generate_series(1, 300) -- 多生成候选数据,过滤后取有效条目 WHERE start_node != end_node ON CONFLICT (LEAST(start_node, end_node), GREATEST(start_node, end_node)) DO NOTHING -- 跳过重复边 LIMIT 200;
有向边(无自环,允许同方向重复)
-- 创建有向边表 CREATE TABLE directed_edges ( edge_id SERIAL PRIMARY KEY, from_node INT REFERENCES nodes(node_id), to_node INT REFERENCES nodes(node_id), edge_weight NUMERIC(5,2) NOT NULL ); -- 插入200条有向边 INSERT INTO directed_edges (from_node, to_node, edge_weight) SELECT floor(random() * 100) + 1 AS from_node, floor(random() * 100) + 1 AS to_node, ROUND((random() * 100)::NUMERIC, 2) AS edge_weight FROM generate_series(1, 200) WHERE from_node != to_node;
3. 进阶:自定义随机分布
如果需要更贴近真实场景的随机值,比如边权重服从正态分布,可以用Box-Muller变换实现:
-- 生成均值为50、标准差为10的正态分布边权重 INSERT INTO edges (start_node, end_node, edge_weight) SELECT floor(random() * 100) + 1 AS start_node, floor(random() * 100) + 1 AS end_node, ROUND((50 + 10 * sqrt(-2 * ln(random())) * cos(2 * pi() * random()))::NUMERIC, 2) AS edge_weight FROM generate_series(1, 200) WHERE start_node != end_node;
内容的提问来源于stack exchange,提问作者ahmed_131313
相关产品推荐
相关产品推荐

