21 个版本 (12 个重大更新)
0.21.0 | 2023年8月28日 |
---|---|
0.20.1 | 2021年5月8日 |
0.19.2 | 2020年6月3日 |
0.19.1 | 2020年2月14日 |
0.9.0 | 2017年12月14日 |
#23 在 #组合数学
每月 64 次下载
505KB
11K SLoC
此 crate 提供自动图推导。
为了为包含实际图数据结构的结构体自动实现图特性,请在该结构体中添加 #[derive(Graph)]。包含图的字段必须命名为 graph
或使用 #[graph]
属性。为嵌套图实现的全部图特性(Graph
、Digraph
和 IndexGraph
)也会在注解的结构体中实现。
示例
use rs_graph_derive::Graph;
use rs_graph::traits::*;
use rs_graph::linkedlistgraph::*;
use rs_graph::classes;
#[derive(Graph)]
struct MyGraph {
#[graph] graph: LinkedListGraph, // #[graph] not needed for fields named `graph`.
balances: Vec<f64>,
bounds: Vec<f64>,
}
impl From<LinkedListGraph> for MyGraph {
fn from(g: LinkedListGraph) -> MyGraph {
let n = g.num_nodes();
let m = g.num_edges();
MyGraph {
graph: g,
balances: vec![0.0; n],
bounds: vec![0.0; m],
}
}
}
impl MyGraph {
fn balance_mut(&mut self, u: Node) -> &mut f64 {
&mut self.balances[self.graph.node_id(u)]
}
fn bound_mut(&mut self, e: Edge) -> &mut f64 {
&mut self.bounds[self.graph.edge_id(e)]
}
}
let mut g: MyGraph = classes::path::<LinkedListGraph>(5).into();
let (s, t) = (g.id2node(0), g.id2node(4));
*g.balance_mut(s) = 1.0;
*g.balance_mut(t) = -1.0;
for eid in 0..g.num_edges() { *g.bound_mut(g.id2edge(eid)) = eid as f64; }
属性图
一些算法需要特定的节点或边属性。这些需求由 NodeAttributes
和 EdgeAttributes
特性表示,这些特性来自 rs_graph::attributes
。如果包装图是 IndexGraph
,则可以使用 #[derive(Graph)]
自动实现这些特性。节点/边属性必须收集在适当大小的可索引数组(切片、Vec
等)中,并使用 nodeattrs
或 edgeattrs
属性注解。请注意,确保这些向量具有正确的大小是用户的责任。
示例
use rs_graph_derive::Graph;
use rs_graph::{traits::*};
use rs_graph::linkedlistgraph::*;
use rs_graph::classes;
use rs_graph::attributes::{NodeAttributes, EdgeAttributes, AttributedGraph};
#[derive(Clone, Default)]
struct NodeData {
balance: f64,
}
#[derive(Clone, Default)]
struct EdgeData {
bound: f64,
}
#[derive(Graph)]
struct MyGraph {
#[graph] graph: LinkedListGraph,
#[nodeattrs(NodeData)] nodedata: Vec<NodeData>,
#[edgeattrs(EdgeData)] edgedata: Vec<EdgeData>,
}
#[derive(Graph)]
struct MyGraph2 {
#[graph] graph: LinkedListGraph,
#[nodeattrs(NodeData)] nodedata: Vec<NodeData>,
#[edgeattrs(EdgeData)] edgedata: Vec<EdgeData>,
}
impl From<LinkedListGraph> for MyGraph {
fn from(g: LinkedListGraph) -> MyGraph {
let n = g.num_nodes();
let m = g.num_edges();
MyGraph {
graph: g,
nodedata: vec![Default::default(); n],
edgedata: vec![Default::default(); m],
}
}
}
let mut g: MyGraph = classes::peterson::<LinkedListGraph>().into();
let (s, t) = (g.id2node(0), g.id2node(4));
g.node_mut(s).balance = 1.0;
g.node_mut(t).balance = -1.0;
for eid in 0..g.num_edges() { g.edge_mut(g.id2edge(eid)).bound = eid as f64; }
{
let (g, mut attrs) = g.split();
// this would also work: let (g, mut attrs) = attrs.split();
for u in g.nodes() {
for (e, v) in g.outedges(u) {
attrs.node_mut(v).balance = 42.0 + g.node_id(v) as f64;
}
}
}
for u in g.nodes() {
assert_eq!(g.node(u).balance, 42.0 + g.node_id(u) as f64);
}
依赖项
~1.5MB
~40K SLoC