Skip to content

Commit

Permalink
Merge remote-tracking branch 'public/test/knapsack/dynamic' into test…
Browse files Browse the repository at this point in the history
…/temp
  • Loading branch information
FiveMovesAhead committed May 16, 2024
2 parents 7232782 + a383f49 commit 2c02dea
Show file tree
Hide file tree
Showing 8 changed files with 368 additions and 1 deletion.
73 changes: 73 additions & 0 deletions tig-algorithms/src/knapsack/dynamic/benchmarker_outbound.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*!
Copyright 2024 Uncharted Trading Limited
Licensed under the TIG Benchmarker Outbound Game License v1.0 (the "License"); you
may not use this file except in compliance with the License. You may obtain a copy
of the License at
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
*/

use tig_challenges::knapsack::*;

pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> {
let max_weight = challenge.max_weight;
let min_value = challenge.min_value;
let num_items = challenge.difficulty.num_items;

// Sort items by value-to-weight ratio in descending order
let mut sorted_items: Vec<usize> = (0..num_items).collect();
sorted_items.sort_by(|&a, &b| {
let ratio_a = challenge.values[a] as f64 / challenge.weights[a] as f64;
let ratio_b = challenge.values[b] as f64 / challenge.weights[b] as f64;
ratio_b.partial_cmp(&ratio_a).unwrap()
});

// Initialize combinations with a single empty combo
let mut combinations: Vec<(Vec<bool>, u32, u32)> = vec![(vec![false; num_items], 0, 0)];

let mut items = Vec::new();
for &item in &sorted_items {
// Create new combos with the current item
let mut new_combinations: Vec<(Vec<bool>, u32, u32)> = combinations
.iter()
.map(|(combo, value, weight)| {
let mut new_combo = combo.clone();
new_combo[item] = true;
(
new_combo,
value + challenge.values[item],
weight + challenge.weights[item],
)
})
.filter(|&(_, _, weight)| weight <= max_weight) // Keep only combos within weight limit
.collect();

// Check if any new combination meets the minimum value requirement
if let Some((combo, _, _)) = new_combinations
.iter()
.find(|&&(_, value, _)| value >= min_value)
{
items = combo
.iter()
.enumerate()
.filter_map(|(i, &included)| if included { Some(i) } else { None })
.collect();
break;
}

// Merge new_combinations with existing combinations
combinations.append(&mut new_combinations);

// Deduplicate combinations by keeping the highest value for each weight
combinations.sort_by(|a, b| a.2.cmp(&b.2).then_with(|| b.1.cmp(&a.1))); // Sort by weight, then by value
combinations.dedup_by(|a, b| a.2 == b.2 && a.1 <= b.1); // Deduplicate by weight, keeping highest value
}

Ok(Some(Solution { items }))
}
73 changes: 73 additions & 0 deletions tig-algorithms/src/knapsack/dynamic/commercial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*!
Copyright 2024 Uncharted Trading Limited
Licensed under the TIG Commercial License v1.0 (the "License"); you
may not use this file except in compliance with the License. You may obtain a copy
of the License at
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
*/

use tig_challenges::knapsack::*;

pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> {
let max_weight = challenge.max_weight;
let min_value = challenge.min_value;
let num_items = challenge.difficulty.num_items;

// Sort items by value-to-weight ratio in descending order
let mut sorted_items: Vec<usize> = (0..num_items).collect();
sorted_items.sort_by(|&a, &b| {
let ratio_a = challenge.values[a] as f64 / challenge.weights[a] as f64;
let ratio_b = challenge.values[b] as f64 / challenge.weights[b] as f64;
ratio_b.partial_cmp(&ratio_a).unwrap()
});

// Initialize combinations with a single empty combo
let mut combinations: Vec<(Vec<bool>, u32, u32)> = vec![(vec![false; num_items], 0, 0)];

let mut items = Vec::new();
for &item in &sorted_items {
// Create new combos with the current item
let mut new_combinations: Vec<(Vec<bool>, u32, u32)> = combinations
.iter()
.map(|(combo, value, weight)| {
let mut new_combo = combo.clone();
new_combo[item] = true;
(
new_combo,
value + challenge.values[item],
weight + challenge.weights[item],
)
})
.filter(|&(_, _, weight)| weight <= max_weight) // Keep only combos within weight limit
.collect();

// Check if any new combination meets the minimum value requirement
if let Some((combo, _, _)) = new_combinations
.iter()
.find(|&&(_, value, _)| value >= min_value)
{
items = combo
.iter()
.enumerate()
.filter_map(|(i, &included)| if included { Some(i) } else { None })
.collect();
break;
}

// Merge new_combinations with existing combinations
combinations.append(&mut new_combinations);

// Deduplicate combinations by keeping the highest value for each weight
combinations.sort_by(|a, b| a.2.cmp(&b.2).then_with(|| b.1.cmp(&a.1))); // Sort by weight, then by value
combinations.dedup_by(|a, b| a.2 == b.2 && a.1 <= b.1); // Deduplicate by weight, keeping highest value
}

Ok(Some(Solution { items }))
}
73 changes: 73 additions & 0 deletions tig-algorithms/src/knapsack/dynamic/inbound.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*!
Copyright 2024 Uncharted Trading Limited
Licensed under the TIG Inbound Game License v1.0 or (at your option) any later
version (the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
*/

use tig_challenges::knapsack::*;

pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> {
let max_weight = challenge.max_weight;
let min_value = challenge.min_value;
let num_items = challenge.difficulty.num_items;

// Sort items by value-to-weight ratio in descending order
let mut sorted_items: Vec<usize> = (0..num_items).collect();
sorted_items.sort_by(|&a, &b| {
let ratio_a = challenge.values[a] as f64 / challenge.weights[a] as f64;
let ratio_b = challenge.values[b] as f64 / challenge.weights[b] as f64;
ratio_b.partial_cmp(&ratio_a).unwrap()
});

// Initialize combinations with a single empty combo
let mut combinations: Vec<(Vec<bool>, u32, u32)> = vec![(vec![false; num_items], 0, 0)];

let mut items = Vec::new();
for &item in &sorted_items {
// Create new combos with the current item
let mut new_combinations: Vec<(Vec<bool>, u32, u32)> = combinations
.iter()
.map(|(combo, value, weight)| {
let mut new_combo = combo.clone();
new_combo[item] = true;
(
new_combo,
value + challenge.values[item],
weight + challenge.weights[item],
)
})
.filter(|&(_, _, weight)| weight <= max_weight) // Keep only combos within weight limit
.collect();

// Check if any new combination meets the minimum value requirement
if let Some((combo, _, _)) = new_combinations
.iter()
.find(|&&(_, value, _)| value >= min_value)
{
items = combo
.iter()
.enumerate()
.filter_map(|(i, &included)| if included { Some(i) } else { None })
.collect();
break;
}

// Merge new_combinations with existing combinations
combinations.append(&mut new_combinations);

// Deduplicate combinations by keeping the highest value for each weight
combinations.sort_by(|a, b| a.2.cmp(&b.2).then_with(|| b.1.cmp(&a.1))); // Sort by weight, then by value
combinations.dedup_by(|a, b| a.2 == b.2 && a.1 <= b.1); // Deduplicate by weight, keeping highest value
}

Ok(Some(Solution { items }))
}
73 changes: 73 additions & 0 deletions tig-algorithms/src/knapsack/dynamic/innovator_outbound.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*!
Copyright 2024 Uncharted Trading Limited
Licensed under the TIG Innovator Outbound Game License v1.0 (the "License"); you
may not use this file except in compliance with the License. You may obtain a copy
of the License at
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
*/

use tig_challenges::knapsack::*;

pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> {
let max_weight = challenge.max_weight;
let min_value = challenge.min_value;
let num_items = challenge.difficulty.num_items;

// Sort items by value-to-weight ratio in descending order
let mut sorted_items: Vec<usize> = (0..num_items).collect();
sorted_items.sort_by(|&a, &b| {
let ratio_a = challenge.values[a] as f64 / challenge.weights[a] as f64;
let ratio_b = challenge.values[b] as f64 / challenge.weights[b] as f64;
ratio_b.partial_cmp(&ratio_a).unwrap()
});

// Initialize combinations with a single empty combo
let mut combinations: Vec<(Vec<bool>, u32, u32)> = vec![(vec![false; num_items], 0, 0)];

let mut items = Vec::new();
for &item in &sorted_items {
// Create new combos with the current item
let mut new_combinations: Vec<(Vec<bool>, u32, u32)> = combinations
.iter()
.map(|(combo, value, weight)| {
let mut new_combo = combo.clone();
new_combo[item] = true;
(
new_combo,
value + challenge.values[item],
weight + challenge.weights[item],
)
})
.filter(|&(_, _, weight)| weight <= max_weight) // Keep only combos within weight limit
.collect();

// Check if any new combination meets the minimum value requirement
if let Some((combo, _, _)) = new_combinations
.iter()
.find(|&&(_, value, _)| value >= min_value)
{
items = combo
.iter()
.enumerate()
.filter_map(|(i, &included)| if included { Some(i) } else { None })
.collect();
break;
}

// Merge new_combinations with existing combinations
combinations.append(&mut new_combinations);

// Deduplicate combinations by keeping the highest value for each weight
combinations.sort_by(|a, b| a.2.cmp(&b.2).then_with(|| b.1.cmp(&a.1))); // Sort by weight, then by value
combinations.dedup_by(|a, b| a.2 == b.2 && a.1 <= b.1); // Deduplicate by weight, keeping highest value
}

Ok(Some(Solution { items }))
}
2 changes: 2 additions & 0 deletions tig-algorithms/src/knapsack/dynamic/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod benchmarker_outbound;
pub use benchmarker_outbound::solve_challenge;
73 changes: 73 additions & 0 deletions tig-algorithms/src/knapsack/dynamic/open_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*!
Copyright 2024 Uncharted Trading Limited
Licensed under the TIG Open Data License v1.0 or (at your option) any later version
(the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
*/

use tig_challenges::knapsack::*;

pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result<Option<Solution>> {
let max_weight = challenge.max_weight;
let min_value = challenge.min_value;
let num_items = challenge.difficulty.num_items;

// Sort items by value-to-weight ratio in descending order
let mut sorted_items: Vec<usize> = (0..num_items).collect();
sorted_items.sort_by(|&a, &b| {
let ratio_a = challenge.values[a] as f64 / challenge.weights[a] as f64;
let ratio_b = challenge.values[b] as f64 / challenge.weights[b] as f64;
ratio_b.partial_cmp(&ratio_a).unwrap()
});

// Initialize combinations with a single empty combo
let mut combinations: Vec<(Vec<bool>, u32, u32)> = vec![(vec![false; num_items], 0, 0)];

let mut items = Vec::new();
for &item in &sorted_items {
// Create new combos with the current item
let mut new_combinations: Vec<(Vec<bool>, u32, u32)> = combinations
.iter()
.map(|(combo, value, weight)| {
let mut new_combo = combo.clone();
new_combo[item] = true;
(
new_combo,
value + challenge.values[item],
weight + challenge.weights[item],
)
})
.filter(|&(_, _, weight)| weight <= max_weight) // Keep only combos within weight limit
.collect();

// Check if any new combination meets the minimum value requirement
if let Some((combo, _, _)) = new_combinations
.iter()
.find(|&&(_, value, _)| value >= min_value)
{
items = combo
.iter()
.enumerate()
.filter_map(|(i, &included)| if included { Some(i) } else { None })
.collect();
break;
}

// Merge new_combinations with existing combinations
combinations.append(&mut new_combinations);

// Deduplicate combinations by keeping the highest value for each weight
combinations.sort_by(|a, b| a.2.cmp(&b.2).then_with(|| b.1.cmp(&a.1))); // Sort by weight, then by value
combinations.dedup_by(|a, b| a.2 == b.2 && a.1 <= b.1); // Deduplicate by weight, keeping highest value
}

Ok(Some(Solution { items }))
}
2 changes: 1 addition & 1 deletion tig-algorithms/src/knapsack/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// c003_a001 placeholder
pub mod dynamic;
// c003_a002 placeholder
// c003_a003 placeholder
// c003_a004 placeholder
Expand Down
Binary file added tig-algorithms/wasm/knapsack/dynamic.wasm
Binary file not shown.

0 comments on commit 2c02dea

Please sign in to comment.