pub struct Graph<T> { /* private fields */ }Expand description
A ‘Graph’ is simply a ‘Vec’ of ’GraphNode’s.
Its important to note that this graph differs from a traditional graph in that it is not a collection of edges and vertices. Instead, it is a collection of nodes that are connected to one another. Each node has a unique index that is used to reference it in the graph and must be identical to its position in the ‘Vec’. Each ‘GraphNode’ has a set of ordered incoming and outgoing connections. These connections are represented by the index of the connected node in the graph. Because of this representation, an edge is not a separate entity, its just a node. The ‘NodeType’ enum is used to distinguish different types of nodes. This allows for a more flexible representation of the graph while still maintaining the ability to represent traditional graphs.
By default, a ‘Graph’ is a directed acyclic graph (DAG). However, it is possible to create cycles in the graph by setting the ‘direction’ field of a ‘GraphNode’ to ‘Direction::Backward’. The ‘Graph’ struct provides methods for attaching and detaching nodes from one another. It also provides methods for iterating over the nodes in the graph in a sudo topological order.
Implementations§
Source§impl<T: Clone + Default> Graph<T>
impl<T: Clone + Default> Graph<T>
Sourcepub fn directed(
input_size: usize,
output_size: usize,
values: impl Into<NodeStore<T>>,
) -> Graph<T>
pub fn directed( input_size: usize, output_size: usize, values: impl Into<NodeStore<T>>, ) -> Graph<T>
Creates a directed graph with the given input and output sizes. The values are used to initialize the nodes in the graph with the given values.
§Example
use radiate::*;
use radiate_gp::*;
let values = vec![
(NodeType::Input, vec![Op::var(0), Op::var(1), Op::var(2)]),
(NodeType::Output, vec![Op::sigmoid()]),
];
let graph = Graph::directed(3, 3, values);
assert_eq!(graph.len(), 6);The graph will have 6 nodes, 3 input nodes and 3 output nodes where each input node is connected to each output node. Such as:
[0, 1, 2] -> [3, 4, 5]§Arguments
input_size- The number of input nodes.output_size- The number of output nodes.values- The values to initialize the nodes with.
§Returns
A new directed graph.
Sourcepub fn recurrent(
input_size: usize,
output_size: usize,
values: impl Into<NodeStore<T>>,
) -> Graph<T>
pub fn recurrent( input_size: usize, output_size: usize, values: impl Into<NodeStore<T>>, ) -> Graph<T>
Creates a recurrent graph with the given input and output sizes. The values are used to initialize the nodes in the graph with the given values. The graph will have a recurrent connection from each hidden vertex to itself. The graph will have a one-to-one connection from each input node to each hidden vertex. The graph will have an all-to-all connection from each hidden vertex to each output node.
§Example
use radiate::*;
use radiate_gp::*;
let values = vec![
(NodeType::Input, vec![Op::var(0), Op::var(1), Op::var(2)]),
(NodeType::Vertex, vec![Op::linear()]),
(NodeType::Output, vec![Op::sigmoid()]),
];
let graph = Graph::recurrent(3, 3, values);
assert_eq!(graph.len(), 12);The graph will have 12 nodes, 3 input nodes, 3 hidden nodes with recurrent connections to themselves, and 3 output nodes. Such as:
[0, 1, 2] -> [3, 4, 5]
[3, 4, 5] -> [6, 7, 8]
[6, 7, 8] -> [3, 4, 5]
[3, 4, 5] -> [9, 10, 11]§Arguments
input_size- The number of input nodes.output_size- The number of output nodes.values- The values to initialize the nodes with.
§Returns
A new recurrent graph.
Sourcepub fn weighted_directed(
input_size: usize,
output_size: usize,
values: impl Into<NodeStore<T>>,
) -> Graph<T>
pub fn weighted_directed( input_size: usize, output_size: usize, values: impl Into<NodeStore<T>>, ) -> Graph<T>
Creates a weighted directed graph with the given input and output sizes.
This will result in the same graph as Graph::directed but with an additional edge
connecting each input node to each output node.
§Arguments
input_size- The number of input nodes.output_size- The number of output nodes.
§Returns
A new weighted directed graph.
Sourcepub fn weighted_recurrent(
input_size: usize,
output_size: usize,
values: impl Into<NodeStore<T>>,
) -> Graph<T>
pub fn weighted_recurrent( input_size: usize, output_size: usize, values: impl Into<NodeStore<T>>, ) -> Graph<T>
Creates a weighted recurrent graph with the given input and output sizes.
This will result in the same graph as Graph::recurrent but with an additional edge
connecting each hidden vertex to each output node.
§Arguments
input_size- The number of input nodes.output_size- The number of output nodes.
§Returns
A new weighted recurrent graph.
Source§impl<T> Graph<T>
The ‘Graph’ struct provides methods for creating, modifying, and iterating over a graph.
impl<T> Graph<T>
The ‘Graph’ struct provides methods for creating, modifying, and iterating over a graph.
Sourcepub fn push(&mut self, node: impl Into<GraphNode<T>>)
pub fn push(&mut self, node: impl Into<GraphNode<T>>)
Push a ‘GraphNode’ onto the last position in the graph.
pub fn insert(&mut self, node_type: NodeType, val: T) -> usize
Sourcepub fn get_mut(&mut self, index: usize) -> Option<&mut GraphNode<T>>
pub fn get_mut(&mut self, index: usize) -> Option<&mut GraphNode<T>>
Returns a mutable reference to the node at the specified index.
Sourcepub fn get(&self, index: usize) -> Option<&GraphNode<T>>
pub fn get(&self, index: usize) -> Option<&GraphNode<T>>
Returns a reference to the node at the specified index.
Sourcepub fn iter(&self) -> impl Iterator<Item = &GraphNode<T>>
pub fn iter(&self) -> impl Iterator<Item = &GraphNode<T>>
iterates over the nodes in the graph. The nodes are returned in the order they were added, so there is no real order to this iterator.
Sourcepub fn iter_mut(&mut self) -> impl Iterator<Item = &mut GraphNode<T>>
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut GraphNode<T>>
mutably iterates over the nodes in the graph. The nodes are returned in the order they
Sourcepub fn attach(&mut self, incoming: usize, outgoing: usize) -> &mut Self
pub fn attach(&mut self, incoming: usize, outgoing: usize) -> &mut Self
Attach and detach nodes from one another. This is the primary way to modify the graph. Note that this method does not check if the nodes are already connected. This is because the connections are represented by ’HashSet’s which do not allow duplicates. Its also important to note that the ‘incoming’ and ‘outgoing’ indices are the indices of the nodes in the graph, not the indices of the connections in the ‘incoming’ and ‘outgoing’ ’HashSet’s. We must also remember that the ‘GraphNode’ cares about the ‘Arity’ of the ‘Operation’ it contains, so if we add a connection that would violate the ‘Arity’ of the ‘Operation’, the connection will result in a ‘GraphNode’ that is not ‘Valid’.
Attaches the node at the ‘incoming’ index to the node at the ‘outgoing’ index. This means that the node at the ‘incoming’ index will have an outgoing connection to the node at the ‘outgoing’ index, and the node at the ‘outgoing’ index will have an incoming connection from the node at the ‘incoming’ index.
§Arguments
- incoming: The index of the node that will have an outgoing connection to the node at the ‘outgoing’ index.
- outgoing: The index of the node that will have an incoming connection from the node at the ‘incoming’ index.
Sourcepub fn detach(&mut self, incoming: usize, outgoing: usize) -> &mut Self
pub fn detach(&mut self, incoming: usize, outgoing: usize) -> &mut Self
Detaches the node at the ‘incoming’ index from the node at the ‘outgoing’ index. This means that the node at the ‘incoming’ index will no longer have an outgoing connection to the node at the ‘outgoing’ index, and the node at the ‘outgoing’ index will no longer have an incoming connection from the node at the ‘incoming’ index.
§Arguments
- incoming: The index of the node that will no longer have an outgoing connection to the node at the ‘outgoing’ index.
- outgoing: The index of the node that will no longer have an incoming connection from the node at the ‘incoming’ index.
Source§impl<T> Graph<T>
Functinos for modifying the graph.
impl<T> Graph<T>
Functinos for modifying the graph.
Sourcepub fn set_cycles(&mut self, indecies: Vec<usize>)
pub fn set_cycles(&mut self, indecies: Vec<usize>)
Given a list of node indices, this function will set the ‘direction’ field of the nodes at those indices to ‘Direction::Backward’ if they are part of a cycle. If they are not part of a cycle, the ‘direction’ field will be set to ‘Direction::Forward’. If no indices are provided, the function will set the ‘direction’ field of all nodes in the graph.
Sourcepub fn try_modify<F>(&mut self, mutation: F) -> TransactionResult<T>
pub fn try_modify<F>(&mut self, mutation: F) -> TransactionResult<T>
tries to modify the graph using a ‘GraphTransaction’. If the transaction is successful, we return true and do nothing. If the transaction is not successful, we rollback the transaction by undoing all the changes made by the transaction and return false.
§Arguments
- mutation: A closure that takes a mutable reference to a ‘GraphTransaction’ and returns a ‘bool’.
Trait Implementations§
Source§impl<T> Codex<GraphChromosome<T>, Graph<T>> for GraphCodex<T>
impl<T> Codex<GraphChromosome<T>, Graph<T>> for GraphCodex<T>
fn encode(&self) -> Genotype<GraphChromosome<T>>
fn decode(&self, genotype: &Genotype<GraphChromosome<T>>) -> Graph<T>
Source§fn spawn(&self, num: usize) -> Vec<T>
fn spawn(&self, num: usize) -> Vec<T>
T from the Codex. This will encode num new Genotypes and then
decode it to a new instance of T.Source§fn spawn_genotypes(&self, num: usize) -> Vec<Genotype<C>>
fn spawn_genotypes(&self, num: usize) -> Vec<Genotype<C>>
Genotype<G, A> from the Codex. This will encode num a new Genotypes.Source§fn spawn_population(&self, num: usize) -> Population<C>
fn spawn_population(&self, num: usize) -> Population<C>
Population<G, A> from the Codex. This will encode num a new Genotypes