From 8c0449e2abd080fc7e8ed138eec00f652b9aba46 Mon Sep 17 00:00:00 2001 From: FiveMovesAhead Date: Mon, 1 Dec 2025 15:23:29 +0000 Subject: [PATCH] Submitted knapsack/kp_annealing --- .../src/knapsack/kp_annealing/README.md | 23 +++ .../src/knapsack/kp_annealing/mod.rs | 151 ++++++++++++++++++ tig-algorithms/src/knapsack/mod.rs | 3 +- 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 tig-algorithms/src/knapsack/kp_annealing/README.md create mode 100644 tig-algorithms/src/knapsack/kp_annealing/mod.rs diff --git a/tig-algorithms/src/knapsack/kp_annealing/README.md b/tig-algorithms/src/knapsack/kp_annealing/README.md new file mode 100644 index 00000000..16240fc4 --- /dev/null +++ b/tig-algorithms/src/knapsack/kp_annealing/README.md @@ -0,0 +1,23 @@ +# TIG Code Submission + +## Submission Details + +* **Challenge Name:** knapsack +* **Algorithm Name:** kp_annealing +* **Copyright:** 2024 CodeAlchemist +* **Identity of Submitter:** CodeAlchemist +* **Identity of Creator of Algorithmic Method:** null +* **Unique Algorithm Identifier (UAI):** null + +## License + +The files in this folder are under the following licenses: +* TIG Benchmarker Outbound License +* TIG Commercial License +* TIG Inbound Game License +* TIG Innovator Outbound Game License +* TIG Open Data License +* TIG THV Game License + +Copies of the licenses can be obtained at: +https://github.com/tig-foundation/tig-monorepo/tree/main/docs/licenses \ No newline at end of file diff --git a/tig-algorithms/src/knapsack/kp_annealing/mod.rs b/tig-algorithms/src/knapsack/kp_annealing/mod.rs new file mode 100644 index 00000000..fd4b5e50 --- /dev/null +++ b/tig-algorithms/src/knapsack/kp_annealing/mod.rs @@ -0,0 +1,151 @@ +use anyhow::{anyhow, Result}; +use serde_json::{Map, Value}; +use tig_challenges::knapsack::*; + + +pub fn solve_challenge( + challenge: &Challenge, + save_solution: &dyn Fn(&Solution) -> Result<()>, + hyperparameters: &Option>, +) -> Result<()> { + Err(anyhow!("This algorithm is no longer compatible.")) +} + +// Old code that is no longer compatible +#[cfg(none)] +mod dead_code { + // TIG's UI uses the pattern `tig_challenges::` to automatically detect your algorithm's challenge + use anyhow::Result; + use rand::{SeedableRng, Rng, rngs::SmallRng}; + use tig_challenges::knapsack::*; + + fn calculate_value_change( + current_solution: &[usize], + item: usize, + values: &[u32], + interaction_values: &[Vec] + ) -> i32 { + let mut value_change = values[item] as i32; + + for &other_item in current_solution { + value_change += interaction_values[item][other_item]; + } + + value_change + } + + fn greedy_initial_solution(challenge: &SubInstance) -> Vec { + let n = challenge.weights.len(); + let mut solution = Vec::new(); + let mut current_weight = 0; + + let mut items: Vec<(usize, f64)> = (0..n) + .map(|i| { + let total_value = challenge.values[i] as i32 + challenge.interaction_values[i].iter().sum::(); + let ratio = total_value as f64 / challenge.weights[i] as f64; + (i, ratio) + }) + .collect(); + + items.sort_unstable_by(|a, b| b.1.partial_cmp(&a.1).unwrap()); + + for (i, _) in items { + if current_weight + challenge.weights[i] <= challenge.max_weight { + solution.push(i); + current_weight += challenge.weights[i]; + } + } + + solution.sort_unstable(); + solution + } + + + pub fn solve_challenge(challenge: &Challenge) -> anyhow::Result> { + let mut solution = Solution { + sub_solutions: Vec::new(), + }; + for sub_instance in &challenge.sub_instances { + match solve_sub_instance(sub_instance)? { + Some(sub_solution) => solution.sub_solutions.push(sub_solution), + None => return Ok(None), + } + } + Ok(Some(solution)) + } + + pub fn solve_sub_instance(challenge: &SubInstance) -> Result> { + { + let coef = vec![7.685029664028169e-08, -0.00026933405380081394, 0.39570553839776795, 4.133197036353228, 8025.3579356210785]; + + let mut lim = 0.0; + let mut val = 1.0; + for i in (0..coef.len()).rev(){ + lim += coef[i] * val; + val *= challenge.num_items as f32; + } + + lim = lim * (1.0 as f32 + (challenge.difficulty.better_than_baseline as f32)/1000.0); + + if challenge.baseline_value as f32 > lim { + return Ok(None); + } + } + + let mut current_solution = greedy_initial_solution(challenge); + let mut current_value = calculate_total_value(¤t_solution, &challenge.values, &challenge.interaction_values); + let mut current_weight: u32 = current_solution.iter().map(|&i| challenge.weights[i]).sum(); + let mut rng = SmallRng::seed_from_u64(u64::from_le_bytes(challenge.seed[..8].try_into()?)); + + let mut positions: Vec = vec![-1; challenge.num_items]; + for (idx, &item) in current_solution.iter().enumerate() { + positions[item] = idx as i32; + } + + let mut temperature = 500.0; + while temperature > 1.0 { + for i in 0..challenge.num_items { + let pos = positions[i]; + if pos >= 0 { + let new_weight = current_weight - challenge.weights[i]; + let new_value = current_value as i32 - calculate_value_change(¤t_solution, i, &challenge.values, &challenge.interaction_values); + + let delta = new_value - current_value as i32; + if delta > 0 || rng.gen::() < (delta as f64 / temperature).exp() { + let last_idx = current_solution.len() - 1; + if pos as usize != last_idx { + current_solution.swap(pos as usize, last_idx); + positions[current_solution[pos as usize]] = pos; + } + current_solution.pop(); + positions[i] = -1; + current_value = new_value as u32; + current_weight = new_weight; + } + } else if current_weight + challenge.weights[i] <= challenge.max_weight { + let new_weight = current_weight + challenge.weights[i]; + let new_value = current_value as i32 + calculate_value_change(¤t_solution, i, &challenge.values, &challenge.interaction_values); + + let delta = (new_value - current_value as i32); + if delta > 0 || rng.gen::() < (delta as f64 / temperature).exp() { + positions[i] = current_solution.len() as i32; + current_solution.push(i); + current_value = new_value as u32; + current_weight = new_weight; + + } + } + + if current_value as i32 >= challenge.baseline_value as i32 && current_weight <= challenge.max_weight { + return Ok(Some(SubSolution { items: current_solution })); + } + } + temperature *= 0.985; + } + Ok(None) + } +} + +pub fn help() { + println!("No help information available."); +} diff --git a/tig-algorithms/src/knapsack/mod.rs b/tig-algorithms/src/knapsack/mod.rs index 33ddf59d..ace33970 100644 --- a/tig-algorithms/src/knapsack/mod.rs +++ b/tig-algorithms/src/knapsack/mod.rs @@ -122,7 +122,8 @@ // c003_a062 -// c003_a063 +pub mod kp_annealing; +pub use kp_annealing as c003_a063; // c003_a064