diff --git a/app/app.py b/app/app.py index b8583a5..6939c67 100644 --- a/app/app.py +++ b/app/app.py @@ -630,9 +630,7 @@ def main(): ) all_results.append({"smiles": smiles, "results": results}) - # 为多 SMILES 模式添加 SMILES 标签 - smiles_label = smiles[:30] + "..." if len(smiles) > 30 else smiles - df = format_results_dataframe(results, smiles_label if is_multi_smiles else None) + df = format_results_dataframe(results, smiles if is_multi_smiles else None) all_dfs.append(df) except httpx.HTTPStatusError as e: @@ -727,7 +725,7 @@ def main(): with col_export: smiles_used = st.session_state.get("smiles_used", "") if isinstance(smiles_used, list): - smiles_used = ",".join(smiles_used) + smiles_used = " | ".join(smiles_used) csv_content = create_export_csv( df, @@ -754,6 +752,13 @@ def main(): use_container_width=True, hide_index=True, height=600, + column_config={ + "SMILES": st.column_config.TextColumn( + "SMILES", + width="medium", + help="界面上按列宽省略显示,可拖动列头加宽;导出的 CSV 中为完整字符串", + ), + }, ) # 详细信息 diff --git a/app/optimize.py b/app/optimize.py index 605f47a..ff0ebf5 100644 --- a/app/optimize.py +++ b/app/optimize.py @@ -897,6 +897,7 @@ def optimize( logger.info(f"Comp ranges: {comp_ranges.to_dict()}") seeds = None + global_pool: List[Formulation] = [] _has_llm = getattr(model, "llm_prompt", None) is not None _do_rerank = bool(_has_llm and rerank_top_n and rerank_top_n > 0) @@ -933,8 +934,13 @@ def optimize( # 选择 top num_seeds 个种子点 seeds = select_top_k(df, organ, num_seeds, scoring_weights) - - logger.info(f"Selected {len(seeds)} seeds for next iteration") + + global_pool = select_top_k( + df, organ, max(num_seeds, top_k * 10), scoring_weights + ) + + logger.info(f"Selected {len(seeds)} seeds for next iteration " + f"(global pool: {len(global_pool)})") else: # ==================== 后续迭代:层级局部搜索 ==================== @@ -999,7 +1005,20 @@ def optimize( logger.info(f"Stage-1: {len(unique_results)} unique formulations (from {len(seeds)} candidates)") - if not _do_rerank: + if len(unique_results) < top_k and global_pool: + n_before = len(unique_results) + for f in global_pool: + if len(unique_results) >= top_k: + break + key = f.unique_key() + if key not in seen_keys: + seen_keys.add(key) + unique_results.append(f) + if len(unique_results) > n_before: + logger.warning( + f"局部搜索收敛至 {n_before} 个不同配方(请求 {top_k} 个)," + f"已从粗筛池回填 {len(unique_results) - n_before} 个未细化候选" + ) return unique_results[:top_k] # ==================== 第二阶段:完整模型重排 ====================