Finish course 3 week 1
parent
b69713fb5e
commit
a13fae6ceb
127
src/heap.rs
127
src/heap.rs
|
@ -4,31 +4,32 @@ struct MinHeap<T> {
|
|||
}
|
||||
|
||||
fn parent_index(index: usize) -> usize {
|
||||
(index + 1) / 2 - 1
|
||||
(index + 1) / 2 - 1
|
||||
}
|
||||
|
||||
fn child_indices(index: usize) -> (usize, usize) {
|
||||
((index + 1) * 2 - 1, (index + 1) * 2 + 1 - 1)
|
||||
((index + 1) * 2 - 1, (index + 1) * 2 + 1 - 1)
|
||||
}
|
||||
|
||||
impl<T: std::cmp::PartialOrd> MinHeap<T> {
|
||||
fn new() -> Self {
|
||||
Self { nodes: Vec::with_capacity(128) }
|
||||
Self {
|
||||
nodes: Vec::with_capacity(128),
|
||||
}
|
||||
}
|
||||
|
||||
fn smaller_than_parent(&self, index: usize) -> bool {
|
||||
if index == 0 {
|
||||
false
|
||||
} else {
|
||||
|
||||
self.nodes[index] < self.nodes[parent_index(index)]
|
||||
}
|
||||
if index == 0 {
|
||||
false
|
||||
} else {
|
||||
self.nodes[index] < self.nodes[parent_index(index)]
|
||||
}
|
||||
}
|
||||
|
||||
fn bubble_up(&mut self, index: usize) -> usize {
|
||||
let parent_index = parent_index(index);
|
||||
self.nodes.swap(index, parent_index);
|
||||
parent_index
|
||||
let parent_index = parent_index(index);
|
||||
self.nodes.swap(index, parent_index);
|
||||
parent_index
|
||||
}
|
||||
|
||||
fn insert(&mut self, e: T) -> () {
|
||||
|
@ -37,57 +38,57 @@ impl<T: std::cmp::PartialOrd> MinHeap<T> {
|
|||
let mut bubble_index = last;
|
||||
|
||||
while self.smaller_than_parent(bubble_index) {
|
||||
bubble_index = self.bubble_up(bubble_index);
|
||||
bubble_index = self.bubble_up(bubble_index);
|
||||
}
|
||||
}
|
||||
|
||||
fn greater_than_children(&self, index: usize) -> bool {
|
||||
let length = self.nodes.len();
|
||||
let (left_index, right_index) = child_indices(index);
|
||||
if left_index < length && self.nodes[index] > self.nodes[left_index] {
|
||||
true
|
||||
} else if right_index < length && self.nodes[index] > self.nodes[right_index] {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
let length = self.nodes.len();
|
||||
let (left_index, right_index) = child_indices(index);
|
||||
if left_index < length && self.nodes[index] > self.nodes[left_index] {
|
||||
true
|
||||
} else if right_index < length && self.nodes[index] > self.nodes[right_index] {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn bubble_down(&mut self, index: usize) -> usize {
|
||||
let length = self.nodes.len();
|
||||
let (left_index, right_index) = child_indices(index);
|
||||
let mut target_index = index;
|
||||
let length = self.nodes.len();
|
||||
let (left_index, right_index) = child_indices(index);
|
||||
let mut target_index = index;
|
||||
|
||||
if left_index < length && self.nodes[target_index] > self.nodes[left_index] {
|
||||
target_index = left_index;
|
||||
}
|
||||
if left_index < length && self.nodes[target_index] > self.nodes[left_index] {
|
||||
target_index = left_index;
|
||||
}
|
||||
|
||||
if right_index < length && self.nodes[right_index] < self.nodes[target_index] {
|
||||
target_index = right_index;
|
||||
}
|
||||
self.nodes.swap(index, target_index);
|
||||
target_index
|
||||
if right_index < length && self.nodes[right_index] < self.nodes[target_index] {
|
||||
target_index = right_index;
|
||||
}
|
||||
self.nodes.swap(index, target_index);
|
||||
target_index
|
||||
}
|
||||
|
||||
fn extract_min(&mut self) -> T {
|
||||
if self.nodes.len() == 0 {
|
||||
panic!("Cannot extract key from empty heap");
|
||||
}
|
||||
if self.nodes.len() == 0 {
|
||||
panic!("Cannot extract key from empty heap");
|
||||
}
|
||||
|
||||
let mut bubble_index = 0;
|
||||
let last = self.nodes.len() - 1;
|
||||
self.nodes.swap(bubble_index, last);
|
||||
let result = self.nodes.pop().unwrap();
|
||||
let mut bubble_index = 0;
|
||||
let last = self.nodes.len() - 1;
|
||||
self.nodes.swap(bubble_index, last);
|
||||
let result = self.nodes.pop().unwrap();
|
||||
|
||||
while self.greater_than_children(bubble_index) {
|
||||
bubble_index = self.bubble_down(bubble_index);
|
||||
}
|
||||
while self.greater_than_children(bubble_index) {
|
||||
bubble_index = self.bubble_down(bubble_index);
|
||||
}
|
||||
|
||||
result
|
||||
result
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
self.nodes.len()
|
||||
self.nodes.len()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,32 +96,32 @@ pub fn heap(v: &Vec<i64>) -> i64 {
|
|||
let mut hl: MinHeap<i64> = MinHeap::new();
|
||||
let mut hh: MinHeap<i64> = MinHeap::new();
|
||||
|
||||
let mut iter = v.into_iter();
|
||||
let mut iter = v.into_iter();
|
||||
let mut current_median = *iter.next().unwrap();
|
||||
let mut median_sum = current_median;
|
||||
hl.insert(-current_median);
|
||||
|
||||
for e in iter {
|
||||
let e = *e;
|
||||
if e < current_median {
|
||||
hl.insert(-e);
|
||||
} else {
|
||||
hh.insert(e);
|
||||
}
|
||||
let e = *e;
|
||||
if e < current_median {
|
||||
hl.insert(-e);
|
||||
} else {
|
||||
hh.insert(e);
|
||||
}
|
||||
|
||||
while hl.size() < hh.size() {
|
||||
let e = hh.extract_min();
|
||||
hl.insert(-e);
|
||||
}
|
||||
while hl.size() < hh.size() {
|
||||
let e = hh.extract_min();
|
||||
hl.insert(-e);
|
||||
}
|
||||
|
||||
while hl.size() > hh.size() + 1 {
|
||||
let e = -hl.extract_min();
|
||||
hh.insert(e);
|
||||
}
|
||||
while hl.size() > hh.size() + 1 {
|
||||
let e = -hl.extract_min();
|
||||
hh.insert(e);
|
||||
}
|
||||
|
||||
current_median = -hl.extract_min();
|
||||
median_sum = (median_sum + current_median) % 10000;
|
||||
hl.insert(-current_median);
|
||||
current_median = -hl.extract_min();
|
||||
median_sum = (median_sum + current_median) % 10000;
|
||||
hl.insert(-current_median);
|
||||
}
|
||||
|
||||
median_sum
|
||||
|
|
48
src/jobs.rs
48
src/jobs.rs
|
@ -2,47 +2,47 @@ use std::cmp::Ordering;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Job {
|
||||
pub weight: i64,
|
||||
pub length: i64,
|
||||
pub weight: i64,
|
||||
pub length: i64,
|
||||
}
|
||||
|
||||
pub type Jobs = Vec<Job>;
|
||||
|
||||
fn weighted_completion_time(jobs: &Jobs) -> i64 {
|
||||
let mut time = 0;
|
||||
let mut weighted_completion_time = 0;
|
||||
let mut time = 0;
|
||||
let mut weighted_completion_time = 0;
|
||||
|
||||
for job in jobs {
|
||||
let completion_time = time + job.length;
|
||||
weighted_completion_time += completion_time * job.weight;
|
||||
time += job.length;
|
||||
}
|
||||
for job in jobs {
|
||||
let completion_time = time + job.length;
|
||||
weighted_completion_time += completion_time * job.weight;
|
||||
time += job.length;
|
||||
}
|
||||
|
||||
weighted_completion_time
|
||||
weighted_completion_time
|
||||
}
|
||||
|
||||
fn compare_1(a: &Job, b: &Job) -> Ordering {
|
||||
let da = a.weight - a.length;
|
||||
let db = b.weight - b.length;
|
||||
if da == db {
|
||||
b.weight.cmp(&a.weight)
|
||||
} else {
|
||||
db.cmp(&da)
|
||||
}
|
||||
let da = a.weight - a.length;
|
||||
let db = b.weight - b.length;
|
||||
if da == db {
|
||||
b.weight.cmp(&a.weight)
|
||||
} else {
|
||||
db.cmp(&da)
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_2(a: &Job, b: &Job) -> Ordering {
|
||||
let da: f64 = a.weight as f64 / a.length as f64;
|
||||
let db: f64 = b.weight as f64 / b.length as f64;
|
||||
db.partial_cmp(&da).unwrap()
|
||||
let da: f64 = a.weight as f64 / a.length as f64;
|
||||
let db: f64 = b.weight as f64 / b.length as f64;
|
||||
db.partial_cmp(&da).unwrap()
|
||||
}
|
||||
|
||||
pub fn jobs_1(jobs: &mut Jobs) -> i64 {
|
||||
jobs.sort_by(compare_1);
|
||||
weighted_completion_time(&jobs)
|
||||
jobs.sort_by(compare_1);
|
||||
weighted_completion_time(&jobs)
|
||||
}
|
||||
|
||||
pub fn jobs_2(jobs: &mut Jobs) -> i64 {
|
||||
jobs.sort_by(compare_2);
|
||||
weighted_completion_time(&jobs)
|
||||
jobs.sort_by(compare_2);
|
||||
weighted_completion_time(&jobs)
|
||||
}
|
||||
|
|
37
src/main.rs
37
src/main.rs
|
@ -1,25 +1,24 @@
|
|||
mod dijkstra;
|
||||
mod heap;
|
||||
mod jobs;
|
||||
mod merge_sort;
|
||||
mod min_cut;
|
||||
mod prims;
|
||||
mod quick_sort;
|
||||
mod ssc;
|
||||
mod util;
|
||||
mod two_sum;
|
||||
mod jobs;
|
||||
mod prims;
|
||||
mod util;
|
||||
|
||||
use std::cmp::min;
|
||||
use crate::dijkstra::dijkstra;
|
||||
use crate::heap::heap;
|
||||
use crate::jobs::{jobs_1, jobs_2};
|
||||
use crate::merge_sort::merge_sort_inversions;
|
||||
use crate::min_cut::min_cut;
|
||||
use crate::prims::prims;
|
||||
use crate::quick_sort::quick_sort;
|
||||
use crate::ssc::ssc;
|
||||
use crate::two_sum::find_two_sums;
|
||||
use crate::jobs::{jobs_1, jobs_2};
|
||||
use crate::prims::prims;
|
||||
|
||||
use std::cmp::min;
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn c1a2() {
|
||||
|
@ -86,20 +85,25 @@ fn c2a4() {
|
|||
let mut v = util::read_to_vector("data/c2a4.txt").unwrap();
|
||||
let r = find_two_sums(&mut v);
|
||||
println!("c2a4={:?}", r);
|
||||
// c2a4=427
|
||||
// c2a4=427
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn c3a1() {
|
||||
let mut jobs = util::read_jobs("data/c3a1_jobs.txt").unwrap();
|
||||
let r1 = jobs_1(&mut jobs);
|
||||
let r2 = jobs_2(&mut jobs);
|
||||
// belongs to c3a1
|
||||
let mut jobs = util::read_jobs("data/c3a1_jobs.txt").unwrap();
|
||||
let r1 = jobs_1(&mut jobs);
|
||||
let r2 = jobs_2(&mut jobs);
|
||||
let g = util::read_weighted_graph("data/c3a1_edges.txt").unwrap();
|
||||
let r3 = prims(&g);
|
||||
println!("r1 = {}; r2 = {}; r3 = {} ", r1, r2, r3);
|
||||
|
||||
let g = util::read_weighted_graph("data/c3a1_edges.txt").unwrap();
|
||||
let r3 = prims(&g);
|
||||
// r1 = 69119377652; r2 = 67311454237; r3 = -3612829
|
||||
}
|
||||
|
||||
println!("r1 = {}; r2 = {}; r3 = {} ", r1, r2, r3);
|
||||
// r1 = 69119377652; r2 != 67311454237;
|
||||
#[allow(dead_code)]
|
||||
fn c3a2() {
|
||||
println!("let's go");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -110,5 +114,6 @@ fn main() {
|
|||
// c2a2();
|
||||
// c2a3();
|
||||
// c2a4();
|
||||
c3a1();
|
||||
// c3a1();
|
||||
c3a2();
|
||||
}
|
||||
|
|
53
src/prims.rs
53
src/prims.rs
|
@ -1,14 +1,49 @@
|
|||
#[derive(Debug, Clone)]
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Edge {
|
||||
pub node_a: u32,
|
||||
pub node_b: u32,
|
||||
pub weight: u32,
|
||||
pub weight: i32,
|
||||
pub source_id: usize,
|
||||
pub target_id: usize,
|
||||
}
|
||||
|
||||
pub type WeightedGraph = Vec<Edge>;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Vertex {
|
||||
pub id: usize,
|
||||
pub edges: Vec<Edge>,
|
||||
}
|
||||
|
||||
pub fn prims(graph: &WeightedGraph) -> usize {
|
||||
println!("{:?}", graph);
|
||||
42
|
||||
}
|
||||
pub type WeightedGraph = Vec<Vertex>;
|
||||
|
||||
pub fn prims(graph: &WeightedGraph) -> i32 {
|
||||
let mut x: HashSet<usize> = HashSet::new();
|
||||
let mut t = Vec::new();
|
||||
|
||||
x.insert(0);
|
||||
|
||||
while x.len() != graph.len() {
|
||||
let mut min_edge = Edge {
|
||||
weight: i32::MAX,
|
||||
source_id: 0,
|
||||
target_id: 0,
|
||||
};
|
||||
|
||||
for node_id in &x {
|
||||
for edge in &graph[*node_id].edges {
|
||||
if edge.weight < min_edge.weight && !x.contains(&edge.target_id) {
|
||||
min_edge = *edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x.insert(min_edge.target_id);
|
||||
t.push(min_edge);
|
||||
}
|
||||
|
||||
let mut result = 0;
|
||||
for edge in &t {
|
||||
result += edge.weight;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
|
|
@ -1,44 +1,49 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
fn binary_search<T: std::cmp::PartialOrd>(min_i: usize, max_i: usize, xs: &Vec<T>, needle: T) -> usize {
|
||||
if min_i >= max_i {
|
||||
return max_i;
|
||||
}
|
||||
let half_i = min_i + (max_i - min_i) / 2;
|
||||
fn binary_search<T: std::cmp::PartialOrd>(
|
||||
min_i: usize,
|
||||
max_i: usize,
|
||||
xs: &Vec<T>,
|
||||
needle: T,
|
||||
) -> usize {
|
||||
if min_i >= max_i {
|
||||
return max_i;
|
||||
}
|
||||
let half_i = min_i + (max_i - min_i) / 2;
|
||||
|
||||
if xs[half_i] == needle {
|
||||
return half_i;
|
||||
}
|
||||
if xs[half_i] == needle {
|
||||
return half_i;
|
||||
}
|
||||
|
||||
if needle < xs[half_i] {
|
||||
binary_search(min_i, half_i - 1, &xs, needle)
|
||||
} else {
|
||||
binary_search(half_i + 1, max_i, xs, needle)
|
||||
}
|
||||
if needle < xs[half_i] {
|
||||
binary_search(min_i, half_i - 1, &xs, needle)
|
||||
} else {
|
||||
binary_search(half_i + 1, max_i, xs, needle)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_two_sums(xs: &mut Vec<i64>) -> usize {
|
||||
let mut found: HashSet<i64> = HashSet::new();
|
||||
const T_MIN: i64 = -10000;
|
||||
const T_MAX: i64 = 10000;
|
||||
xs.sort();
|
||||
let mut found: HashSet<i64> = HashSet::new();
|
||||
const T_MIN: i64 = -10000;
|
||||
const T_MAX: i64 = 10000;
|
||||
xs.sort();
|
||||
|
||||
for i in 0..xs.len() {
|
||||
let a: i64 = xs[i];
|
||||
let b_min = T_MIN - a;
|
||||
let b_max = T_MAX - a;
|
||||
let i_min = binary_search(i + 1, xs.len() - 1, &xs, b_min);
|
||||
let i_max = binary_search(i + 1, xs.len() - 1, &xs, b_max);
|
||||
for i in 0..xs.len() {
|
||||
let a: i64 = xs[i];
|
||||
let b_min = T_MIN - a;
|
||||
let b_max = T_MAX - a;
|
||||
let i_min = binary_search(i + 1, xs.len() - 1, &xs, b_min);
|
||||
let i_max = binary_search(i + 1, xs.len() - 1, &xs, b_max);
|
||||
|
||||
for i in i_min..(i_max + 1) {
|
||||
let b = xs[i];
|
||||
let t = a + b;
|
||||
if T_MIN <= t && t <= T_MAX {
|
||||
found.insert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
found.len()
|
||||
for i in i_min..(i_max + 1) {
|
||||
let b = xs[i];
|
||||
let t = a + b;
|
||||
if T_MIN <= t && t <= T_MAX {
|
||||
found.insert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
found.len()
|
||||
}
|
||||
|
||||
// fn two_sum(t: i64, xs: &Vec<i64>, ys: &HashSet<i64>) -> bool {
|
||||
|
@ -63,7 +68,7 @@ pub fn find_two_sums(xs: &mut Vec<i64>) -> usize {
|
|||
// for t in -10000..10001 {
|
||||
// if t % 10 == 0 {
|
||||
// println!("{:?}", t);
|
||||
// }
|
||||
// }
|
||||
// if two_sum(t, &xs_min, &xs_max_set) {
|
||||
// r += 1
|
||||
// }
|
||||
|
|
54
src/util.rs
54
src/util.rs
|
@ -1,9 +1,9 @@
|
|||
use crate::jobs::{Job, Jobs};
|
||||
use crate::prims::{Edge, Vertex, WeightedGraph};
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{BufRead, BufReader, Error, ErrorKind};
|
||||
use std::vec::Vec;
|
||||
use crate::jobs::{Job, Jobs};
|
||||
use crate::prims::{WeightedGraph, Edge};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Graph {
|
||||
|
@ -163,28 +163,44 @@ pub fn read_jobs(path: &str) -> Result<Jobs, io::Error> {
|
|||
}
|
||||
|
||||
pub fn read_weighted_graph(path: &str) -> Result<WeightedGraph, io::Error> {
|
||||
let g = Vec::new();
|
||||
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 nodes = line.split_whitespace();
|
||||
let n_nodes: usize = nodes.next().unwrap().parse().unwrap();
|
||||
let n_edges: usize = nodes.next().unwrap().parse().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();
|
||||
|
||||
println!("{:?} {:?}", n_nodes, n_edges);
|
||||
// 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 = Job {
|
||||
// weight: weight,
|
||||
// length: length,
|
||||
// };
|
||||
// jobs.push(job);
|
||||
// }
|
||||
for i in 0..n_nodes {
|
||||
let node = 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 = Edge {
|
||||
weight: weight,
|
||||
source_id: id_a,
|
||||
target_id: id_b,
|
||||
};
|
||||
g[id_a].edges.push(edge);
|
||||
|
||||
let edge = Edge {
|
||||
weight: weight,
|
||||
source_id: id_b,
|
||||
target_id: id_a,
|
||||
};
|
||||
g[id_b].edges.push(edge);
|
||||
}
|
||||
|
||||
Ok(g)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue