import numpy as np
import time
import os
import re
import json

# EVOLVE-BLOCK-START

def read_distance_matrix_from_file(file_path: str) -> np.ndarray:
    """从.txt文件中直接读取预计算的距离矩阵。"""
    matrix_rows = []
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                # 跳过空行或非数字开头的行（如标题或最优解行）
                if not line or not line[0].isdigit():
                    continue
                
                try:
                    row = [float(num) for num in line.split()]
                    if row:
                        matrix_rows.append(row)
                except ValueError:
                    # 跳过无法完全转换为数字的行
                    continue
    except FileNotFoundError:
        raise

    if not matrix_rows:
        raise ValueError(f"未能从文件 '{os.path.basename(file_path)}' 中解析任何矩阵数据。")

    return np.array(matrix_rows, dtype=int)


def parse_optimal_distance_from_file(file_path: str) -> float | None:
    """从文件中解析预存的最优距离。"""
    pattern = re.compile(r"Total Distance:\s*([\d.]+)")
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in reversed(f.readlines()):
                match = pattern.search(line)
                if match:
                    return float(match.group(1))
    except (FileNotFoundError, IOError):
        return None
    return None

# EVOLVE-BLOCK-START
def solve_tsp_approximate(dist_matrix: np.ndarray) -> tuple[list, float]:
    """
    使用最近邻启发式算法解决TSP问题。
    """
    n = dist_matrix.shape[0]
    if n == 0:
        return [], 0.0

    start_city = 0
    unvisited_cities = set(range(n))
    tour = [start_city]
    unvisited_cities.remove(start_city)
    current_city = start_city
    total_distance = 0.0

    while unvisited_cities:
        nearest_city = min(
            unvisited_cities,
            key=lambda city: dist_matrix[current_city, city]
        )
        total_distance += dist_matrix[current_city, nearest_city]
        current_city = nearest_city
        tour.append(current_city)
        unvisited_cities.remove(current_city)
    
    total_distance += dist_matrix[current_city, start_city]
    
    return tour, total_distance

# EVOLVE-BLOCK-END
if __name__ == "__main__":
    folder_path = 'all'
    
    if not os.path.isdir(folder_path):
        print(f"❌ 错误: 文件夹 '{folder_path}' 不存在。")
        exit()

    errors = []
    results_data = []  # 用于存储所有结果的列表
    total_start_time = time.time()

    # 修改为处理 .txt 文件
    print(f"🚀 开始处理文件夹 '{os.path.abspath(folder_path)}' 中的所有 .txt 文件...")
    
    problem_files = [f for f in os.listdir(folder_path) if f.endswith(".txt")]
    
    if not problem_files:
        print("⚠️ 未在该文件夹中找到任何 .txt 文件。")
        exit()

    for filename in sorted(problem_files):
        file_path = os.path.join(folder_path, filename)
        
        print("\n" + "-"*50)
        print(f"处理文件: {filename}")

        try:
            optimal_distance = parse_optimal_distance_from_file(file_path)
            if optimal_distance is None:
                print("   -> ⚠️ 警告: 未在该文件中找到预存的最优解，跳过此文件。")
                continue
            
            # 直接从文件读取距离矩阵
            dist_matrix = read_distance_matrix_from_file(file_path)
            
            heuristic_tour, heuristic_distance = solve_tsp_approximate(dist_matrix)
            
            error = (heuristic_distance - optimal_distance) / optimal_distance
            errors.append(error)

            # 将结果存入字典
            result_entry = {
                "filename": filename,
                "optimal_distance": optimal_distance,
                "heuristic_distance": heuristic_distance,
                "error": error
            }
            results_data.append(result_entry)
            
            print(f"   -> 最优解 (文件内): {optimal_distance:.2f}")
            print(f"   -> 本代码结果: {heuristic_distance:.2f}")
            print(f"   -> 本次误差: {error:.2%}")

        except Exception as e:
            print(f"   -> ❌ 处理文件时发生错误: {e}")

    # --- 保存结果到 JSON 文件 ---
    json_output_path = os.path.join(folder_path, 'initial_solution_result.json')
    print("\n" + "-"*50)
    print(f"💾 正在将详细结果保存到 {json_output_path}...")
    try:
        with open(json_output_path, 'w', encoding='utf-8') as f:
            json.dump(results_data, f, indent=4, ensure_ascii=False)
        print("   -> ✅ 保存成功。")
    except Exception as e:
        print(f"   -> ❌ 保存JSON文件失败: {e}")


    # --- 最终结果汇总 ---
    total_execution_time = time.time() - total_start_time
    print("\n" + "="*50)
    print("🎉 所有文件处理完毕，结果如下:")
    print("="*50)
    
    if errors:
        average_error = np.mean(errors)
        print(f"处理文件总数: {len(errors)}")
        print(f"平均误差: {average_error:.2%}")
    else:
        print("未成功计算任何文件的误差。")

    print(f"总运行时间: {total_execution_time:.4f} 秒")

