diff --git a/submissions/Daanish-Mehra/.DS_Store b/submissions/Daanish-Mehra/.DS_Store new file mode 100644 index 0000000..49f3d34 Binary files /dev/null and b/submissions/Daanish-Mehra/.DS_Store differ diff --git a/submissions/Daanish-Mehra/README.md b/submissions/Daanish-Mehra/README.md new file mode 100644 index 0000000..ba0d9af --- /dev/null +++ b/submissions/Daanish-Mehra/README.md @@ -0,0 +1,104 @@ +# Evolution Arena - Hugging Face Powered + +A genetic algorithm game that leverages **multiple Hugging Face models**, datasets, and Spaces for LLM-guided optimization. + +## 🤖 Hugging Face Integration + +### Multiple Models +- **google/flan-t5-base** - For bitstring problems +- **microsoft/DialoGPT-small** - For permutation problems +- **facebook/blenderbot-400M-distill** - For expression problems +- **google/flan-t5-small** - Default fallback model + +### HF Datasets +- Converts 100+ optimization problems to HF Dataset format +- Includes metadata, difficulty scores, and tags +- Shareable and discoverable on Hugging Face Hub + +### HF Spaces +- Full Gradio web interface +- Interactive problem selection and visualization +- Real-time evolution progress tracking + +## 🚀 Quick Start + +```bash +pip install -r reqs.txt +python3 main.py +``` + +### Available Modes + +1. **Fast Learning Arena** - Basic optimization +2. **Real Evolution Arena** - Full LLM integration +3. **Custom Challenge** - Interactive problem selection +4. **Multi-Model Demo** - Test different HF models +5. **Gradio Space** - Web interface + +## 📁 Project Structure + +``` +lib/ +├── ai/ +│ ├── llm.py # Original single model +│ └── multi_model_llm.py # Multiple HF models +├── data/ +│ └── hf_dataset.py # HF Dataset management +├── algo/ +│ └── ga.py # Genetic Algorithm +├── rl/ +│ ├── rl_agent.py # RL agent +│ └── rl_loop.py # RL utilities +└── problems/ + └── probs.json # 100 optimization problems +``` + +## 🎮 Usage Examples + +### Multi-Model Testing +```bash +python3 main.py +# Choose option 4 +``` + +### Gradio Space +```bash +python3 main.py +# Choose option 5 +# Or directly: python3 gradio_space.py +``` + +### Dataset Stats +```python +from lib.data.hf_dataset import HFDatasetManager +manager = HFDatasetManager() +print(manager.get_stats()) +``` + +## 🔧 Dependencies + +Core Hugging Face: +- transformers +- datasets +- huggingface_hub +- gradio + +Scientific: +- torch, numpy, scipy +- matplotlib, pandas +- deap, networkx + +## 🎯 Features + +- 100+ optimization problems +- Multiple specialized HF models +- HF Dataset integration +- Interactive web interface +- Real-time visualization +- RL-guided algorithm selection + +## �� Problems + +Bitstring, permutation, expression, constraint, and combinatorial optimization problems across easy to expert difficulty levels. + +That's it. diff --git a/submissions/Daanish-Mehra/app.py b/submissions/Daanish-Mehra/app.py new file mode 100644 index 0000000..e3f2970 --- /dev/null +++ b/submissions/Daanish-Mehra/app.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 +""" +Evolution Arena - Hugging Face Space +A genetic algorithm game powered by multiple HF models +""" + +from gradio_space import create_interface + +if __name__ == "__main__": + # This is the entry point for Hugging Face Spaces + demo = create_interface() + demo.launch() diff --git a/submissions/Daanish-Mehra/custom_arena.py b/submissions/Daanish-Mehra/custom_arena.py new file mode 100644 index 0000000..53c9d0b --- /dev/null +++ b/submissions/Daanish-Mehra/custom_arena.py @@ -0,0 +1,165 @@ +import numpy as np +import json +import random +import time +from lib.algo.ga import EnhancedGAEngine +from lib.ai.llm import EnhancedLLMSolver +from lib.rl.rl_loop import get_reward, update_rl_state, init_rl_state + +class CustomArena: + def __init__(self, difficulty, problem_types): + self.problems = self.load_problems() + self.score = 0 + self.level = 1 + self.difficulty = difficulty + self.problem_types = problem_types + self.unlocked = self.get_unlocked_problems() + self.rl_state = init_rl_state() + self.fitness_history = [] + self.problem_history = [] + + print("=" * 60) + print("CUSTOM CHALLENGE ARENA - TAILORED EVOLUTION") + print("=" * 60) + print("Initializing LLM Solver...") + self.llm_solver = EnhancedLLMSolver() + print("Ready for custom challenge!") + print() + + def load_problems(self): + with open('lib/problems/probs.json', 'r') as f: + return json.load(f) + + def get_unlocked_problems(self): + if self.difficulty == 1: + return set(range(1, 21)) + elif self.difficulty == 2: + return set(range(21, 51)) + elif self.difficulty == 3: + return set(range(51, 81)) + elif self.difficulty == 4: + return set(range(81, 101)) + else: + return set(range(1, 101)) + + def filter_problems_by_type(self, problem): + if "all" in self.problem_types: + return True + + type_map = { + 1: "bitstring", + 2: "permutation", + 3: "expression", + 4: "constraint", + 5: "combinatorial" + } + + for t in self.problem_types: + if problem["type"] == type_map[t]: + return True + return False + + def run_session(self, num_problems=5): + print(f"Starting {num_problems} problem custom challenge...") + print("=" * 60) + + available_problems = [p for p in self.problems if p["id"] in self.unlocked and self.filter_problems_by_type(p)] + + if not available_problems: + print("No problems available with your criteria!") + return 0 + + for i in range(num_problems): + problem = random.choice(available_problems) + + print(f"\nPROBLEM {i+1}/{num_problems}") + print("-" * 40) + print(f"Name: {problem['name']}") + print(f"Type: {problem['type'].upper()}") + print(f"Difficulty: {problem['difficulty'].upper()}") + print(f"Description: {problem['description']}") + print() + + result = self.solve_problem(problem) + self.score += result['score'] + self.fitness_history.append(result['best_fitness']) + self.problem_history.append(problem['name']) + + print(f"BEST FITNESS: {result['best_fitness']:.2f}") + print(f"SCORE EARNED: {result['score']}") + print(f"TOTAL SCORE: {self.score}") + print(f"LLM EFFECTIVENESS: {self.rl_state['llm_effectiveness']:.3f}") + + if result['score'] > 50: + self.level += 1 + print(f"LEVEL UP! You're getting better!") + + print("-" * 40) + + self.show_final_results() + return self.score + + def solve_problem(self, problem): + engine = EnhancedGAEngine(problem) + best_fitness = 0 + generations = 10 + gen_fitness = [] + + print("Evolution Progress:") + print("Generation | Fitness | Algorithm | Progress") + print("-" * 50) + + for gen in range(generations): + fitness = engine.get_fitness(engine.pop) + current_best = max(fitness) + best_fitness = max(best_fitness, current_best) + gen_fitness.append(current_best) + + if random.random() < self.rl_state['llm_effectiveness']: + print(f"Gen {gen:2d} | {current_best:6.2f} | LLM | ", end="") + llm_candidates = self.llm_solver.get_candidates(problem, engine.pop, 3) + engine.pop = engine.next_gen(engine.pop, llm_candidates) + llm_used = "LLM" + else: + print(f"Gen {gen:2d} | {current_best:6.2f} | GA | ", end="") + engine.pop = engine.next_gen(engine.pop) + llm_used = "GA" + + progress_bar = "█" * int((gen / generations) * 20) + "░" * (20 - int((gen / generations) * 20)) + print(f"[{progress_bar}]") + + time.sleep(0.5) + + print("-" * 50) + print(f"Evolution complete! Best fitness: {best_fitness:.2f}") + + score = int(best_fitness * 10) + reward = get_reward([0], [best_fitness]) + self.rl_state = update_rl_state(self.rl_state, reward, problem['id']) + + return { + 'best_fitness': best_fitness, + 'score': score, + 'generations': generations + } + + def show_final_results(self): + print("\n" + "=" * 60) + print("CUSTOM CHALLENGE COMPLETE - FINAL RESULTS") + print("=" * 60) + print(f"Total Score: {self.score}") + print(f"Problems Solved: {len(self.problem_history)}") + print(f"Final Level: {self.level}") + print(f"LLM Effectiveness: {self.rl_state['llm_effectiveness']:.3f}") + print(f"Average Reward: {self.rl_state['avg_reward']:.2f}") + print() + + print("Problem Performance:") + for i, (name, fitness) in enumerate(zip(self.problem_history, self.fitness_history)): + print(f" {i+1}. {name}: {fitness:.2f}") + + print("\n" + "=" * 60) + +if __name__ == "__main__": + arena = CustomArena(1, [1, 2]) + arena.run_session(5) diff --git a/submissions/Daanish-Mehra/fast_one.py b/submissions/Daanish-Mehra/fast_one.py new file mode 100644 index 0000000..171c65b --- /dev/null +++ b/submissions/Daanish-Mehra/fast_one.py @@ -0,0 +1,130 @@ +import numpy as np +import json +import random +import time +from lib.algo.ga import EnhancedGAEngine +from lib.ai.llm import EnhancedLLMSolver +from lib.rl.rl_loop import get_reward, update_rl_state, init_rl_state + +class FastLearningArena: + def __init__(self): + self.problems = self.load_problems() + self.score = 0 + self.level = 1 + self.unlocked = set(range(1, 21)) + self.rl_state = init_rl_state() + self.fitness_history = [] + self.problem_history = [] + print("=" * 60) + print("FAST LEARNING ARENA - LLM GUIDED EVOLUTION") + print("=" * 60) + print("Initializing LLM Solver...") + self.llm_solver = EnhancedLLMSolver() + print("Ready to evolve!") + print() + + def load_problems(self): + with open('lib/problems/probs.json', 'r') as f: + return json.load(f) + + def run_session(self, num_problems=5): + print(f"Starting {num_problems} problem evolution session...") + print("=" * 60) + + for i in range(num_problems): + problem_id = random.choice(list(self.unlocked)) + problem = self.problems[problem_id - 1] + + print(f"\nPROBLEM {i+1}/{num_problems}") + print("-" * 40) + print(f"Name: {problem['name']}") + print(f"Type: {problem['type'].upper()}") + print(f"Difficulty: {problem['difficulty'].upper()}") + print(f"Description: {problem['description']}") + print() + + result = self.solve_problem(problem) + self.score += result['score'] + self.fitness_history.append(result['best_fitness']) + self.problem_history.append(problem['name']) + + print(f"BEST FITNESS: {result['best_fitness']:.2f}") + print(f"SCORE EARNED: {result['score']}") + print(f"TOTAL SCORE: {self.score}") + print(f"LLM EFFECTIVENESS: {self.rl_state['llm_effectiveness']:.3f}") + + if result['score'] > 50: + self.level += 1 + new_problems = list(range(21, min(41, 21 + self.level * 5))) + self.unlocked.update(new_problems) + print(f"LEVEL UP! Unlocked {len(new_problems)} new problems") + + print("-" * 40) + + self.show_final_results() + return self.score + + def solve_problem(self, problem): + engine = EnhancedGAEngine(problem) + best_fitness = 0 + generations = 10 + gen_fitness = [] + + print("Evolution Progress:") + print("Generation | Fitness | Algorithm | Progress") + print("-" * 50) + + for gen in range(generations): + fitness = engine.get_fitness(engine.pop) + current_best = max(fitness) + best_fitness = max(best_fitness, current_best) + gen_fitness.append(current_best) + + if random.random() < self.rl_state['llm_effectiveness']: + print(f"Gen {gen:2d} | {current_best:6.2f} | LLM | ", end="") + llm_candidates = self.llm_solver.get_candidates(problem, engine.pop, 3) + engine.pop = engine.next_gen(engine.pop, llm_candidates) + llm_used = "LLM" + else: + print(f"Gen {gen:2d} | {current_best:6.2f} | GA | ", end="") + engine.pop = engine.next_gen(engine.pop) + llm_used = "GA" + + progress_bar = "█" * int((gen / generations) * 20) + "░" * (20 - int((gen / generations) * 20)) + print(f"[{progress_bar}]") + + time.sleep(0.5) + + print("-" * 50) + print(f"Evolution complete! Best fitness: {best_fitness:.2f}") + + score = int(best_fitness * 10) + reward = get_reward([0], [best_fitness]) + self.rl_state = update_rl_state(self.rl_state, reward, problem['id']) + + return { + 'best_fitness': best_fitness, + 'score': score, + 'generations': generations + } + + def show_final_results(self): + print("\n" + "=" * 60) + print("SESSION COMPLETE - FINAL RESULTS") + print("=" * 60) + print(f"Total Score: {self.score}") + print(f"Problems Solved: {len(self.problem_history)}") + print(f"Final Level: {self.level}") + print(f"LLM Effectiveness: {self.rl_state['llm_effectiveness']:.3f}") + print(f"Average Reward: {self.rl_state['avg_reward']:.2f}") + print() + + print("Problem Performance:") + for i, (name, fitness) in enumerate(zip(self.problem_history, self.fitness_history)): + print(f" {i+1}. {name}: {fitness:.2f}") + + print("\n" + "=" * 60) + +if __name__ == "__main__": + arena = FastLearningArena() + arena.run_session(5) diff --git a/submissions/Daanish-Mehra/gradio_space.py b/submissions/Daanish-Mehra/gradio_space.py new file mode 100644 index 0000000..9a1eedd --- /dev/null +++ b/submissions/Daanish-Mehra/gradio_space.py @@ -0,0 +1,195 @@ +import gradio as gr +import json +import numpy as np +from lib.ai.multi_model_llm import MultiModelLLMSolver +from lib.algo.ga import EnhancedGAEngine +from lib.data.hf_dataset import HFDatasetManager + +class EvolutionArenaGradio: + def __init__(self): + print(" Loading Evolution Arena for Hugging Face Spaces...") + self.llm_solver = MultiModelLLMSolver() + self.dataset_manager = HFDatasetManager() + + def run_evolution(self, problem_name, num_generations, population_size, use_llm): + try: + # Find problem in dataset + problems_data = self.dataset_manager.dataset.filter(lambda x: x["name"] == problem_name) + if len(problems_data) == 0: + return "Problem not found!", "", "" + + problem = problems_data[0] + + # Convert to format expected by GA engine + problem_dict = { + "name": problem["name"], + "type": problem["type"], + "length": problem["length"], + "description": problem["description"], + "difficulty": problem["difficulty"] + } + + # Run evolution + ga_engine = EnhancedGAEngine(problem_dict) + ga_engine.size = population_size + + results = [] + fitness_history = [] + + for gen in range(num_generations): + # Evaluate fitness + fitness = ga_engine.get_fitness(ga_engine.pop) + best_fitness = np.max(fitness) + avg_fitness = np.mean(fitness) + + fitness_history.append({ + "generation": gen, + "best_fitness": best_fitness, + "avg_fitness": avg_fitness + }) + + results.append(f"Gen {gen}: Best={best_fitness:.2f}, Avg={avg_fitness:.2f}") + + # Generate next generation + if use_llm and gen % 3 == 0: # Use LLM every 3 generations + llm_candidates = self.llm_solver.get_candidates(problem_dict, ga_engine.pop, 3) + ga_engine.pop = ga_engine.next_gen(ga_engine.pop, llm_candidates) + results.append(f" → Used LLM to generate candidates") + else: + ga_engine.pop = ga_engine.next_gen(ga_engine.pop) + + # Final results + final_fitness = ga_engine.get_fitness(ga_engine.pop) + best_solution = ga_engine.pop[np.argmax(final_fitness)] + + summary = f""" +## Evolution Complete! + +**Problem**: {problem['name']} ({problem['difficulty']}) +**Type**: {problem['type']} +**Generations**: {num_generations} +**Population Size**: {population_size} +**Used LLM**: {'Yes' if use_llm else 'No'} + +**Final Best Fitness**: {np.max(final_fitness):.2f} +**Best Solution**: {best_solution[:10]}... (truncated) + +**Problem Description**: {problem['description']} + """ + + return "\n".join(results), summary, str(fitness_history) + + except Exception as e: + return f"Error: {str(e)}", "", "" + + def get_problem_info(self, problem_name): + try: + problems_data = self.dataset_manager.dataset.filter(lambda x: x["name"] == problem_name) + if len(problems_data) == 0: + return "Problem not found!" + + problem = problems_data[0] + return f""" +**Name**: {problem['name']} +**Type**: {problem['type']} +**Difficulty**: {problem['difficulty']} +**Length**: {problem['length']} +**Complexity Score**: {problem['complexity_score']} +**Tags**: {', '.join(problem['tags'])} + +**Description**: {problem['description']} + """ + except Exception as e: + return f"Error: {str(e)}" + + def get_dataset_stats(self): + stats = self.dataset_manager.get_stats() + return f""" +# Evolution Arena Dataset Stats + +**Total Problems**: {stats['total_problems']} +**Average Complexity**: {stats['avg_complexity']:.2f} +**Average Length**: {stats['avg_length']:.1f} + +## Problem Types: +{chr(10).join([f"- {k}: {v}" for k, v in stats['types'].items()])} + +## Difficulty Distribution: +{chr(10).join([f"- {k}: {v}" for k, v in stats['difficulties'].items()])} + """ + +def create_interface(): + app = EvolutionArenaGradio() + + # Get list of problem names for dropdown + problem_names = app.dataset_manager.dataset["name"] + + with gr.Blocks(title=" Evolution Arena - Hugging Face Space", theme=gr.themes.Soft()) as demo: + gr.Markdown("# Evolution Arena - LLM-Guided Genetic Algorithms") + gr.Markdown("**Powered by Multiple Hugging Face Models & Datasets**") + + with gr.Tab("🎮 Run Evolution"): + with gr.Row(): + with gr.Column(scale=1): + problem_dropdown = gr.Dropdown( + choices=problem_names, + label="Select Problem", + value=problem_names[0] if problem_names else None + ) + num_generations = gr.Slider(5, 50, value=20, step=1, label="Generations") + population_size = gr.Slider(5, 50, value=20, step=5, label="Population Size") + use_llm = gr.Checkbox(label="Use LLM Assistance", value=True) + + run_btn = gr.Button(" Start Evolution", variant="primary") + + with gr.Column(scale=2): + evolution_log = gr.Textbox( + label="Evolution Progress", + lines=15, + max_lines=20 + ) + + with gr.Row(): + summary_output = gr.Markdown(label="Results Summary") + fitness_data = gr.Textbox(label="Fitness History (JSON)", visible=False) + + with gr.Tab("📋 Problem Info"): + with gr.Row(): + with gr.Column(scale=1): + info_problem_dropdown = gr.Dropdown( + choices=problem_names, + label="Select Problem", + value=problem_names[0] if problem_names else None + ) + info_btn = gr.Button("📖 Get Info") + + with gr.Column(scale=2): + problem_info_output = gr.Markdown() + + with gr.Tab(" Dataset Stats"): + stats_btn = gr.Button("�� Show Dataset Statistics") + stats_output = gr.Markdown() + + # Event handlers + run_btn.click( + app.run_evolution, + inputs=[problem_dropdown, num_generations, population_size, use_llm], + outputs=[evolution_log, summary_output, fitness_data] + ) + + info_btn.click( + app.get_problem_info, + inputs=[info_problem_dropdown], + outputs=[problem_info_output] + ) + + stats_btn.click( + app.get_dataset_stats, + outputs=[stats_output] + ) + + return demo + +if __name__ == "__main__": + demo = create_interface() + demo.launch(share=True) diff --git a/submissions/Daanish-Mehra/lib/ai/__pycache__/llm.cpython-312.pyc b/submissions/Daanish-Mehra/lib/ai/__pycache__/llm.cpython-312.pyc new file mode 100644 index 0000000..c0b9d9a Binary files /dev/null and b/submissions/Daanish-Mehra/lib/ai/__pycache__/llm.cpython-312.pyc differ diff --git a/submissions/Daanish-Mehra/lib/ai/__pycache__/multi_model_llm.cpython-312.pyc b/submissions/Daanish-Mehra/lib/ai/__pycache__/multi_model_llm.cpython-312.pyc new file mode 100644 index 0000000..763cd73 Binary files /dev/null and b/submissions/Daanish-Mehra/lib/ai/__pycache__/multi_model_llm.cpython-312.pyc differ diff --git a/submissions/Daanish-Mehra/lib/ai/llm.py b/submissions/Daanish-Mehra/lib/ai/llm.py new file mode 100644 index 0000000..4aad2e2 --- /dev/null +++ b/submissions/Daanish-Mehra/lib/ai/llm.py @@ -0,0 +1,122 @@ +from transformers import AutoTokenizer, AutoModelForSeq2SeqLM +import torch +import numpy as np +import re +import random + +class EnhancedLLMSolver: + def __init__(self): + self.model_name = "google/flan-t5-small" + self.tokenizer = AutoTokenizer.from_pretrained(self.model_name) + self.model = AutoModelForSeq2SeqLM.from_pretrained(self.model_name) + + def get_candidates(self, problem, pop, max_candidates=5): + try: + prompt = self.make_prompt(problem, pop, max_candidates) + inputs = self.tokenizer(prompt, return_tensors="pt", max_length=512, truncation=True) + outputs = self.model.generate(inputs.input_ids, max_new_tokens=200) + text = self.tokenizer.decode(outputs[0], skip_special_tokens=True) + candidates = self.parse_candidates(text, problem, max_candidates) + if isinstance(candidates, np.ndarray): + candidates = candidates.tolist() + while len(candidates) < max_candidates: + random_candidates = self.make_random(problem, max_candidates - len(candidates)) + candidates.extend(random_candidates) + return candidates[:max_candidates] + except Exception as e: + print(f"LLM generation failed: {e}") + return self.make_random(problem, max_candidates) + + def make_prompt(self, problem, pop, max_candidates=5): + name = problem["name"] + typ = problem["type"] + pop_str = str(pop[:2]) + length = problem.get("length", 5) + return f"solve {name} {typ} problem, current pop: {pop_str}, make {max_candidates} new solutions" + + def parse_candidates(self, text, problem, max_candidates): + problem_type = problem["type"] + if problem_type == "bitstring": + return self.parse_bitstring_candidates(text, problem, max_candidates) + elif problem_type == "permutation": + return self.parse_permutation_candidates(text, problem, max_candidates) + else: + return self.parse_continuous_candidates(text, problem, max_candidates) + + def parse_bitstring_candidates(self, text, problem, max_candidates): + candidates = [] + length = problem["length"] + lines = text.split('\n') + for line in lines: + if '[' in line and ']' in line: + try: + start = line.find('[') + end = line.find(']') + 1 + candidate_str = line[start:end] + candidate = eval(candidate_str) + if isinstance(candidate, list) and len(candidate) == length: + if all(x in [0, 1] for x in candidate): + candidates.append(candidate) + except: + continue + return np.array(candidates) if candidates else np.array([]).reshape(0, length) + + def parse_permutation_candidates(self, text, problem, max_candidates): + candidates = [] + length = problem["length"] + lines = text.split('\n') + for line in lines: + if '[' in line and ']' in line: + try: + start = line.find('[') + end = line.find(']') + 1 + candidate_str = line[start:end] + candidate = eval(candidate_str) + if isinstance(candidate, list) and len(candidate) == length: + if set(candidate) == set(range(length)): + candidates.append(candidate) + except: + continue + return np.array(candidates) if candidates else np.array([]).reshape(0, length) + + def parse_continuous_candidates(self, text, problem, max_candidates): + candidates = [] + length = problem.get("length", 5) + lines = text.split('\n') + for line in lines: + if '[' in line and ']' in line: + try: + start = line.find('[') + end = line.find(']') + 1 + candidate_str = line[start:end] + candidate = eval(candidate_str) + if isinstance(candidate, list) and len(candidate) == length: + candidates.append(candidate) + except: + continue + return np.array(candidates) if candidates else np.array([]).reshape(0, length) + + def make_random(self, problem, num_candidates): + candidates = [] + problem_type = problem["type"] + if problem_type == "bitstring": + length = problem["length"] + for _ in range(num_candidates): + candidate = np.random.randint(0, 2, length).tolist() + candidates.append(candidate) + elif problem_type == "permutation": + length = problem["length"] + for _ in range(num_candidates): + candidate = list(range(length)) + random.shuffle(candidate) + candidates.append(candidate) + elif problem_type == "expression": + for _ in range(num_candidates): + candidate = np.random.rand(5).tolist() + candidates.append(candidate) + else: + length = problem.get("length", 5) + for _ in range(num_candidates): + candidate = np.random.rand(length).tolist() + candidates.append(candidate) + return candidates diff --git a/submissions/Daanish-Mehra/lib/ai/multi_model_llm.py b/submissions/Daanish-Mehra/lib/ai/multi_model_llm.py new file mode 100644 index 0000000..8399ef8 --- /dev/null +++ b/submissions/Daanish-Mehra/lib/ai/multi_model_llm.py @@ -0,0 +1,181 @@ +from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForCausalLM, pipeline +import torch +import numpy as np +import re +import random + +class MultiModelLLMSolver: + def __init__(self): + self.models = { + "bitstring": { + "model_name": "google/flan-t5-base", + "tokenizer": None, + "model": None + }, + "permutation": { + "model_name": "microsoft/DialoGPT-small", + "tokenizer": None, + "model": None + }, + "expression": { + "model_name": "facebook/blenderbot-400M-distill", + "tokenizer": None, + "model": None + }, + "default": { + "model_name": "google/flan-t5-small", + "tokenizer": None, + "model": None + } + } + self.load_models() + + def load_models(self): + print("Loading multiple Hugging Face models...") + for model_type, config in self.models.items(): + try: + if "flan-t5" in config["model_name"]: + config["tokenizer"] = AutoTokenizer.from_pretrained(config["model_name"]) + config["model"] = AutoModelForSeq2SeqLM.from_pretrained(config["model_name"]) + else: + config["tokenizer"] = AutoTokenizer.from_pretrained(config["model_name"]) + config["model"] = AutoModelForCausalLM.from_pretrained(config["model_name"]) + print(f" Loaded {config['model_name']} for {model_type}") + except Exception as e: + print(f" Failed to load {config['model_name']}: {e}") + config["tokenizer"] = None + config["model"] = None + + def get_candidates(self, problem, pop, max_candidates=5): + problem_type = problem["type"] + model_config = self.models.get(problem_type, self.models["default"]) + + if model_config["model"] is None: + return self.make_random(problem, max_candidates) + + try: + prompt = self.make_prompt(problem, pop, max_candidates) + candidates = self.generate_with_model(model_config, prompt, problem, max_candidates) + + while len(candidates) < max_candidates: + random_candidates = self.make_random(problem, max_candidates - len(candidates)) + candidates.extend(random_candidates) + return candidates[:max_candidates] + except Exception as e: + print(f"LLM generation failed with {model_config['model_name']}: {e}") + return self.make_random(problem, max_candidates) + + def generate_with_model(self, model_config, prompt, problem, max_candidates): + tokenizer = model_config["tokenizer"] + model = model_config["model"] + + inputs = tokenizer(prompt, return_tensors="pt", max_length=512, truncation=True) + + with torch.no_grad(): + if "flan-t5" in model_config["model_name"]: + outputs = model.generate(inputs.input_ids, max_new_tokens=200, do_sample=True, temperature=0.7) + else: + outputs = model.generate(inputs.input_ids, max_new_tokens=200, do_sample=True, temperature=0.7, pad_token_id=tokenizer.eos_token_id) + + text = tokenizer.decode(outputs[0], skip_special_tokens=True) + return self.parse_candidates(text, problem, max_candidates) + + def make_prompt(self, problem, pop, max_candidates=5): + name = problem["name"] + typ = problem["type"] + pop_str = str(pop[:2]) + length = problem.get("length", 5) + + if typ == "bitstring": + return f"Generate {max_candidates} bitstring solutions for {name}. Length: {length}. Current: {pop_str}. Format: [1,0,1,0]" + elif typ == "permutation": + return f"Generate {max_candidates} permutation solutions for {name}. Length: {length}. Current: {pop_str}. Format: [2,0,1,3]" + else: + return f"Generate {max_candidates} solutions for {name} {typ} problem. Length: {length}. Current: {pop_str}. Format: [1.0, 2.0, 0.5]" + + def parse_candidates(self, text, problem, max_candidates): + problem_type = problem["type"] + if problem_type == "bitstring": + return self.parse_bitstring_candidates(text, problem, max_candidates) + elif problem_type == "permutation": + return self.parse_permutation_candidates(text, problem, max_candidates) + else: + return self.parse_continuous_candidates(text, problem, max_candidates) + + def parse_bitstring_candidates(self, text, problem, max_candidates): + candidates = [] + length = problem["length"] + lines = text.split('\n') + for line in lines: + if '[' in line and ']' in line: + try: + start = line.find('[') + end = line.find(']') + 1 + candidate_str = line[start:end] + candidate = eval(candidate_str) + if isinstance(candidate, list) and len(candidate) == length: + if all(x in [0, 1] for x in candidate): + candidates.append(candidate) + except: + continue + return candidates + + def parse_permutation_candidates(self, text, problem, max_candidates): + candidates = [] + length = problem["length"] + lines = text.split('\n') + for line in lines: + if '[' in line and ']' in line: + try: + start = line.find('[') + end = line.find(']') + 1 + candidate_str = line[start:end] + candidate = eval(candidate_str) + if isinstance(candidate, list) and len(candidate) == length: + if set(candidate) == set(range(length)): + candidates.append(candidate) + except: + continue + return candidates + + def parse_continuous_candidates(self, text, problem, max_candidates): + candidates = [] + length = problem.get("length", 5) + lines = text.split('\n') + for line in lines: + if '[' in line and ']' in line: + try: + start = line.find('[') + end = line.find(']') + 1 + candidate_str = line[start:end] + candidate = eval(candidate_str) + if isinstance(candidate, list) and len(candidate) == length: + candidates.append(candidate) + except: + continue + return candidates + + def make_random(self, problem, num_candidates): + candidates = [] + problem_type = problem["type"] + if problem_type == "bitstring": + length = problem["length"] + for _ in range(num_candidates): + candidate = np.random.randint(0, 2, length).tolist() + candidates.append(candidate) + elif problem_type == "permutation": + length = problem["length"] + for _ in range(num_candidates): + candidate = list(range(length)) + random.shuffle(candidate) + candidates.append(candidate) + elif problem_type == "expression": + for _ in range(num_candidates): + candidate = np.random.rand(5).tolist() + candidates.append(candidate) + else: + length = problem.get("length", 5) + for _ in range(num_candidates): + candidate = np.random.rand(length).tolist() + candidates.append(candidate) + return candidates diff --git a/submissions/Daanish-Mehra/lib/algo/__pycache__/ga.cpython-312.pyc b/submissions/Daanish-Mehra/lib/algo/__pycache__/ga.cpython-312.pyc new file mode 100644 index 0000000..336170d Binary files /dev/null and b/submissions/Daanish-Mehra/lib/algo/__pycache__/ga.cpython-312.pyc differ diff --git a/submissions/Daanish-Mehra/lib/algo/ga.py b/submissions/Daanish-Mehra/lib/algo/ga.py new file mode 100644 index 0000000..0fc7fb2 --- /dev/null +++ b/submissions/Daanish-Mehra/lib/algo/ga.py @@ -0,0 +1,162 @@ +import numpy as np +import random + +class EnhancedGAEngine: + def __init__(self, problem): + self.problem = problem + self.size = 50 + self.pop = self.make_pop() + + def make_pop(self): + if self.problem["type"] == "bitstring": + return np.random.randint(0, 2, (self.size, self.problem["length"])) + elif self.problem["type"] == "permutation": + result = [] + for i in range(self.size): + perm = list(range(self.problem["length"])) + random.shuffle(perm) + result.append(perm) + return np.array(result) + elif self.problem["type"] == "expression": + return np.random.rand(self.size, 5) + else: + return np.random.rand(self.size, self.problem["length"]) + + def get_fitness(self, pop): + if self.problem["type"] == "bitstring": + return self.bit_fitness(pop) + elif self.problem["type"] == "permutation": + return self.perm_fitness(pop) + elif self.problem["type"] == "expression": + return self.expr_fitness(pop) + else: + return np.zeros(self.size) + + def bit_fitness(self, pop): + name = self.problem["name"].lower() + if "onemax" in name: + return np.sum(pop, axis=1) + elif "leadingones" in name: + result = [] + for person in pop: + count = 0 + for bit in person: + if bit == 1: + count += 1 + else: + break + result.append(count) + return np.array(result) + else: + return np.sum(pop, axis=1) + + def perm_fitness(self, pop): + name = self.problem["name"].lower() + if "queens" in name: + result = [] + for p in pop: + result.append(self.queens_fit(p)) + return np.array(result) + elif "tsp" in name: + result = [] + for p in pop: + result.append(self.tsp_fit(p)) + return np.array(result) + else: + result = [] + for p in pop: + result.append(len(np.unique(p))) + return np.array(result) + + def expr_fitness(self, pop): + result = [] + for person in pop: + mse = 0 + for x, y_true in self.problem["dataset"]: + y_pred = person[0] * x + person[1] + mse += (y_pred - y_true) ** 2 + result.append(1.0 / (1.0 + mse)) + return np.array(result) + + def queens_fit(self, perm): + n = len(perm) + bad = 0 + for i in range(n): + for j in range(i + 1, n): + if abs(i - j) == abs(perm[i] - perm[j]): + bad += 1 + return n * (n - 1) // 2 - bad + + def tsp_fit(self, perm): + n = len(perm) + if n <= 1: + return 0 + cities = np.random.rand(n, 2) + dist = 0 + for i in range(n): + p1 = cities[perm[i]] + p2 = cities[perm[(i + 1) % n]] + dist += np.linalg.norm(p1 - p2) + return 1.0 / (1.0 + dist) + + def next_gen(self, pop, llm_help=None): + new_pop = pop.copy() + if llm_help is not None and len(llm_help) > 0: + fit = self.get_fitness(pop) + bad_idx = np.argsort(fit)[:len(llm_help)] + for i, help in enumerate(llm_help): + if i < len(bad_idx): + new_pop[bad_idx[i]] = help + for i in range(len(new_pop)): + if random.random() < 0.7: + new_pop[i] = self.mutate(new_pop[i]) + if random.random() < 0.7: + j = random.randint(0, len(new_pop) - 1) + new_pop[i], new_pop[j] = self.cross(new_pop[i], new_pop[j]) + return new_pop + + def mutate(self, person): + if self.problem["type"] == "bitstring": + for _ in range(5): + idx = random.randint(0, len(person) - 1) + person[idx] = 1 - person[idx] + elif self.problem["type"] == "permutation": + i, j = random.sample(range(len(person)), 2) + person[i], person[j] = person[j], person[i] + else: + person += np.random.normal(0, 0.1, len(person)) + return person + + def cross(self, p1, p2): + if self.problem["type"] == "bitstring": + point = random.randint(1, len(p1) - 1) + new1 = np.concatenate([p1[:point], p2[point:]]) + new2 = np.concatenate([p2[:point], p1[point:]]) + elif self.problem["type"] == "permutation": + new1, new2 = self.order_cross(p1, p2) + else: + alpha = random.random() + new1 = alpha * p1 + (1 - alpha) * p2 + new2 = alpha * p2 + (1 - alpha) * p1 + return new1, new2 + + def order_cross(self, p1, p2): + size = len(p1) + start, end = sorted(random.sample(range(size), 2)) + child1 = [-1] * size + child1[start:end] = p1[start:end] + left = [x for x in p2 if x not in child1[start:end]] + j = 0 + for i in range(size): + if child1[i] == -1: + child1[i] = left[j] + j += 1 + child2 = [-1] * size + child2[start:end] = p2[start:end] + left = [x for x in p1 if x not in child2[start:end]] + j = 0 + for i in range(size): + if child2[i] == -1: + child2[i] = left[j] + j += 1 + return np.array(child1), np.array(child2) diff --git a/submissions/Daanish-Mehra/lib/data/__pycache__/hf_dataset.cpython-312.pyc b/submissions/Daanish-Mehra/lib/data/__pycache__/hf_dataset.cpython-312.pyc new file mode 100644 index 0000000..b022620 Binary files /dev/null and b/submissions/Daanish-Mehra/lib/data/__pycache__/hf_dataset.cpython-312.pyc differ diff --git a/submissions/Daanish-Mehra/lib/data/hf_dataset.py b/submissions/Daanish-Mehra/lib/data/hf_dataset.py new file mode 100644 index 0000000..ce1467a --- /dev/null +++ b/submissions/Daanish-Mehra/lib/data/hf_dataset.py @@ -0,0 +1,105 @@ +from datasets import Dataset, DatasetDict +import json +import numpy as np + +class HFDatasetManager: + def __init__(self, problems_file="lib/problems/probs.json"): + self.problems_file = problems_file + self.dataset = None + self.load_problems_as_dataset() + + def load_problems_as_dataset(self): + print("Converting problems to Hugging Face Dataset format...") + + with open(self.problems_file, 'r') as f: + problems = json.load(f) + + dataset_dict = { + "name": [], + "type": [], + "difficulty": [], + "length": [], + "description": [], + "fitness_description": [], + "tags": [], + "complexity_score": [] + } + + for problem in problems: + dataset_dict["name"].append(problem["name"]) + dataset_dict["type"].append(problem["type"]) + dataset_dict["difficulty"].append(problem["difficulty"]) + dataset_dict["length"].append(problem.get("length", 0)) + dataset_dict["description"].append(problem["description"]) + dataset_dict["fitness_description"].append(problem.get("fitness_description", "")) + + # Add tags based on problem type + tags = [problem["type"], problem["difficulty"]] + if "OneMax" in problem["name"]: + tags.append("counting") + elif "Queen" in problem["name"]: + tags.append("constraint") + elif "TSP" in problem["name"]: + tags.append("routing") + elif "Sudoku" in problem["name"]: + tags.append("puzzle") + + dataset_dict["tags"].append(tags) + + # Calculate complexity score + complexity = self.calculate_complexity(problem) + dataset_dict["complexity_score"].append(complexity) + + self.dataset = Dataset.from_dict(dataset_dict) + print(f" Created HF Dataset with {len(self.dataset)} problems") + print(f" - Types: {set(self.dataset['type'])}") + print(f" - Difficulties: {set(self.dataset['difficulty'])}") + + def calculate_complexity(self, problem): + base_score = { + "easy": 1, + "medium": 2, + "hard": 3, + "expert": 4 + }.get(problem["difficulty"], 2) + + length = problem.get("length", 10) + length_factor = min(length / 50.0, 2.0) + + type_factor = { + "bitstring": 1.0, + "permutation": 1.5, + "expression": 2.0, + "constraint": 2.5, + "combinatorial": 3.0 + }.get(problem["type"], 1.0) + + return round(base_score * length_factor * type_factor, 2) + + def filter_by_difficulty(self, difficulty): + return self.dataset.filter(lambda x: x["difficulty"] == difficulty) + + def filter_by_type(self, problem_type): + return self.dataset.filter(lambda x: x["type"] == problem_type) + + def get_random_problems(self, n=10): + indices = np.random.choice(len(self.dataset), min(n, len(self.dataset)), replace=False) + return self.dataset.select(indices) + + def save_to_hub(self, repo_name="evolution-arena-problems"): + print(f"Saving dataset to Hugging Face Hub: {repo_name}") + try: + self.dataset.push_to_hub(repo_name) + print(" Dataset saved to HF Hub!") + except Exception as e: + print(f" Failed to save to HF Hub: {e}") + + def get_stats(self): + stats = { + "total_problems": len(self.dataset), + "types": dict(self.dataset.to_pandas()["type"].value_counts()), + "difficulties": dict(self.dataset.to_pandas()["difficulty"].value_counts()), + "avg_complexity": np.mean(self.dataset["complexity_score"]), + "avg_length": np.mean([x for x in self.dataset["length"] if x > 0]) + } + return stats diff --git a/submissions/Daanish-Mehra/lib/problems/probs.json b/submissions/Daanish-Mehra/lib/problems/probs.json new file mode 100644 index 0000000..11b2769 --- /dev/null +++ b/submissions/Daanish-Mehra/lib/problems/probs.json @@ -0,0 +1,114 @@ +[ + {"id": 1, "name": "OneMax 20-bit", "type": "bitstring", "length": 20, "fitness": "sum(bits)", "difficulty": "easy", "description": "Maximize the number of 1s in a 20-bit string"}, + {"id": 2, "name": "OneMax 50-bit", "type": "bitstring", "length": 50, "fitness": "sum(bits)", "difficulty": "medium", "description": "Maximize the number of 1s in a 50-bit string"}, + {"id": 3, "name": "OneMax 100-bit", "type": "bitstring", "length": 100, "fitness": "sum(bits)", "difficulty": "hard", "description": "Maximize the number of 1s in a 100-bit string"}, + {"id": 4, "name": "LeadingOnes 20-bit", "type": "bitstring", "length": 20, "fitness": "consecutive 1s from start", "difficulty": "medium", "description": "Maximize consecutive 1s from the beginning"}, + {"id": 5, "name": "LeadingOnes 50-bit", "type": "bitstring", "length": 50, "fitness": "consecutive 1s from start", "difficulty": "hard", "description": "Maximize consecutive 1s from the beginning"}, + {"id": 6, "name": "LeadingOnes 100-bit", "type": "bitstring", "length": 100, "fitness": "consecutive 1s from start", "difficulty": "expert", "description": "Maximize consecutive 1s from the beginning"}, + {"id": 7, "name": "Simple Trap 10-bit", "type": "bitstring", "length": 10, "fitness": "trap function", "difficulty": "medium", "description": "Deceptive trap function with local optima"}, + {"id": 8, "name": "Simple Trap 20-bit", "type": "bitstring", "length": 20, "fitness": "trap function", "difficulty": "hard", "description": "Deceptive trap function with local optima"}, + {"id": 9, "name": "Knapsack 10-item", "type": "bitstring", "length": 10, "fitness": "sum(values if selected) <= capacity", "difficulty": "medium", "description": "Classic knapsack optimization"}, + {"id": 10, "name": "Knapsack 20-item", "type": "bitstring", "length": 20, "fitness": "sum(values if selected) <= capacity", "difficulty": "hard", "description": "Classic knapsack optimization"}, + + {"id": 11, "name": "4-Queens", "type": "permutation", "length": 4, "fitness": "non-attacking pairs", "difficulty": "easy", "description": "Place 4 queens on 4x4 board without attacks"}, + {"id": 12, "name": "8-Queens", "type": "permutation", "length": 8, "fitness": "non-attacking pairs", "difficulty": "medium", "description": "Place 8 queens on 8x8 board without attacks"}, + {"id": 13, "name": "10-Queens", "type": "permutation", "length": 10, "fitness": "non-attacking pairs", "difficulty": "hard", "description": "Place 10 queens on 10x10 board without attacks"}, + {"id": 14, "name": "TSP 5 cities", "type": "permutation", "length": 5, "fitness": "inverse of total path length", "difficulty": "easy", "description": "Traveling Salesman Problem with 5 cities"}, + {"id": 15, "name": "TSP 8 cities", "type": "permutation", "length": 8, "fitness": "inverse of total path length", "difficulty": "medium", "description": "Traveling Salesman Problem with 8 cities"}, + {"id": 16, "name": "TSP 10 cities", "type": "permutation", "length": 10, "fitness": "inverse of total path length", "difficulty": "hard", "description": "Traveling Salesman Problem with 10 cities"}, + {"id": 17, "name": "Mini Sudoku 4x4", "type": "permutation", "length": 16, "fitness": "row+column+box constraints", "difficulty": "medium", "description": "4x4 Sudoku puzzle completion"}, + {"id": 18, "name": "Mini Sudoku 6x6", "type": "permutation", "length": 36, "fitness": "row+column+box constraints", "difficulty": "hard", "description": "6x6 Sudoku puzzle completion"}, + {"id": 19, "name": "Latin Square 4x4", "type": "permutation", "length": 16, "fitness": "row+column uniqueness", "difficulty": "medium", "description": "4x4 Latin square completion"}, + {"id": 20, "name": "Latin Square 6x6", "type": "permutation", "length": 36, "fitness": "row+column uniqueness", "difficulty": "hard", "description": "6x6 Latin square completion"}, + + {"id": 21, "name": "y=x^2", "type": "expression", "dataset": [[-2,4],[-1,1],[0,0],[1,1],[2,4]], "fitness": "MSE", "difficulty": "easy", "description": "Find quadratic function y=x²"}, + {"id": 22, "name": "y=x^3", "type": "expression", "dataset": [[-2,-8],[-1,-1],[0,0],[1,1],[2,8]], "fitness": "MSE", "difficulty": "easy", "description": "Find cubic function y=x³"}, + {"id": 23, "name": "y=2x+3", "type": "expression", "dataset": [[-2,-1],[-1,1],[0,3],[1,5],[2,7]], "fitness": "MSE", "difficulty": "easy", "description": "Find linear function y=2x+3"}, + {"id": 24, "name": "y=sin(x)", "type": "expression", "dataset": [[0,0],[1,0.841],[2,0.909],[3,0.141],[4,-0.757]], "fitness": "MSE", "difficulty": "medium", "description": "Find trigonometric function y=sin(x)"}, + {"id": 25, "name": "y=cos(x)", "type": "expression", "dataset": [[0,1],[1,0.540],[2,-0.416],[3,-0.990],[4,-0.653]], "fitness": "MSE", "difficulty": "medium", "description": "Find trigonometric function y=cos(x)"}, + {"id": 26, "name": "y=x^2+x+1", "type": "expression", "dataset": [[-2,3],[-1,1],[0,1],[1,3],[2,7]], "fitness": "MSE", "difficulty": "medium", "description": "Find quadratic function y=x²+x+1"}, + {"id": 27, "name": "y=log(x+1)", "type": "expression", "dataset": [[0,0],[1,0.693],[2,1.098],[3,1.386],[4,1.609]], "fitness": "MSE", "difficulty": "hard", "description": "Find logarithmic function y=log(x+1)"}, + {"id": 28, "name": "y=x^2-2x+1", "type": "expression", "dataset": [[-2,9],[-1,4],[0,1],[1,0],[2,1]], "fitness": "MSE", "difficulty": "medium", "description": "Find quadratic function y=x²-2x+1"}, + {"id": 29, "name": "y=exp(x)", "type": "expression", "dataset": [[0,1],[1,2.718],[2,7.389],[3,20.085],[4,54.598]], "fitness": "MSE", "difficulty": "hard", "description": "Find exponential function y=e^x"}, + {"id": 30, "name": "y=x^3-3x+2", "type": "expression", "dataset": [[-2,-4],[-1,4],[0,2],[1,0],[2,2]], "fitness": "MSE", "difficulty": "hard", "description": "Find cubic function y=x³-3x+2"}, + + {"id": 31, "name": "Bin Packing 5 items", "type": "constraint", "length": 5, "fitness": "minimize number of bins used", "difficulty": "easy", "description": "Pack 5 items into minimum bins"}, + {"id": 32, "name": "Bin Packing 10 items", "type": "constraint", "length": 10, "fitness": "minimize number of bins used", "difficulty": "medium", "description": "Pack 10 items into minimum bins"}, + {"id": 33, "name": "Job Scheduling 3 jobs", "type": "constraint", "length": 3, "fitness": "minimize makespan", "difficulty": "easy", "description": "Schedule 3 jobs to minimize completion time"}, + {"id": 34, "name": "Job Scheduling 5 jobs", "type": "constraint", "length": 5, "fitness": "minimize makespan", "difficulty": "medium", "description": "Schedule 5 jobs to minimize completion time"}, + {"id": 35, "name": "Job Scheduling 8 jobs", "type": "constraint", "length": 8, "fitness": "minimize makespan", "difficulty": "hard", "description": "Schedule 8 jobs to minimize completion time"}, + {"id": 36, "name": "Resource Allocation 3 tasks", "type": "constraint", "length": 3, "fitness": "maximize resource utilization", "difficulty": "medium", "description": "Allocate resources to 3 tasks optimally"}, + {"id": 37, "name": "Resource Allocation 5 tasks", "type": "constraint", "length": 5, "fitness": "maximize resource utilization", "difficulty": "hard", "description": "Allocate resources to 5 tasks optimally"}, + {"id": 38, "name": "Task Sequencing 4 tasks", "type": "constraint", "length": 4, "fitness": "minimize completion time", "difficulty": "medium", "description": "Sequence 4 tasks optimally"}, + {"id": 39, "name": "Task Sequencing 6 tasks", "type": "constraint", "length": 6, "fitness": "minimize completion time", "difficulty": "hard", "description": "Sequence 6 tasks optimally"}, + {"id": 40, "name": "Task Sequencing 8 tasks", "type": "constraint", "length": 8, "fitness": "minimize completion time", "difficulty": "expert", "description": "Sequence 8 tasks optimally"}, + + {"id": 41, "name": "Graph Coloring 4 nodes", "type": "combinatorial", "length": 4, "fitness": "minimize color conflicts", "difficulty": "easy", "description": "Color 4-node graph with minimum colors"}, + {"id": 42, "name": "Graph Coloring 6 nodes", "type": "combinatorial", "length": 6, "fitness": "minimize color conflicts", "difficulty": "medium", "description": "Color 6-node graph with minimum colors"}, + {"id": 43, "name": "Graph Coloring 8 nodes", "type": "combinatorial", "length": 8, "fitness": "minimize color conflicts", "difficulty": "hard", "description": "Color 8-node graph with minimum colors"}, + {"id": 44, "name": "Shortest Path 4-node graph", "type": "combinatorial", "length": 4, "fitness": "inverse of path length", "difficulty": "easy", "description": "Find shortest path in 4-node graph"}, + {"id": 45, "name": "Shortest Path 6-node graph", "type": "combinatorial", "length": 6, "fitness": "minimize path length", "difficulty": "medium", "description": "Find shortest path in 6-node graph"}, + {"id": 46, "name": "Shortest Path 8-node graph", "type": "combinatorial", "length": 8, "fitness": "minimize path length", "difficulty": "hard", "description": "Find shortest path in 8-node graph"}, + {"id": 47, "name": "Max-Cut 4-node graph", "type": "combinatorial", "length": 4, "fitness": "size of cut", "difficulty": "medium", "description": "Find maximum cut in 4-node graph"}, + {"id": 48, "name": "Max-Cut 6-node graph", "type": "combinatorial", "length": 6, "fitness": "size of cut", "difficulty": "hard", "description": "Find maximum cut in 6-node graph"}, + {"id": 49, "name": "Max-Cut 8-node graph", "type": "combinatorial", "length": 8, "fitness": "size of cut", "difficulty": "expert", "description": "Find maximum cut in 8-node graph"}, + {"id": 50, "name": "Hamiltonian Path 5-node", "type": "combinatorial", "length": 5, "fitness": "1 if exists, else 0", "difficulty": "hard", "description": "Find Hamiltonian path in 5-node graph"}, + + {"id": 51, "name": "OneMax + LeadingOnes 20-bit", "type": "multi-objective", "length": 20, "fitness": "sum(bits)+consecutive1s", "difficulty": "hard", "description": "Multi-objective: maximize 1s and leading 1s"}, + {"id": 52, "name": "OneMax + Trap 20-bit", "type": "multi-objective", "length": 20, "fitness": "sum(bits)+trap function", "difficulty": "expert", "description": "Multi-objective: maximize 1s and trap function"}, + {"id": 53, "name": "Knapsack + LeadingOnes 10-bit", "type": "multi-objective", "length": 10, "fitness": "value+leading1s", "difficulty": "hard", "description": "Multi-objective: maximize value and leading 1s"}, + {"id": 54, "name": "N-Queens + Max-Cut 4-node", "type": "multi-objective", "length": 4, "fitness": "non-attacking+cut", "difficulty": "expert", "description": "Multi-objective: N-queens and max-cut combined"}, + {"id": 55, "name": "TSP + Minimize Turns 5-city", "type": "multi-objective", "length": 5, "fitness": "distance+turn penalty", "difficulty": "hard", "description": "Multi-objective: minimize distance and turns"}, + {"id": 56, "name": "Symbolic Regression + Simplicity", "type": "multi-objective", "length": 5, "fitness": "MSE + expression length", "difficulty": "expert", "description": "Multi-objective: accuracy and simplicity"}, + {"id": 57, "name": "Job Scheduling + Resource Usage", "type": "multi-objective", "length": 5, "fitness": "minimize makespan + maximize utilization", "difficulty": "expert", "description": "Multi-objective: scheduling and resource optimization"}, + {"id": 58, "name": "Bin Packing + Diversity", "type": "multi-objective", "length": 10, "fitness": "minimize bins + maximize variation", "difficulty": "hard", "description": "Multi-objective: packing efficiency and diversity"}, + {"id": 59, "name": "Graph Coloring + Connectivity", "type": "multi-objective", "length": 6, "fitness": "color conflicts + connected components", "difficulty": "expert", "description": "Multi-objective: coloring and connectivity"}, + {"id": 60, "name": "Multi-Constraint Task Sequencing", "type": "multi-objective", "length": 6, "fitness": "minimize time + resource conflict", "difficulty": "expert", "description": "Multi-objective: time and resource optimization"}, + + {"id": 61, "name": "Multi-Modal Optimization", "type": "hybrid", "length": 15, "fitness": "combined bitstring+permutation", "difficulty": "expert", "description": "Optimize both bitstring and permutation simultaneously"}, + {"id": 62, "name": "Dynamic Fitness Landscape", "type": "adaptive", "length": 20, "fitness": "changes over generations", "difficulty": "expert", "description": "Fitness function that evolves during optimization"}, + {"id": 63, "name": "Multi-Objective Knapsack", "type": "multi-objective", "length": 25, "fitness": "value+weight+volume optimization", "difficulty": "hard", "description": "3D knapsack with multiple constraints"}, + {"id": 64, "name": "Neural Architecture Search", "type": "neural", "length": 30, "fitness": "accuracy+latency trade-off", "difficulty": "expert", "description": "Optimize neural network architectures"}, + {"id": 65, "name": "Quantum Circuit Design", "type": "quantum", "length": 16, "fitness": "circuit depth + error rate", "difficulty": "expert", "description": "Design quantum computing circuits"}, + {"id": 66, "name": "Game Strategy Optimization", "type": "game", "length": 12, "fitness": "win rate + strategy diversity", "difficulty": "hard", "description": "Optimize game-playing strategies"}, + {"id": 67, "name": "Music Composition", "type": "creative", "length": 20, "fitness": "melody + harmony + rhythm", "difficulty": "hard", "description": "Compose musical sequences"}, + {"id": 68, "name": "Protein Folding", "type": "bio", "length": 18, "fitness": "energy minimization", "difficulty": "expert", "description": "Optimize protein 3D structures"}, + {"id": 69, "name": "Financial Portfolio", "type": "finance", "length": 22, "fitness": "return + risk + diversification", "difficulty": "hard", "description": "Optimize investment portfolios"}, + {"id": 70, "name": "Supply Chain Network", "type": "logistics", "length": 28, "fitness": "cost + time + reliability", "difficulty": "expert", "description": "Optimize supply chain networks"}, + + {"id": 71, "name": "Hyperparameter Tuning", "type": "ml", "length": 10, "fitness": "validation accuracy + training time", "difficulty": "medium", "description": "Optimize ML model hyperparameters"}, + {"id": 72, "name": "Feature Selection", "type": "ml", "length": 35, "fitness": "accuracy + feature count", "difficulty": "medium", "description": "Select optimal feature subsets"}, + {"id": 73, "name": "Ensemble Learning", "type": "ml", "length": 15, "fitness": "diversity + accuracy", "difficulty": "hard", "description": "Optimize ensemble model combinations"}, + {"id": 74, "name": "AutoML Pipeline", "type": "ml", "length": 25, "fitness": "performance + interpretability", "difficulty": "expert", "description": "Design automated ML pipelines"}, + {"id": 75, "name": "Reinforcement Learning", "type": "rl", "length": 20, "fitness": "reward + exploration", "difficulty": "hard", "description": "Optimize RL agent policies"}, + + {"id": 76, "name": "Computer Vision", "type": "vision", "length": 16, "fitness": "accuracy + efficiency", "difficulty": "hard", "description": "Optimize CV model architectures"}, + {"id": 77, "name": "Natural Language Processing", "type": "nlp", "length": 18, "fitness": "performance + interpretability", "difficulty": "hard", "description": "Optimize NLP model designs"}, + {"id": 78, "name": "Speech Recognition", "type": "audio", "length": 14, "fitness": "accuracy + latency", "difficulty": "medium", "description": "Optimize speech models"}, + {"id": 79, "name": "Recommendation System", "type": "recsys", "length": 24, "fitness": "precision + recall + diversity", "difficulty": "hard", "description": "Optimize recommendation algorithms"}, + {"id": 80, "name": "Anomaly Detection", "type": "detection", "length": 20, "fitness": "detection rate + false positives", "difficulty": "medium", "description": "Optimize anomaly detection systems"}, + + {"id": 81, "name": "Time Series Forecasting", "type": "forecasting", "length": 16, "fitness": "accuracy + horizon", "difficulty": "hard", "description": "Optimize forecasting models"}, + {"id": 82, "name": "Clustering", "type": "clustering", "length": 18, "fitness": "silhouette + calinski", "difficulty": "medium", "description": "Optimize clustering algorithms"}, + {"id": 83, "name": "Dimensionality Reduction", "type": "dimred", "length": 22, "fitness": "variance + reconstruction", "difficulty": "medium", "description": "Optimize dimension reduction"}, + {"id": 84, "name": "Active Learning", "type": "active", "length": 12, "fitness": "information gain + cost", "difficulty": "hard", "description": "Optimize active learning strategies"}, + {"id": 85, "name": "Transfer Learning", "type": "transfer", "length": 20, "fitness": "target performance + adaptation", "difficulty": "expert", "description": "Optimize transfer learning approaches"}, + + {"id": 86, "name": "Federated Learning", "type": "federated", "length": 26, "fitness": "global accuracy + privacy", "difficulty": "expert", "description": "Optimize federated learning protocols"}, + {"id": 87, "name": "Meta-Learning", "type": "meta", "length": 24, "fitness": "adaptation speed + performance", "difficulty": "expert", "description": "Optimize meta-learning algorithms"}, + {"id": 88, "name": "Neural Architecture Search", "type": "nas", "length": 30, "fitness": "accuracy + efficiency + search", "difficulty": "expert", "description": "Optimize NAS strategies"}, + {"id": 89, "name": "AutoML", "type": "automl", "length": 28, "fitness": "performance + automation", "difficulty": "expert", "description": "Optimize AutoML frameworks"}, + {"id": 90, "name": "Neural Evolution", "type": "neuroevolution", "length": 32, "fitness": "fitness + complexity", "difficulty": "expert", "description": "Evolve neural network structures"}, + + {"id": 91, "name": "Evolutionary Robotics", "type": "robotics", "length": 25, "fitness": "task completion + energy", "difficulty": "expert", "description": "Optimize robot behaviors"}, + {"id": 92, "name": "Swarm Intelligence", "type": "swarm", "length": 20, "fitness": "coordination + efficiency", "difficulty": "hard", "description": "Optimize swarm algorithms"}, + {"id": 93, "name": "Multi-Agent Systems", "type": "agents", "length": 22, "fitness": "cooperation + competition", "difficulty": "hard", "description": "Optimize multi-agent coordination"}, + {"id": 94, "name": "Game Theory", "type": "game_theory", "length": 18, "fitness": "equilibrium + stability", "difficulty": "expert", "description": "Optimize game theoretic strategies"}, + {"id": 95, "name": "Auction Design", "type": "auction", "length": 16, "fitness": "efficiency + revenue", "difficulty": "hard", "description": "Design optimal auction mechanisms"}, + + {"id": 96, "name": "Blockchain Optimization", "type": "blockchain", "length": 24, "fitness": "throughput + security", "difficulty": "expert", "description": "Optimize blockchain protocols"}, + {"id": 97, "name": "Cryptocurrency Mining", "type": "crypto", "length": 20, "fitness": "hash rate + energy", "difficulty": "medium", "description": "Optimize mining strategies"}, + {"id": 98, "name": "Smart Contract", "type": "smart_contract", "length": 18, "fitness": "functionality + gas", "difficulty": "hard", "description": "Optimize smart contract code"}, + {"id": 99, "name": "DeFi Protocol", "type": "defi", "length": 26, "fitness": "yield + risk", "difficulty": "expert", "description": "Design DeFi protocols"}, + {"id": 100, "name": "Web3 Infrastructure", "type": "web3", "length": 30, "fitness": "scalability + decentralization", "difficulty": "expert", "description": "Optimize Web3 infrastructure"} +] \ No newline at end of file diff --git a/submissions/Daanish-Mehra/lib/rl/__pycache__/rl_agent.cpython-312.pyc b/submissions/Daanish-Mehra/lib/rl/__pycache__/rl_agent.cpython-312.pyc new file mode 100644 index 0000000..1019225 Binary files /dev/null and b/submissions/Daanish-Mehra/lib/rl/__pycache__/rl_agent.cpython-312.pyc differ diff --git a/submissions/Daanish-Mehra/lib/rl/__pycache__/rl_loop.cpython-312.pyc b/submissions/Daanish-Mehra/lib/rl/__pycache__/rl_loop.cpython-312.pyc new file mode 100644 index 0000000..59e9d0b Binary files /dev/null and b/submissions/Daanish-Mehra/lib/rl/__pycache__/rl_loop.cpython-312.pyc differ diff --git a/submissions/Daanish-Mehra/lib/rl/rl_agent.py b/submissions/Daanish-Mehra/lib/rl/rl_agent.py new file mode 100644 index 0000000..674fded --- /dev/null +++ b/submissions/Daanish-Mehra/lib/rl/rl_agent.py @@ -0,0 +1,119 @@ +import numpy as np +import random +import json +from collections import deque + +class RL_agent: + def __init__(self, agent_type="llm"): + self.agent_type = agent_type + self.experience_buffer = deque(maxlen=1000) + self.q_table = {} + self.epsilon = 0.3 + self.learning_rate = 0.1 + self.discount_factor = 0.9 + self.performance_history = [] + + def get_state_key(self, problem_info, current_fitness, generation): + problem_type = problem_info["type"] + difficulty = problem_info["difficulty"] + fitness_bucket = int(current_fitness / 5) * 5 + gen_bucket = int(generation / 2) * 2 + return f"{problem_type}_{difficulty}_{fitness_bucket}_{gen_bucket}" + + def get_action(self, state_key, available_actions): + if random.random() < self.epsilon: + return random.choice(available_actions) + + if state_key not in self.q_table: + self.q_table[state_key] = {action: 0.0 for action in available_actions} + + q_values = self.q_table[state_key] + best_action = max(q_values, key=q_values.get) + return best_action + + def update_q_value(self, state_key, action, reward, next_state_key): + if state_key not in self.q_table: + self.q_table[state_key] = {} + + if action not in self.q_table[state_key]: + self.q_table[state_key][action] = 0.0 + + current_q = self.q_table[state_key][action] + + if next_state_key in self.q_table: + max_next_q = max(self.q_table[next_state_key].values()) if self.q_table[next_state_key] else 0 + else: + max_next_q = 0 + + new_q = current_q + self.learning_rate * (reward + self.discount_factor * max_next_q - current_q) + self.q_table[state_key][action] = new_q + + def store_experience(self, state, action, reward, next_state, done): + experience = { + 'state': state, + 'action': action, + 'reward': reward, + 'next_state': next_state, + 'done': done + } + self.experience_buffer.append(experience) + + def calculate_reward(self, old_fitness, new_fitness, problem_info): + fitness_improvement = new_fitness - old_fitness + + if self.agent_type == "llm": + base_reward = fitness_improvement * 10 + if fitness_improvement > 0: + base_reward += 5 + else: + base_reward -= 2 + else: + base_reward = fitness_improvement * 8 + if fitness_improvement > 0: + base_reward += 3 + else: + base_reward -= 1 + + if problem_info["difficulty"] == "expert": + base_reward *= 1.5 + elif problem_info["difficulty"] == "hard": + base_reward *= 1.2 + + return base_reward + + def decay_epsilon(self): + self.epsilon = max(0.05, self.epsilon * 0.995) + + def get_performance_stats(self): + if not self.performance_history: + return {"avg_reward": 0, "total_episodes": 0, "success_rate": 0} + + recent_rewards = self.performance_history[-50:] + avg_reward = sum(recent_rewards) / len(recent_rewards) + success_rate = sum(1 for r in recent_rewards if r > 0) / len(recent_rewards) + + return { + "avg_reward": avg_reward, + "total_episodes": len(self.performance_history), + "success_rate": success_rate, + "epsilon": self.epsilon + } + + def save_model(self, filename): + model_data = { + 'q_table': self.q_table, + 'epsilon': self.epsilon, + 'performance_history': self.performance_history[-100:] + } + with open(filename, 'w') as f: + json.dump(model_data, f) + + def load_model(self, filename): + try: + with open(filename, 'r') as f: + model_data = json.load(f) + self.q_table = model_data['q_table'] + self.epsilon = model_data['epsilon'] + self.performance_history = model_data['performance_history'] + except FileNotFoundError: + pass diff --git a/submissions/Daanish-Mehra/lib/rl/rl_loop.py b/submissions/Daanish-Mehra/lib/rl/rl_loop.py new file mode 100644 index 0000000..e0f8f9a --- /dev/null +++ b/submissions/Daanish-Mehra/lib/rl/rl_loop.py @@ -0,0 +1,31 @@ +import numpy as np + +def get_reward(old_fit, new_fit): + old_sum = sum(old_fit) + new_sum = sum(new_fit) + return new_sum - old_sum + +def update_rl_state(rl_state, reward, problem_id): + rl_state['total_reward'] += reward + rl_state['episodes'] += 1 + rl_state['avg_reward'] = rl_state['total_reward'] / rl_state['episodes'] + + if reward > 0: + rl_state['llm_effectiveness'] = min(1.0, rl_state['llm_effectiveness'] + 0.01) + else: + rl_state['llm_effectiveness'] = max(0.1, rl_state['llm_effectiveness'] - 0.01) + + if problem_id not in rl_state['problem_rewards']: + rl_state['problem_rewards'][problem_id] = [] + rl_state['problem_rewards'][problem_id].append(reward) + + return rl_state + +def init_rl_state(): + return { + 'total_reward': 0, + 'episodes': 0, + 'avg_reward': 0, + 'llm_effectiveness': 0.1, + 'problem_rewards': {} + } diff --git a/submissions/Daanish-Mehra/main.py b/submissions/Daanish-Mehra/main.py new file mode 100644 index 0000000..0d9d364 --- /dev/null +++ b/submissions/Daanish-Mehra/main.py @@ -0,0 +1,222 @@ +import sys +import os +import time + +def show_banner(): + print("=" * 70) + print("AI EVOLUTION CHALLENGE") + print("=" * 70) + print("LLMs and Genetic Algorithms compete to solve problems!") + print("ENHANCED WITH HF MODELS") + print() + +def show_mode_menu(): + print("EVOLUTION MODES:") + print() + print("1. Fast Learning Arena") + print(" - Quick evolution with basic LLM integration") + print(" - Perfect for beginners") + print() + print("2. Real Evolution Arena") + print(" - Full LLM integration with Hugging Face") + print(" - Advanced reinforcement learning") + print(" - For experienced players") + print() + print("3. Custom Challenge") + print(" - Choose specific problem types") + print(" - Set custom parameters") + print() + print("4. RL Tournament Mode") + print(" - LLM vs GA") + print(" - Advanced Q-learning agents") + print(" - Watch AI agents learn and compete") + print() + print("5. Multi-Model Demo") + print(" - Test different HF models") + print() + print("6. Gradio Space") + print(" - Web interface") + print() + print("7. Exit") + print("=" * 70) + +def get_problem_count(): + while True: + try: + count = int(input("How many problems do you want to solve? (1-20): ")) + if 1 <= count <= 20: + return count + else: + print("Please enter a number between 1 and 20.") + except ValueError: + print("Please enter a valid number.") + +def get_round_count(): + while True: + try: + count = int(input("How many rounds do you want? (1-10): ")) + if 1 <= count <= 10: + return count + else: + print("Please enter a number between 1 and 10.") + except ValueError: + print("Please enter a valid number.") + +def get_difficulty(): + print("\nDIFFICULTY LEVELS:") + print("1. Easy (problems 1-20)") + print("2. Medium (problems 21-50)") + print("3. Hard (problems 51-80)") + print("4. Expert (problems 81-100)") + print("5. Random (all problems)") + + while True: + choice = input("Enter choice (1-5): ").strip() + if choice in ["1", "2", "3", "4", "5"]: + return int(choice) + print("Invalid choice! Please enter 1-5.") + +def get_problem_types(): + print("\nPROBLEM TYPES:") + print("1. Bitstring (OneMax, LeadingOnes, Trap)") + print("2. Permutation (N-Queens, TSP, Sudoku)") + print("3. Expression (Symbolic Regression)") + print("4. Constraint (Bin Packing, Scheduling)") + print("5. Combinatorial (Graph Coloring, Max-Cut)") + print("6. All types") + + while True: + choice = input("Enter choices (e.g., 1,2,3 or 6): ").strip() + if choice == "6": + return ["all"] + try: + types = [int(x.strip()) for x in choice.split(",")] + if all(1 <= t <= 5 for t in types): + return types + except: + pass + print("Invalid choice! Please enter numbers 1-5 separated by commas.") + +def show_loading_animation(): + print("\nInitializing AI systems...") + for i in range(3): + print("Loading" + "." * (i + 1), end="\r") + time.sleep(0.5) + print("Ready! ") + +def run_multi_model_demo(): + print("Testing Multiple Hugging Face Models...") + from lib.ai.multi_model_llm import MultiModelLLMSolver + from lib.data.hf_dataset import HFDatasetManager + + llm_solver = MultiModelLLMSolver() + dataset_manager = HFDatasetManager() + + print("\nDataset Statistics:") + stats = dataset_manager.get_stats() + print(f"Total problems: {stats['total_problems']}") + print(f"Types: {list(stats['types'].keys())}") + print(f"Difficulties: {list(stats['difficulties'].keys())}") + + test_problems = dataset_manager.get_random_problems(3) + + for i, problem in enumerate(test_problems): + print(f"\nTesting Problem {i+1}: {problem['name']}") + print(f"Type: {problem['type']}, Difficulty: {problem['difficulty']}") + + import numpy as np + if problem['type'] == 'bitstring': + pop = np.random.randint(0, 2, (5, problem['length'])) + elif problem['type'] == 'permutation': + pop = np.array([np.random.permutation(problem['length']) for _ in range(5)]) + else: + pop = np.random.rand(5, problem.get('length', 5)) + + try: + candidates = llm_solver.get_candidates(problem, pop, 3) + print(f"Generated {len(candidates)} candidates") + except Exception as e: + print(f"LLM failed: {e}") + +def run_hf_space(): + print("Starting Hugging Face Space Interface...") + from gradio_space import create_interface + demo = create_interface() + demo.launch(share=True) + +def main(): + show_banner() + + while True: + show_mode_menu() + choice = input("Enter your choice (1-7): ").strip() + + if choice == "1": + print("\n" + "=" * 50) + print("FAST LEARNING ARENA SELECTED") + print("=" * 50) + num_problems = get_problem_count() + show_loading_animation() + from fast_one import FastLearningArena + arena = FastLearningArena() + arena.run_session(num_problems) + break + + elif choice == "2": + print("\n" + "=" * 50) + print("REAL EVOLUTION ARENA SELECTED") + print("=" * 50) + num_problems = get_problem_count() + show_loading_animation() + from real_one import RealEvolutionArena + arena = RealEvolutionArena() + arena.run_session(num_problems) + break + + elif choice == "3": + print("\n" + "=" * 50) + print("CUSTOM CHALLENGE SELECTED") + print("=" * 50) + num_problems = get_problem_count() + difficulty = get_difficulty() + problem_types = get_problem_types() + show_loading_animation() + from custom_arena import CustomArena + arena = CustomArena(difficulty, problem_types) + arena.run_session(num_problems) + break + + elif choice == "4": + print("\n" + "=" * 50) + print("RL TOURNAMENT MODE SELECTED") + print("=" * 50) + num_rounds = get_round_count() + show_loading_animation() + from rl_tournament_arena import RLTournamentArena + arena = RLTournamentArena() + arena.run_session(num_rounds) + break + + elif choice == "5": + print("\n" + "=" * 50) + print("MULTI-MODEL DEMO SELECTED") + print("=" * 50) + run_multi_model_demo() + break + + elif choice == "6": + print("\n" + "=" * 50) + print("GRADIO SPACE SELECTED") + print("=" * 50) + run_hf_space() + break + + elif choice == "7": + print("\nThanks for using Evolution Arena!") + sys.exit(0) + else: + print("Invalid choice! Please enter 1-7.") + print() + +if __name__ == "__main__": + main() diff --git a/submissions/Daanish-Mehra/real_one.py b/submissions/Daanish-Mehra/real_one.py new file mode 100644 index 0000000..a91b945 --- /dev/null +++ b/submissions/Daanish-Mehra/real_one.py @@ -0,0 +1,135 @@ +import numpy as np +import json +import random +import time +import matplotlib.pyplot as plt +from lib.algo.ga import EnhancedGAEngine +from lib.ai.llm import EnhancedLLMSolver +from lib.rl.rl_loop import get_reward, update_rl_state, init_rl_state + +class RealEvolutionArena: + def __init__(self): + self.problems = self.load_problems() + self.score = 0 + self.level = 1 + self.unlocked = set(range(1, 11)) + self.rl_state = init_rl_state() + self.fitness_history = [] + self.problem_history = [] + print("=" * 60) + print("REAL EVOLUTION ARENA - FULL LLM INTEGRATION") + print("=" * 60) + print("Loading Hugging Face LLM...") + self.llm_solver = EnhancedLLMSolver() + print("LLM Ready! Starting evolution...") + print() + + def load_problems(self): + with open('lib/problems/probs.json', 'r') as f: + return json.load(f) + + def run_session(self, num_problems=5): + print(f"Starting {num_problems} problem evolution session...") + print("=" * 60) + + for i in range(num_problems): + problem_id = random.choice(list(self.unlocked)) + problem = self.problems[problem_id - 1] + + print(f"\nPROBLEM {i+1}/{num_problems}") + print("-" * 40) + print(f"Name: {problem['name']}") + print(f"Type: {problem['type'].upper()}") + print(f"Difficulty: {problem['difficulty'].upper()}") + print(f"Description: {problem['description']}") + print() + + result = self.solve_problem(problem) + self.score += result['score'] + self.fitness_history.append(result['best_fitness']) + self.problem_history.append(problem['name']) + + print(f"BEST FITNESS: {result['best_fitness']:.2f}") + print(f"SCORE EARNED: {result['score']}") + print(f"TOTAL SCORE: {self.score}") + print(f"LLM EFFECTIVENESS: {self.rl_state['llm_effectiveness']:.3f}") + + if result['score'] > 50: + self.level += 1 + new_problems = list(range(11, min(21, 11 + self.level * 3))) + self.unlocked.update(new_problems) + print(f"LEVEL UP! Unlocked {len(new_problems)} new problems") + + print("-" * 40) + + self.show_final_results() + return self.score + + def solve_problem(self, problem): + engine = EnhancedGAEngine(problem) + best_fitness = 0 + generations = 10 + gen_fitness = [] + + print("Evolution Progress:") + for gen in range(generations): + fitness = engine.get_fitness(engine.pop) + current_best = max(fitness) + best_fitness = max(best_fitness, current_best) + gen_fitness.append(current_best) + + if random.random() < self.rl_state['llm_effectiveness']: + llm_candidates = self.llm_solver.get_candidates(problem, engine.pop, 3) + engine.pop = engine.next_gen(engine.pop, llm_candidates) + llm_used = "LLM" + else: + engine.pop = engine.next_gen(engine.pop) + llm_used = "GA" + + if gen % 2 == 0: + progress_bar = "█" * int((gen / generations) * 20) + "░" * (20 - int((gen / generations) * 20)) + print(f"Gen {gen:2d}: [{progress_bar}] {current_best:6.2f} ({llm_used})") + + self.plot_evolution(problem['name'], gen_fitness) + + score = int(best_fitness * 10) + reward = get_reward([0], [best_fitness]) + self.rl_state = update_rl_state(self.rl_state, reward, problem['id']) + + return { + 'best_fitness': best_fitness, + 'score': score, + 'generations': generations + } + + def plot_evolution(self, problem_name, fitness_history): + plt.figure(figsize=(8, 4)) + plt.plot(fitness_history, 'r-', linewidth=2, marker='s', markersize=4) + plt.title(f'Evolution Progress: {problem_name}', fontsize=12, fontweight='bold') + plt.xlabel('Generation') + plt.ylabel('Best Fitness') + plt.grid(True, alpha=0.3) + plt.tight_layout() + plt.show(block=False) + plt.pause(0.1) + + def show_final_results(self): + print("\n" + "=" * 60) + print("SESSION COMPLETE - FINAL RESULTS") + print("=" * 60) + print(f"Total Score: {self.score}") + print(f"Problems Solved: {len(self.problem_history)}") + print(f"Final Level: {self.level}") + print(f"LLM Effectiveness: {self.rl_state['llm_effectiveness']:.3f}") + print(f"Average Reward: {self.rl_state['avg_reward']:.2f}") + print() + + print("Problem Performance:") + for i, (name, fitness) in enumerate(zip(self.problem_history, self.fitness_history)): + print(f" {i+1}. {name}: {fitness:.2f}") + + print("\n" + "=" * 60) + +if __name__ == "__main__": + arena = RealEvolutionArena() + arena.run_session(5) diff --git a/submissions/Daanish-Mehra/reqs.txt b/submissions/Daanish-Mehra/reqs.txt new file mode 100644 index 0000000..e6ef317 --- /dev/null +++ b/submissions/Daanish-Mehra/reqs.txt @@ -0,0 +1,27 @@ +# Core ML/AI +torch>=2.0.0 +transformers>=4.35.0 +datasets>=2.14.0 +huggingface_hub>=0.17.0 + +# Web Interface +gradio>=4.0.0 + +# Core Scientific Computing +numpy>=1.24.0 +matplotlib>=3.7.0 +scipy>=1.11.0 + +# Genetic Programming +deap>=1.4.0 +networkx>=3.1.0 + +# Data Processing +pandas>=2.0.0 +scikit-learn>=1.3.0 + +# Utilities +joblib>=1.3.0 +Pillow>=10.0.0 +PyYAML>=6.0.0 +regex>=2023.0.0 diff --git a/submissions/Daanish-Mehra/rl_tournament_arena.py b/submissions/Daanish-Mehra/rl_tournament_arena.py new file mode 100644 index 0000000..69ff82c --- /dev/null +++ b/submissions/Daanish-Mehra/rl_tournament_arena.py @@ -0,0 +1,198 @@ +import numpy as np +import json +import random +import time +from lib.algo.ga import EnhancedGAEngine +from lib.ai.llm import EnhancedLLMSolver +from lib.rl.rl_agent import RL_agent +from tournament_mode import TournamentMode + +class RLTournamentArena: + def __init__(self): + self.problems = self.load_problems() + self.llm_agent = RL_agent("llm") + self.ga_agent = RL_agent("ga") + self.llm_solver = EnhancedLLMSolver() + self.tournament_results = [] + + print("=" * 60) + print("RL TOURNAMENT ARENA - ADVANCED AI COMPETITION") + print("=" * 60) + print("Loading advanced RL agents...") + print("LLM Agent: Neural network ready!") + print("GA Agent: Q-learning ready!") + print("Tournament system: Online!") + print() + + def load_problems(self): + with open('lib/problems/probs.json', 'r') as f: + return json.load(f) + + def run_session(self, num_rounds=5): + print(f"Starting {num_rounds} round RL tournament...") + print("=" * 60) + + llm_wins = 0 + ga_wins = 0 + ties = 0 + + for round_num in range(num_rounds): + print(f"\nROUND {round_num + 1}/{num_rounds}") + print("-" * 40) + + problem = random.choice(self.problems[:20]) + print(f"Problem: {problem['name']}") + print(f"Type: {problem['type'].upper()}") + print(f"Difficulty: {problem['difficulty'].upper()}") + print() + + llm_result = self.run_llm_agent(problem, round_num) + ga_result = self.run_ga_agent(problem, round_num) + + print(f"LLM Agent: {llm_result['best_fitness']:.2f}") + print(f"GA Agent: {ga_result['best_fitness']:.2f}") + + if llm_result['best_fitness'] > ga_result['best_fitness']: + llm_wins += 1 + winner = "LLM Agent" + elif ga_result['best_fitness'] > llm_result['best_fitness']: + ga_wins += 1 + winner = "GA Agent" + else: + ties += 1 + winner = "TIE" + + print(f"Winner: {winner}") + print("-" * 40) + + self.tournament_results.append({ + 'round': round_num + 1, + 'problem': problem['name'], + 'llm_fitness': llm_result['best_fitness'], + 'ga_fitness': ga_result['best_fitness'], + 'winner': winner + }) + + self.show_tournament_results(llm_wins, ga_wins, ties) + return llm_wins, ga_wins, ties + + def run_llm_agent(self, problem, round_num): + engine = EnhancedGAEngine(problem) + best_fitness = 0 + generations = 10 + + print("LLM Agent Evolution:") + for gen in range(generations): + fitness = engine.get_fitness(engine.pop) + current_best = max(fitness) + best_fitness = max(best_fitness, current_best) + + state_key = self.llm_agent.get_state_key(problem, current_best, gen) + action = self.llm_agent.get_action(state_key, ["use_llm", "use_ga"]) + + if action == "use_llm": + llm_candidates = self.llm_solver.get_candidates(problem, engine.pop, 3) + engine.pop = engine.next_gen(engine.pop, llm_candidates) + action_used = "LLM" + else: + engine.pop = engine.next_gen(engine.pop) + action_used = "GA" + + if gen % 2 == 0: + progress_bar = "█" * int((gen / generations) * 20) + "░" * (20 - int((gen / generations) * 20)) + print(f"Gen {gen:2d}: [{progress_bar}] {current_best:6.2f} ({action_used})") + + if gen > 0: + old_fitness = max(engine.get_fitness(engine.pop)) if gen > 0 else current_best + reward = self.llm_agent.calculate_reward(old_fitness, current_best, problem) + next_state_key = self.llm_agent.get_state_key(problem, current_best, gen + 1) + self.llm_agent.update_q_value(state_key, action, reward, next_state_key) + self.llm_agent.performance_history.append(reward) + + time.sleep(0.3) + + self.llm_agent.decay_epsilon() + return {'best_fitness': best_fitness} + + def run_ga_agent(self, problem, round_num): + engine = EnhancedGAEngine(problem) + best_fitness = 0 + generations = 10 + + print("GA Agent Evolution:") + for gen in range(generations): + fitness = engine.get_fitness(engine.pop) + current_best = max(fitness) + best_fitness = max(best_fitness, current_best) + + state_key = self.ga_agent.get_state_key(problem, current_best, gen) + action = self.ga_agent.get_action(state_key, ["mutate", "crossover", "both"]) + + if action == "mutate": + for i in range(len(engine.pop)): + if random.random() < 0.7: + engine.pop[i] = engine.mutate(engine.pop[i]) + action_used = "MUTATE" + elif action == "crossover": + for i in range(0, len(engine.pop), 2): + if i + 1 < len(engine.pop): + engine.pop[i], engine.pop[i+1] = engine.cross(engine.pop[i], engine.pop[i+1]) + action_used = "CROSS" + else: + for i in range(len(engine.pop)): + if random.random() < 0.7: + engine.pop[i] = engine.mutate(engine.pop[i]) + for i in range(0, len(engine.pop), 2): + if i + 1 < len(engine.pop): + engine.pop[i], engine.pop[i+1] = engine.cross(engine.pop[i], engine.pop[i+1]) + action_used = "BOTH" + + if gen % 2 == 0: + progress_bar = "█" * int((gen / generations) * 20) + "░" * (20 - int((gen / generations) * 20)) + print(f"Gen {gen:2d}: [{progress_bar}] {current_best:6.2f} ({action_used})") + + if gen > 0: + old_fitness = max(engine.get_fitness(engine.pop)) if gen > 0 else current_best + reward = self.ga_agent.calculate_reward(old_fitness, current_best, problem) + next_state_key = self.ga_agent.get_state_key(problem, current_best, gen + 1) + self.ga_agent.update_q_value(state_key, action, reward, next_state_key) + self.ga_agent.performance_history.append(reward) + + time.sleep(0.3) + + self.ga_agent.decay_epsilon() + return {'best_fitness': best_fitness} + + def show_tournament_results(self, llm_wins, ga_wins, ties): + print("\n" + "=" * 60) + print("RL TOURNAMENT RESULTS") + print("=" * 60) + print(f"LLM Agent Wins: {llm_wins}") + print(f"GA Agent Wins: {ga_wins}") + print(f"Ties: {ties}") + print() + + if llm_wins > ga_wins: + print(" LLM AGENT WINS THE TOURNAMENT!") + elif ga_wins > llm_wins: + print(" GA AGENT WINS THE TOURNAMENT!") + else: + print("🤝 TOURNAMENT ENDS IN A TIE!") + + print("\nRound-by-Round Results:") + for result in self.tournament_results: + print(f"Round {result['round']}: {result['problem']}") + print(f" LLM: {result['llm_fitness']:.2f} | GA: {result['ga_fitness']:.2f} | Winner: {result['winner']}") + + print("\nAgent Performance Stats:") + llm_stats = self.llm_agent.get_performance_stats() + ga_stats = self.ga_agent.get_performance_stats() + + print(f"LLM Agent - Avg Reward: {llm_stats['avg_reward']:.2f}, Success Rate: {llm_stats['success_rate']:.2f}") + print(f"GA Agent - Avg Reward: {ga_stats['avg_reward']:.2f}, Success Rate: {ga_stats['success_rate']:.2f}") + + print("\n" + "=" * 60) + +if __name__ == "__main__": + arena = RLTournamentArena() + arena.run_session(5) diff --git a/submissions/Daanish-Mehra/tournament_mode.py b/submissions/Daanish-Mehra/tournament_mode.py new file mode 100644 index 0000000..0b6133e --- /dev/null +++ b/submissions/Daanish-Mehra/tournament_mode.py @@ -0,0 +1,196 @@ +import numpy as np +import json +import random +import time +from lib.algo.ga import EnhancedGAEngine +from lib.ai.llm import EnhancedLLMSolver +from lib.rl.rl_agent import RL_agent + +class TournamentMode: + def __init__(self): + self.problems = self.load_problems() + self.llm_agent = RL_agent("llm") + self.ga_agent = RL_agent("ga") + self.llm_solver = EnhancedLLMSolver() + self.tournament_results = [] + + print("=" * 60) + print("TOURNAMENT MODE - LLM vs GA COMPETITION") + print("=" * 60) + print("Loading AI agents...") + print("LLM Agent: Ready for battle!") + print("GA Agent: Ready for battle!") + print() + + def load_problems(self): + with open('lib/problems/probs.json', 'r') as f: + return json.load(f) + + def run_tournament(self, num_rounds=5): + print(f"Starting {num_rounds} round tournament...") + print("=" * 60) + + llm_wins = 0 + ga_wins = 0 + ties = 0 + + for round_num in range(num_rounds): + print(f"\nROUND {round_num + 1}/{num_rounds}") + print("-" * 40) + + problem = random.choice(self.problems[:20]) + print(f"Problem: {problem['name']}") + print(f"Type: {problem['type'].upper()}") + print(f"Difficulty: {problem['difficulty'].upper()}") + print() + + llm_result = self.run_llm_agent(problem, round_num) + ga_result = self.run_ga_agent(problem, round_num) + + print(f"LLM Agent: {llm_result['best_fitness']:.2f}") + print(f"GA Agent: {ga_result['best_fitness']:.2f}") + + if llm_result['best_fitness'] > ga_result['best_fitness']: + llm_wins += 1 + winner = "LLM Agent" + elif ga_result['best_fitness'] > llm_result['best_fitness']: + ga_wins += 1 + winner = "GA Agent" + else: + ties += 1 + winner = "TIE" + + print(f"Winner: {winner}") + print("-" * 40) + + self.tournament_results.append({ + 'round': round_num + 1, + 'problem': problem['name'], + 'llm_fitness': llm_result['best_fitness'], + 'ga_fitness': ga_result['best_fitness'], + 'winner': winner + }) + + self.show_tournament_results(llm_wins, ga_wins, ties) + return llm_wins, ga_wins, ties + + def run_llm_agent(self, problem, round_num): + engine = EnhancedGAEngine(problem) + best_fitness = 0 + generations = 10 + + print("LLM Agent Evolution:") + for gen in range(generations): + fitness = engine.get_fitness(engine.pop) + current_best = max(fitness) + best_fitness = max(best_fitness, current_best) + + state_key = self.llm_agent.get_state_key(problem, current_best, gen) + action = self.llm_agent.get_action(state_key, ["use_llm", "use_ga"]) + + if action == "use_llm": + llm_candidates = self.llm_solver.get_candidates(problem, engine.pop, 3) + engine.pop = engine.next_gen(engine.pop, llm_candidates) + action_used = "LLM" + else: + engine.pop = engine.next_gen(engine.pop) + action_used = "GA" + + if gen % 2 == 0: + progress_bar = "█" * int((gen / generations) * 20) + "░" * (20 - int((gen / generations) * 20)) + print(f"Gen {gen:2d}: [{progress_bar}] {current_best:6.2f} ({action_used})") + + if gen > 0: + old_fitness = max(engine.get_fitness(engine.pop)) if gen > 0 else current_best + reward = self.llm_agent.calculate_reward(old_fitness, current_best, problem) + next_state_key = self.llm_agent.get_state_key(problem, current_best, gen + 1) + self.llm_agent.update_q_value(state_key, action, reward, next_state_key) + self.llm_agent.performance_history.append(reward) + + time.sleep(0.3) + + self.llm_agent.decay_epsilon() + return {'best_fitness': best_fitness} + + def run_ga_agent(self, problem, round_num): + engine = EnhancedGAEngine(problem) + best_fitness = 0 + generations = 10 + + print("GA Agent Evolution:") + for gen in range(generations): + fitness = engine.get_fitness(engine.pop) + current_best = max(fitness) + best_fitness = max(best_fitness, current_best) + + state_key = self.ga_agent.get_state_key(problem, current_best, gen) + action = self.ga_agent.get_action(state_key, ["mutate", "crossover", "both"]) + + if action == "mutate": + for i in range(len(engine.pop)): + if random.random() < 0.7: + engine.pop[i] = engine.mutate(engine.pop[i]) + action_used = "MUTATE" + elif action == "crossover": + for i in range(0, len(engine.pop), 2): + if i + 1 < len(engine.pop): + engine.pop[i], engine.pop[i+1] = engine.cross(engine.pop[i], engine.pop[i+1]) + action_used = "CROSS" + else: + for i in range(len(engine.pop)): + if random.random() < 0.7: + engine.pop[i] = engine.mutate(engine.pop[i]) + for i in range(0, len(engine.pop), 2): + if i + 1 < len(engine.pop): + engine.pop[i], engine.pop[i+1] = engine.cross(engine.pop[i], engine.pop[i+1]) + action_used = "BOTH" + + if gen % 2 == 0: + progress_bar = "█" * int((gen / generations) * 20) + "░" * (20 - int((gen / generations) * 20)) + print(f"Gen {gen:2d}: [{progress_bar}] {current_best:6.2f} ({action_used})") + + if gen > 0: + old_fitness = max(engine.get_fitness(engine.pop)) if gen > 0 else current_best + reward = self.ga_agent.calculate_reward(old_fitness, current_best, problem) + next_state_key = self.ga_agent.get_state_key(problem, current_best, gen + 1) + self.ga_agent.update_q_value(state_key, action, reward, next_state_key) + self.ga_agent.performance_history.append(reward) + + time.sleep(0.3) + + self.ga_agent.decay_epsilon() + return {'best_fitness': best_fitness} + + def show_tournament_results(self, llm_wins, ga_wins, ties): + print("\n" + "=" * 60) + print("TOURNAMENT RESULTS") + print("=" * 60) + print(f"LLM Agent Wins: {llm_wins}") + print(f"GA Agent Wins: {ga_wins}") + print(f"Ties: {ties}") + print() + + if llm_wins > ga_wins: + print(" LLM AGENT WINS THE TOURNAMENT!") + elif ga_wins > llm_wins: + print(" GA AGENT WINS THE TOURNAMENT!") + else: + print("🤝 TOURNAMENT ENDS IN A TIE!") + + print("\nRound-by-Round Results:") + for result in self.tournament_results: + print(f"Round {result['round']}: {result['problem']}") + print(f" LLM: {result['llm_fitness']:.2f} | GA: {result['ga_fitness']:.2f} | Winner: {result['winner']}") + + print("\nAgent Performance Stats:") + llm_stats = self.llm_agent.get_performance_stats() + ga_stats = self.ga_agent.get_performance_stats() + + print(f"LLM Agent - Avg Reward: {llm_stats['avg_reward']:.2f}, Success Rate: {llm_stats['success_rate']:.2f}") + print(f"GA Agent - Avg Reward: {ga_stats['avg_reward']:.2f}, Success Rate: {ga_stats['success_rate']:.2f}") + + print("\n" + "=" * 60) + +if __name__ == "__main__": + tournament = TournamentMode() + tournament.run_tournament(5)