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#组合数学

Download history 6/week @ 2024-03-16 10/week @ 2024-03-30

每月 64 次下载

GPL-3.0+

505KB
11K SLoC

此 crate 提供自动图推导。

为了为包含实际图数据结构的结构体自动实现图特性,请在该结构体中添加 #[derive(Graph)]。包含图的字段必须命名为 graph 或使用 #[graph] 属性。为嵌套图实现的全部图特性(GraphDigraphIndexGraph)也会在注解的结构体中实现。

示例

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; }

属性图

一些算法需要特定的节点或边属性。这些需求由 NodeAttributesEdgeAttributes 特性表示,这些特性来自 rs_graph::attributes。如果包装图是 IndexGraph,则可以使用 #[derive(Graph)] 自动实现这些特性。节点/边属性必须收集在适当大小的可索引数组(切片、Vec 等)中,并使用 nodeattrsedgeattrs 属性注解。请注意,确保这些向量具有正确的大小是用户的责任。

示例

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