algos/src/util.rs

356 lines
10 KiB
Rust

use crate::floyd_warshall;
use crate::huffman;
use crate::jobs;
use crate::k_clustering;
use crate::k_clustering_big;
use crate::knapsack;
use crate::min_cut;
use crate::mwis;
use crate::prims;
use crate::ssc;
use std::fs::File;
use std::io;
use std::io::{BufRead, BufReader, Error, ErrorKind};
use std::vec::Vec;
pub fn read_to_vector(path: &str) -> Result<Vec<i64>, io::Error> {
let file = File::open(path)?;
let br = BufReader::new(file);
let mut v = Vec::new();
for line in br.lines() {
let line = line?;
let n = line
.trim()
.parse()
.map_err(|e| Error::new(ErrorKind::InvalidData, e))?;
v.push(n);
}
Ok(v)
}
pub fn read_to_graph(path: &str) -> Result<min_cut::Graph, io::Error> {
let mut g = min_cut::Graph {
nodes: vec![],
edges: vec![],
};
let file = File::open(path)?;
let br = BufReader::new(file);
for line in br.lines() {
let line = line?;
let mut nodes = line.split_whitespace();
let current_node = nodes.next().unwrap().parse().unwrap();
g.nodes.push(current_node);
for neightbor in nodes {
let neightbor: u32 = neightbor.parse().unwrap();
// If the neighbor is smaller than the current node that means we
// have already added it when we iterated over that smaller node.
// Hence, we do not add the edge again.
if neightbor > current_node {
let edge = (current_node, neightbor);
g.edges.push(edge);
}
}
}
Ok(g)
}
fn get_node_size(path: &str) -> Result<usize, io::Error> {
let mut node_size = 0;
let file = File::open(path)?;
let br = BufReader::new(file);
for line in br.lines() {
let line = line?;
let mut nodes = line.split_whitespace();
let node: usize = nodes.next().unwrap().parse().unwrap();
if node > node_size {
node_size = node;
}
}
Ok(node_size)
}
pub fn read_to_directed_graph(
path: &str,
) -> Result<(ssc::DirectedGraph, ssc::DirectedGraph), io::Error> {
let nodes: usize = get_node_size(path).unwrap();
let mut g = ssc::DirectedGraph {
nodes: vec![vec![]; nodes],
explored: vec![false; nodes],
time: vec![0; nodes],
leader: vec![0; nodes],
};
let mut g_dash = ssc::DirectedGraph {
nodes: vec![vec![]; nodes],
explored: vec![false; nodes],
time: vec![0; nodes],
leader: vec![0; nodes],
};
let file = File::open(path)?;
let br = BufReader::new(file);
for line in br.lines() {
let line = line?;
let mut nodes = line.split_whitespace();
let first_node: usize = nodes.next().unwrap().parse().unwrap();
let second_node: usize = nodes.next().unwrap().parse().unwrap();
g.nodes[first_node - 1].push(second_node - 1);
g_dash.nodes[second_node - 1].push(first_node - 1);
}
Ok((g, g_dash))
}
pub fn read_to_directed_weighted_graph(
path: &str,
) -> Result<crate::dijkstra::DirectedWeightedGraph, io::Error> {
let nodes: usize = get_node_size(path).unwrap();
let mut g = crate::dijkstra::DirectedWeightedGraph {
nodes: vec![vec![]; nodes],
distance: vec![1000000; nodes], // initial distance based on instructions
};
let file = File::open(path)?;
let br = BufReader::new(file);
for line in br.lines() {
let line = line?;
let mut nodes = line.split_whitespace();
let current_node: usize = nodes.next().unwrap().parse().unwrap();
for edge in nodes {
let mut it = edge.split(",");
let target_node: usize = it.next().unwrap().parse().unwrap();
let distance: usize = it.next().unwrap().parse().unwrap();
g.nodes[current_node - 1].push((target_node - 1, distance))
}
}
Ok(g)
}
pub fn read_jobs(path: &str) -> Result<jobs::Jobs, io::Error> {
let mut jobs = Vec::new();
let file = File::open(path)?;
let br = BufReader::new(file);
let mut lines = br.lines();
lines.next();
for line in lines {
let line = line?;
let mut nodes = line.split_whitespace();
let weight = nodes.next().unwrap().parse().unwrap();
let length = nodes.next().unwrap().parse().unwrap();
let job = jobs::Job {
weight: weight,
length: length,
};
jobs.push(job);
}
Ok(jobs)
}
pub fn read_weighted_graph_prims(path: &str) -> Result<prims::WeightedGraph, io::Error> {
let mut g = Vec::new();
let file = File::open(path)?;
let br = BufReader::new(file);
let mut lines = br.lines();
let line = lines.next().unwrap().unwrap();
let mut fields = line.split_whitespace();
let n_nodes: usize = fields.next().unwrap().parse().unwrap();
// let n_edges: usize = fields.next().unwrap().parse().unwrap();
for i in 0..n_nodes {
let node = prims::Vertex {
id: i,
edges: vec![],
};
g.push(node);
}
for line in lines {
let line = line?;
let mut nodes = line.split_whitespace();
let id_a: usize = nodes.next().unwrap().parse::<usize>().unwrap() - 1;
let id_b: usize = nodes.next().unwrap().parse::<usize>().unwrap() - 1;
let weight = nodes.next().unwrap().parse().unwrap();
let edge = prims::Edge {
weight: weight,
source_id: id_a,
target_id: id_b,
};
g[id_a].edges.push(edge);
let edge = crate::prims::Edge {
weight: weight,
source_id: id_b,
target_id: id_a,
};
g[id_b].edges.push(edge);
}
Ok(g)
}
pub fn read_weighted_graph_clustering(
path: &str,
) -> Result<k_clustering::WeightedGraph, io::Error> {
let file = File::open(path)?;
let mut lines = BufReader::new(file).lines();
let line = lines.next().unwrap().unwrap();
let n_nodes: usize = line.parse().unwrap();
let mut g = k_clustering::WeightedGraph {
n_nodes: n_nodes,
edges: Vec::new(),
};
for line in lines {
let line = line?;
let mut nodes = line.split_whitespace();
let id_a: usize = nodes.next().unwrap().parse::<usize>().unwrap() - 1;
let id_b: usize = nodes.next().unwrap().parse::<usize>().unwrap() - 1;
let weight = nodes.next().unwrap().parse().unwrap();
let edge = k_clustering::Edge {
weight: weight,
source_id: id_a,
target_id: id_b,
};
g.edges.push(edge)
}
Ok(g)
}
pub fn read_k_cluster_big(path: &str) -> Result<k_clustering_big::ImpliciteGraph, io::Error> {
let file = File::open(path)?;
let mut lines = BufReader::new(file).lines();
lines.next();
let mut g = Vec::new();
for line in lines {
let mut s = line?;
s.retain(|c| !c.is_whitespace());
let u = u32::from_str_radix(&s, 2).unwrap();
g.push(u);
}
Ok(g)
}
pub fn read_huffman_alphabet(path: &str) -> Result<huffman::HuffmanAlphabet, io::Error> {
let file = File::open(path)?;
let mut lines = BufReader::new(file).lines();
let line = lines.next().unwrap().unwrap();
let length = line.parse().unwrap();
let mut h = huffman::HuffmanAlphabet {
length: length,
frequencies: Vec::new(),
};
for line in lines {
let line = line?;
let frequency = line.parse().unwrap();
h.frequencies.push(frequency);
}
assert!(length == h.frequencies.len());
Ok(h)
}
pub fn read_max_weight_set(path: &str) -> Result<mwis::IndependentSet, io::Error> {
let file = File::open(path)?;
let mut lines = BufReader::new(file).lines();
let line = lines.next().unwrap().unwrap();
let length = line.parse().unwrap();
let mut s = mwis::IndependentSet {
length: length,
weights: Vec::new(),
};
for line in lines {
let line = line?;
let weight = line.parse().unwrap();
s.weights.push(weight);
}
assert!(length == s.weights.len());
Ok(s)
}
pub fn read_knapsack(path: &str) -> Result<knapsack::Knapsack, io::Error> {
let file = File::open(path)?;
let mut lines = BufReader::new(file).lines();
let line = lines.next().unwrap().unwrap();
let mut fields = line.split_whitespace();
let knapsack_size = fields.next().unwrap().parse().unwrap();
let number_of_items = fields.next().unwrap().parse().unwrap();
let mut k = knapsack::Knapsack {
size: knapsack_size,
n_items: number_of_items,
items: Vec::new(),
};
for line in lines {
let line = line?;
let mut fields = line.split_whitespace();
let value = fields.next().unwrap().parse().unwrap();
let weight = fields.next().unwrap().parse().unwrap();
let item = knapsack::Item {
value: value,
weight: weight,
};
k.items.push(item);
}
Ok(k)
}
pub fn read_floyd_warshall_graph(path: &str) -> Result<floyd_warshall::Graph, io::Error> {
let file = File::open(path)?;
let mut lines = BufReader::new(file).lines();
let line = lines.next().unwrap()?;
let mut fields = line.split_whitespace();
let n_nodes = fields.next().unwrap().parse().unwrap();
let n_edges = fields.next().unwrap().parse().unwrap();
let mut g = floyd_warshall::Graph {
n_nodes: n_nodes,
n_edges: n_edges,
nodes: Vec::new(),
};
for i in 0..n_nodes {
let n = floyd_warshall::Node {
id: i,
edges: Vec::new(),
};
g.nodes.push(n);
}
for line in lines {
let line = line?;
let mut it = line.split_whitespace();
let mut source = it.next().unwrap().parse().unwrap();
let mut target = it.next().unwrap().parse().unwrap();
let length = it.next().unwrap().parse().unwrap();
source = source - 1;
target = target - 1;
let e = floyd_warshall::Edge {
source: source,
target: target,
length: length,
};
g.nodes[source].edges.push(e);
}
Ok(g)
}