CoolFace
Apppublic

bbqddt2/Antigravity

sourceHugging Faceupdated 2mo agoView on Hugging Face
0likes
orchestrate.py339 linesDownload Raw Back to root
1# -*- coding: utf-8 -*-2"""3Antigravity 统一编排入口4 5用法:6    python orchestrate.py              # 运行全部引擎 + 因果验证 + 保存统一输出7    python orchestrate.py --engine luckcast  # 只运行 Luckcast8    python orchestrate.py --engine enhanced    # 只运行 Enhanced9    python orchestrate.py --causal-only        # 只运行因果验证报告10"""11 12import json13import sys14import time15import logging16from pathlib import Path17from datetime import datetime18from typing import List, Dict, Optional19 20# Fix Windows GBK21if sys.stdout.encoding and sys.stdout.encoding.lower() != "utf-8":22    sys.stdout.reconfigure(encoding="utf-8")23 24_PROJECT_ROOT = Path(__file__).resolve().parent25sys.path.insert(0, str(_PROJECT_ROOT))26 27from data_layer import load_history, Draw28 29logger = logging.getLogger("Orchestrator")30logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")31 32 33# ─── 引擎调用器 ─────────────────────────────────────────────34 35def run_luckcast(draws: List[Draw], top_k: int = 5) -> Optional[List[Dict]]:36    """运行 Luckcast V15 预测引擎"""37    try:38        from luckcast_antigravity_v1 import rank_candidates39        results = rank_candidates(draws, n_candidates=1000, top_k=top_k)40        return [41            {42                "engine": "Luckcast V15",43                "reds": list(r[0]),44                "blue": int(r[1]),45                "scores": {k: float(v) for k, v in r[2].items()},46            }47            for r in results48        ]49    except Exception as e:50        logger.error(f"Luckcast V15 失败: {e}")51        return None52 53 54def run_enhanced(draws: List[Draw], top_k: int = 5) -> Optional[List[Dict]]:55    """运行 Enhanced Predictor V2.0"""56    try:57        # 临时加载 DataFrame58        import pandas as pd59        csv_file = _PROJECT_ROOT / "data" / "lottery_history.csv"60        df = pd.read_csv(csv_file)61 62        from enhanced_predictor import WeightedEnsemble, parse_reds63        ensemble = WeightedEnsemble(df)64        preds = ensemble.generate(num_groups=top_k)65        return [66            {67                "engine": "Enhanced V2.0",68                "strategy": p.get("strategy", ""),69                "reds": list(p["reds"]),70                "blue": int(p["blue"]),71                "scores": {72                    "causal_valid": p.get("causal_valid", True),73                    "causal_multiplier": p.get("causal_multiplier", 1.0),74                },75            }76            for p in preds77        ]78    except Exception as e:79        logger.error(f"Enhanced Predictor 失败: {e}")80        return None81 82 83def run_evolution_life(draws: List[Draw], top_k: int = 1) -> Optional[List[Dict]]:84    """运行 Evolution Life (RF+Spectral)"""85    try:86        import importlib.util87        spec = importlib.util.spec_from_file_location("evolution_life", _PROJECT_ROOT / "evolution_life.py")88        mod = importlib.util.module_from_spec(spec)89        spec.loader.exec_module(mod)90        result = mod.run_prediction()91        if result and "predictions" in result:92            return result["predictions"]93        return [{"engine": "Evolution Life", "reds": [], "blue": 0, "scores": {}}]94    except Exception as e:95        logger.error(f"Evolution Life 失败: {e}")96        return None97 98 99# ─── 因果验证器 ─────────────────────────────────────────────100 101def causal_verify_all(predictions: List[Dict]) -> List[Dict]:102    """对一组预测做完整的因果验证报告"""103    try:104        from core.causal_reasoning import CausalAnalyzer105        analyzer = CausalAnalyzer()106    except ImportError:107        return predictions108 109    verified = []110    for p in predictions:111        reds = p.get("reds", [])112        blue = p.get("blue", 0)113        reds_str = ", ".join(str(r) for r in reds)114        result = analyzer.evaluate_causality(reds_str, str(blue))115 116        p["causal_status"] = result.get("status", "unknown")117        p["causal_multiplier"] = result.get("confidence_multiplier", 1.0)118        p["causal_warnings"] = result.get("warnings", [])119        p["causal_metrics"] = result.get("metrics", {})120        verified.append(p)121 122    return verified123 124 125# ─── 融合引擎 ───────────────────────────────────────────────126 127def fuse_predictions(all_results: Dict[str, List[Dict]]) -> List[Dict]:128    """129    多引擎结果融合。130    策略: 对所有引擎预测的号码做跨引擎共振计数 + 因果加权。131    """132    from collections import Counter133 134    # 收集所有预测135    all_preds = []136    for engine_name, preds in all_results.items():137        if preds:138            for p in preds:139                p["_engine"] = engine_name140                all_preds.append(p)141 142    if not all_preds:143        return []144 145    # 按红球组合分组(忽略蓝球)146    combo_counter: Counter = Counter()147    combo_map: Dict[tuple, List[Dict]] = {}148    for p in all_preds:149        key = tuple(p["reds"])150        combo_counter[key] += 1151        if key not in combo_map:152            combo_map[key] = []153        combo_map[key].append(p)154 155    # 跨引擎共振的组合得分更高156    fused = []157    for combo, count in combo_counter.most_common(20):158        if count < 2:159            continue  # 只保留至少2个引擎都推荐的组合160        candidates = combo_map[combo]161        # 取蓝球得票最多的162        blue_counter = Counter()163        best_score = 0164        for c in candidates:165            b = c.get("blue", 0)166            s = c.get("scores", {})167            total = s.get("total_score", s.get("causal_multiplier", 0))168            blue_counter[b] += total169            best_score += total170 171        best_blue = blue_counter.most_common(1)[0][0] if blue_counter else 0172 173        fused.append({174            "engine": f"Fusion({count} engines)",175            "reds": list(combo),176            "blue": int(best_blue),177            "cross_engine_support": count,178            "fused_score": round(best_score, 4),179            "contributing_engines": [c.get("_engine", "") for c in candidates],180        })181 182    return fused183 184 185# ─── 主流程 ─────────────────────────────────────────────────186 187def run_full_pipeline(top_k: int = 5) -> Dict:188    """完整流水线: 数据加载 → 多引擎预测 → 因果验证 → 融合 → 保存"""189    start = time.time()190    logger.info("=" * 60)191    logger.info("  Antigravity 统一编排系统 V1.0")192    logger.info("=" * 60)193 194    # 1. 加载数据195    draws = load_history()196    latest = draws[-1]197    target = latest.period + 1198    logger.info(f"数据: {len(draws)} 期 | 最新: #{latest.period} | 目标: #{target}")199 200    # 2. 运行引擎201    all_results: Dict[str, List[Dict]] = {}202 203    engines = {204        "Luckcast V15": run_luckcast,205        "Enhanced V2.0": run_enhanced,206    }207 208    for name, runner in engines.items():209        logger.info(f"🚀 启动 {name}...")210        t0 = time.time()211        results = runner(draws, top_k=top_k)212        elapsed = time.time() - t0213        if results:214            all_results[name] = results215            logger.info(f"✅ {name}: {len(results)} 组预测 ({elapsed:.1f}s)")216        else:217            logger.warning(f"❌ {name}: 失败")218 219    # 3. 因果验证220    logger.info("\n🔬 因果验证...")221    verified_results = {}222    for name, preds in all_results.items():223        verified_results[name] = causal_verify_all(preds)224 225    # 4. 融合226    logger.info("\n🔗 多引擎融合...")227    fused = fuse_predictions(verified_results)228    if fused:229        logger.info(f"✅ 融合结果: {len(fused)} 组跨引擎共振号码")230    else:231        logger.info("⚠️ 无跨引擎共振组合")232 233    # 5. 保存统一输出234    output = {235        "target_period": target,236        "timestamp": datetime.now().isoformat(),237        "data_periods": len(draws),238        "latest_period": latest.period,239        "latest_actual": {240            "reds": list(latest.reds),241            "blue": latest.blue,242        },243        "engines": {244            name: {245                "status": "ok" if preds else "fail",246                "count": len(preds) if preds else 0,247                "predictions": preds,248            }249            for name, preds in verified_results.items()250        },251        "fusion": fused,252        "elapsed_seconds": round(time.time() - start, 2),253    }254 255    # 保存标准格式256    output_path = _PROJECT_ROOT / "latest_prediction.json"257    with open(output_path, "w", encoding="utf-8") as f:258        json.dump(output, f, ensure_ascii=False, indent=2)259 260    # 同时保存兼容旧格式的 latest_decision.json261    if fused:262        best = fused[0]263        legacy = {264            "period": str(target),265            "red": best["reds"],266            "blue": best["blue"],267            "engine": "Fusion",268            "scores": {"fused_score": best.get("fused_score", 0)},269        }270    elif verified_results:271        # 取第一个引擎的第一组272        first_engine = list(verified_results.keys())[0]273        first_pred = verified_results[first_engine][0]274        legacy = {275            "period": str(target),276            "red": first_pred["reds"],277            "blue": first_pred["blue"],278            "engine": first_engine,279            "scores": first_pred.get("scores", {}),280        }281    else:282        legacy = {"period": str(target), "red": [], "blue": 0, "engine": "none"}283 284    legacy_path = _PROJECT_ROOT / "latest_decision.json"285    with open(legacy_path, "w", encoding="utf-8") as f:286        json.dump(legacy, f, ensure_ascii=False, indent=2)287 288    # 6. 打印报告289    logger.info(f"\n{'='*60}")290    logger.info(f"  预测结果 - 第 {target} 期")291    logger.info(f"{'='*60}")292 293    for name, preds in verified_results.items():294        logger.info(f"\n  [{name}]")295        for p in preds[:3]:  # 只显示前3组296            reds = ", ".join(f"{r:02d}" for r in p.get("reds", []))297            blue = f"{p.get('blue', 0):02d}"298            causal = p.get("causal_status", "?")299            mult = p.get("causal_multiplier", 1.0)300            logger.info(f"    🔴[{reds}] 🔵{blue} | 因果:{causal} (x{mult:.2f})")301 302    if fused:303        logger.info(f"\n  [融合结果]")304        for p in fused[:3]:305            reds = ", ".join(f"{r:02d}" for r in p.get("reds", []))306            blue = f"{p.get('blue', 0):02d}"307            support = p.get("cross_engine_support", 0)308            logger.info(f"    🔴[{reds}] 🔵{blue} | 跨引擎支持:{support} 引擎:{p.get('contributing_engines', [])}")309 310    logger.info(f"\n✅ 总耗时: {output['elapsed_seconds']}s")311    logger.info(f"📄 输出: {output_path}")312 313    return output314 315 316# ─── CLI ────────────────────────────────────────────────────317 318if __name__ == "__main__":319    import argparse320    parser = argparse.ArgumentParser(description="Antigravity 统一编排系统")321    parser.add_argument("--engine", choices=["luckcast", "enhanced", "all"], default="all")322    parser.add_argument("--top-k", type=int, default=5, help="每组预测几组号码")323    parser.add_argument("--causal-only", action="store_true", help="只运行因果验证")324    args = parser.parse_args()325 326    draws = load_history()327 328    if args.causal_only:329        logger.info("因果验证器独立运行模式")330        from core.causal_reasoning import CausalAnalyzer331        analyzer = CausalAnalyzer()332        # 测试最近10期333        for d in draws[-10:]:334            reds_str = ", ".join(str(r) for r in d.reds)335            result = analyzer.evaluate_causality(reds_str, str(d.blue))336            logger.info(f"#{d.period}: {d.reds} + {d.blue} → {result['status']} (x{result['confidence_multiplier']:.2f})")337    else:338        run_full_pipeline(top_k=args.top_k)339