Skip to content

Commit

Permalink
Change network params
Browse files Browse the repository at this point in the history
  • Loading branch information
reinterpretcat committed Jan 24, 2025
1 parent 5aea7b9 commit d86b1ad
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 76 deletions.
8 changes: 4 additions & 4 deletions experiments/heuristic-research/src/plots/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ pub enum PopulationSeries {
rows: Range<i32>,
/// Columns range.
cols: Range<i32>,
/// Mean node distance.
mean_distance: Float,
/// MSE distance.
mse: Float,
/// Best fitness values.
fitness_values: Vec<Float>,
/// Objective values chart series.
Expand All @@ -82,8 +82,8 @@ pub enum PopulationSeries {
t_matrix: Series2D,
/// L-matrix values chart series.
l_matrix: Series2D,
/// Node distance values chart series.
n_matrix: Series2D,
/// MSE values chart series.
m_matrix: Series2D,
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ pub(crate) fn draw_on_area<B: DrawingBackend + 'static>(
cols,
fitness_values,
fitness_matrices,
mean_distance,
mse,
u_matrix,
t_matrix,
l_matrix,
n_matrix,
m_matrix,
} => {
let _fitness_values = fitness_values;
let plots = fitness_matrices.len() + 5;
Expand Down Expand Up @@ -202,8 +202,8 @@ pub(crate) fn draw_on_area<B: DrawingBackend + 'static>(
draw_series2d(sub_areas.get_mut(len + 3).unwrap(), &get_caption_usize("lh"), l_matrix)?;
draw_series2d(
sub_areas.get_mut(len + 4).unwrap(),
&get_caption_float(format!("mu ({:.2})", *mean_distance).as_str()),
n_matrix,
&get_caption_float(format!("mse ({:.2})", *mse).as_str()),
m_matrix,
)?;

fitness_matrices.iter().enumerate().try_for_each(|(idx, objective)| {
Expand Down
8 changes: 4 additions & 4 deletions experiments/heuristic-research/src/plots/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,13 @@ fn get_population_series(generation: usize) -> PopulationSeries {
Some(PopulationState::Rosomaxa {
rows,
cols,
mean_distance,
mse,
fitness_values,
fitness_matrices,
u_matrix,
t_matrix,
l_matrix,
n_matrix,
m_matrix,
}) => {
let get_series = |matrix: &MatrixData| {
let matrix = matrix.clone();
Expand All @@ -369,13 +369,13 @@ fn get_population_series(generation: usize) -> PopulationSeries {
Some(PopulationSeries::Rosomaxa {
rows: rows.clone(),
cols: cols.clone(),
mean_distance: *mean_distance,
mse: *mse,
fitness_values: fitness_values.clone(),
fitness_matrices: fitness_matrices.iter().map(get_series).collect(),
u_matrix: get_series(u_matrix),
t_matrix: get_series(t_matrix),
l_matrix: get_series(l_matrix),
n_matrix: get_series(n_matrix),
m_matrix: get_series(m_matrix),
})
}
_ => None,
Expand Down
29 changes: 9 additions & 20 deletions experiments/heuristic-research/src/solver/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub enum PopulationState {
rows: Range<i32>,
/// Cols range.
cols: Range<i32>,
/// Mean distance.
mean_distance: Float,
/// MSE distance.
mse: Float,
/// Best fitness values.
fitness_values: Vec<Float>,
/// Overall fitness values data split into separate matrices.
Expand All @@ -36,8 +36,8 @@ pub enum PopulationState {
t_matrix: MatrixData,
/// L-matrix values data.
l_matrix: MatrixData,
/// Node distance values data.
n_matrix: MatrixData,
/// MSE node values data.
m_matrix: MatrixData,
},
}

Expand Down Expand Up @@ -68,27 +68,19 @@ fn create_rosomaxa_state(network_state: NetworkState, fitness_values: Vec<Float>
let rosomaxa = PopulationState::Rosomaxa {
rows,
cols,
mean_distance: 0.,
mse: 0.,
fitness_values,
fitness_matrices: Default::default(),
u_matrix: Default::default(),
t_matrix: Default::default(),
l_matrix: Default::default(),
n_matrix: Default::default(),
m_matrix: Default::default(),
};

network_state.nodes.iter().fold(rosomaxa, |mut rosomaxa, node| {
let coordinate = Coordinate(node.coordinate.0, node.coordinate.1);
match &mut rosomaxa {
PopulationState::Rosomaxa {
fitness_matrices,
mean_distance,
u_matrix,
t_matrix,
l_matrix,
n_matrix,
..
} => {
PopulationState::Rosomaxa { fitness_matrices, mse, u_matrix, t_matrix, l_matrix, m_matrix, .. } => {
// NOTE get first fitness in assumption of sorted order
let fitness = match (node.dump.starts_with("[["), node.dump.find(']')) {
(true, Some(value)) => node.dump[2..value]
Expand All @@ -106,14 +98,11 @@ fn create_rosomaxa_state(network_state: NetworkState, fitness_values: Vec<Float>
});
}

if let Some(node_distance) = node.node_distance {
n_matrix.insert(coordinate, node_distance);
}

m_matrix.insert(coordinate, node.mse);
u_matrix.insert(coordinate, node.unified_distance);
t_matrix.insert(coordinate, node.total_hits as Float);
l_matrix.insert(coordinate, node.last_hits as Float);
*mean_distance = network_state.mean_distance;
*mse = network_state.mse;
}
_ => unreachable!(),
}
Expand Down
25 changes: 16 additions & 9 deletions rosomaxa/src/algorithms/gsom/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
mod network_test;

use super::*;
use crate::algorithms::math::get_mean_iter;
use crate::utils::*;
use rand::prelude::SliceRandom;
use rayon::iter::Either;
Expand Down Expand Up @@ -238,16 +237,19 @@ where
self.time
}

/// Calculates mean distance of nodes with individuals.
pub fn mean_distance(&self) -> Float {
get_mean_iter(self.nodes.iter().filter_map(|(_, node)| node.node_distance(self)))
}

/// Calculates mean squared error of the whole network.
pub fn mse(&self) -> Float {
let n = if self.nodes.is_empty() { 1 } else { self.nodes.len() } as Float;
let (n, sum) = self
.nodes
.iter()
.filter(|(_, node)| node.storage.size() > 0)
.fold((0, 0.), |(n, sum), (_, node)| (n + 1, sum + node.mse(self)));

self.nodes.iter().fold(0., |acc, (_, node)| acc + node.mse()) / n
if n > 0 {
sum / n as Float
} else {
0.
}
}

/// Returns max unified distance of the network.
Expand Down Expand Up @@ -598,9 +600,14 @@ where
}

/// Returns a distance between weights.
pub fn distance(&self, left: &[Float], right: &[Float]) -> Float {
pub(crate) fn distance(&self, left: &[Float], right: &[Float]) -> Float {
euclidian_distance(left, right, &self.min_max_weights)
}

/// Returns normalized weights.
pub(crate) fn normalize<'a>(&'a self, values: &'a [Float]) -> impl Iterator<Item = Float> + 'a {
normalize(values, &self.min_max_weights)
}
}

fn compare_input<I: Input>(left: &I, right: &I) -> Ordering {
Expand Down
37 changes: 10 additions & 27 deletions rosomaxa/src/algorithms/gsom/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,39 +126,22 @@ impl<I: Input, S: Storage<Item = I>> Node<I, S> {
}
}

/// Returns distance between underlying item (if any) and node weight's.
pub fn node_distance<C, F>(&self, network: &Network<C, I, S, F>) -> Option<Float>
/// Returns mean squared error.
pub fn mse<C, F>(&self, network: &Network<C, I, S, F>) -> Float
where
C: Send + Sync,
F: StorageFactory<C, I, S>,
{
self.storage.iter().next().map(|item| network.distance(&self.weights, item.weights()))
}
if self.storage.size() == 0 {
return 0.;
}

/// Calculates mean squared error of the node.
pub fn mse(&self) -> Float {
let (count, sum) = self
.storage
.iter()
// NOTE try only first item so far
.take(1)
.fold((0, 0.), |(items, acc), data| {
let err = data
.weights()
.iter()
.zip(self.weights.iter())
.map(|(&w1, &w2)| (w1 - w2) * (w1 - w2))
.sum::<Float>()
/ self.weights.len() as Float;

(items + 1, acc + err)
});
self.storage.iter().fold(0., |acc, input| {
let node_weights = network.normalize(&self.weights);
let input_weights = network.normalize(input.weights());

if count > 0 {
sum / count as Float
} else {
sum
}
acc + node_weights.zip(input_weights).map(|(w1, w2)| (w1 - w2) * (w1 - w2)).sum::<Float>()
}) / self.storage.size() as Float
}
}

Expand Down
14 changes: 7 additions & 7 deletions rosomaxa/src/algorithms/gsom/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use std::ops::Range;
pub struct NetworkState {
/// Shape of the network as (rows, cols, num of weights).
pub shape: (Range<i32>, Range<i32>, usize),
/// Mean of node distance.
pub mean_distance: Float,
/// Mean squared error of the network.
pub mse: Float,
/// Nodes of the network.
pub nodes: Vec<NodeState>,
}
Expand All @@ -23,8 +23,8 @@ pub struct NodeState {
pub coordinate: (i32, i32),
/// Unified distance to neighbors.
pub unified_distance: Float,
/// Distance between weights of individual and node weights.
pub node_distance: Option<Float>,
/// Mean squared error of the node.
pub mse: Float,
/// Node weights.
pub weights: Vec<Float>,
/// Total hits.
Expand All @@ -45,7 +45,7 @@ where
{
let ((x_min, x_max), (y_min, y_max)) = get_network_shape(network);

let mean_distance = network.mean_distance();
let mse = network.mse();

let nodes = network
.get_nodes()
Expand All @@ -56,7 +56,7 @@ where
NodeState {
coordinate: (node.coordinate.0, node.coordinate.1),
unified_distance: node.unified_distance(network, 1),
node_distance: node.node_distance(network),
mse: node.mse(network),
weights: node.weights.clone(),
total_hits: node.total_hits,
last_hits: node.get_last_hits(network.get_current_time()),
Expand All @@ -67,7 +67,7 @@ where

let dim = nodes.first().map_or(0, |node| node.weights.len());

NetworkState { shape: (x_min..x_max, y_min..y_max, dim), nodes, mean_distance }
NetworkState { shape: (x_min..x_max, y_min..y_max, dim), nodes, mse }
}

/// Gets network's shape: min-max coordinate indices.
Expand Down
1 change: 0 additions & 1 deletion rosomaxa/tests/unit/algorithms/gsom/network_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,6 @@ fn can_create_network_random_data() {
// Verify node coverage
assert_eq!(count_data_stored(&network.nodes), initial_data.len());
// Check network metrics
assert!(network.mean_distance() > 0.);
assert!(network.mse() > 0.);
assert!(network.max_unified_distance() > 0.);
}
Expand Down

0 comments on commit d86b1ad

Please sign in to comment.