├── .env.example ├── .gitignore ├── .python-version ├── README.md ├── README_CN.md ├── assets ├── MCP.gif ├── dynamic.gif ├── mcp_client.png ├── pic1_2.PNG └── pic2_1.PNG ├── data ├── analyze_types_problems.py ├── datasets │ ├── complexor_combined_result.json │ ├── dataset_combined_result.json │ ├── dataset_combined_result_mark.json │ ├── dataset_md_result.json │ ├── lpwp_combined_result.json │ └── question_lengths.txt ├── images │ ├── problems_distribution_pie.png │ ├── problems_distribution_pie_no_text.png │ ├── question_length_histogram.png │ └── types_distribution.png ├── process_complexor_dataset.py ├── process_dataset.py ├── process_lpwp_dataset.py ├── question_length.py └── save_json.py ├── mcp_server.py ├── or_llm_eval.py ├── or_llm_eval_async.py ├── or_llm_show.py ├── pyproject.toml ├── requirements.txt ├── utils.py └── uv.lock /.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY="your_openai_api_key" 2 | OPENAI_API_BASE="your_openai_api_base" 3 | CLAUDE_API_KEY="your_claude_api_key" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | 110 | # pdm 111 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 112 | #pdm.lock 113 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 114 | # in version control. 115 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 116 | .pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 121 | __pypackages__/ 122 | 123 | # Celery stuff 124 | celerybeat-schedule 125 | celerybeat.pid 126 | 127 | # SageMath parsed files 128 | *.sage.py 129 | 130 | # Environments 131 | .env 132 | .venv 133 | env/ 134 | venv/ 135 | ENV/ 136 | env.bak/ 137 | venv.bak/ 138 | 139 | # Spyder project settings 140 | .spyderproject 141 | .spyproject 142 | 143 | # Rope project settings 144 | .ropeproject 145 | 146 | # mkdocs documentation 147 | /site 148 | 149 | # mypy 150 | .mypy_cache/ 151 | .dmypy.json 152 | dmypy.json 153 | 154 | # Pyre type checker 155 | .pyre/ 156 | 157 | # pytype static type analyzer 158 | .pytype/ 159 | 160 | # Cython debug symbols 161 | cython_debug/ 162 | 163 | # PyCharm 164 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 165 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 166 | # and can be added to the global gitignore or merged into this file. For a more nuclear 167 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 168 | #.idea/ 169 | 170 | # PyPI configuration file 171 | .pypirc 172 | 173 | .DS_Store 174 | 175 | data/results 176 | 177 | data/datasets/LPWP 178 | 179 | data/datasets/ComplexOR 180 | 181 | model.ilp -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.10 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | OR-LLM-Agent: Automating Modeling and Solving of Operations Research Optimization Problem with Reasoning Large Language Model 5 |

6 | 7 | [Chinese Version 中文版本](./README_CN.md) 8 | 9 |

arXiv GitHub

10 | 11 | ![](assets/dynamic.gif?autoplay=1) 12 |
13 | 14 | 15 | 16 |
17 | 18 | ## Abstract 19 | Operations Research (OR) has been widely applied in various fields such as resource allocation, production planning, and supply chain management. However, addressing real-world OR problems requires OR experts to perform mathematical modeling and programmers to develop solution algorithms. This traditional method, heavily reliant on experts, is costly and has long development cycles, severely limiting the widespread adoption of OR techniques. Few have considered using Artificial Intelligence (AI) to replace professionals to achieve fully automated solutions for OR problems. We proposed OR-LLM-Agent, the AI agent that enables end-to-end automation for solving real-world OR problems. OR-LLM-Agent leverages the Chain-of-Thought (CoT) reasoning capabilities of Large Language Models (LLMs) to translate natural language problem descriptions into formal mathematical models and automatically generate Gurobi solver code. In OR-LLM-Agent, OR-CodeAgent is designed to automate code execution and repair within a sandbox environment, facilitating the derivation of the final solution. Due to the lack of dedicated benchmark datasets for evaluating the automated solving of OR problems, we construct a benchmark dataset comprising 83 real-world OR problems described in natural language. We conduct comparative experiments with state-of-the-art (SOTA) reasoning LLMs, including GPT-o3-mini, DeepSeek-R1, and Gemini 2.0 Flash Thinking. The OR-LLM-Agent achieved the highest pass rate of 100% and the highest solution accuracy of 85%, demonstrating the feasibility of automated OR problem-solving. 20 |

21 | 22 | ## Introduction 📖 23 | 24 | Companies have traditionally relied on OR experts to develop specialized models for complex optimization problems, ensuring rigorous and tailored solutions. However, this approach is costly and slow, and even well-defined models face implementation challenges, as effective use of solvers like Gurobi and CPLEX demands advanced programming and debugging skills. 25 | 26 | or-llm-agent 27 | 28 | We propose OR-LLM-Agent, a reasoning LLM-based framework for fully automated OR optimization. OR-LLM-Agent converts a natural language problem description into a mathematical model, generates and executes the solution code, and thus facilitates an end-to-end automation pipeline from OR problem description to the solution. OR-LLM-Agent comprises modules for user problem description input, LLM mathematical modeling, LLM code generation, and OR-CodeAgent. The LLM mathematical modeling module constructs linear programming models for the OR problem. The LLM code generation module produces OR solver code based on the mathematical model. OR-CodeAgent ensures automated code execution and repair to obtain the final solution. The framework of OR-LLM-Agent is shown in following figure. 29 | 30 | or-llm-agent 31 | 32 |

33 | 34 | ## Installation 35 | ### Prerequisites 36 | - Python 3.8+ 37 | - Gurobi Optimizer 38 | 39 | ### Installation Steps 40 | ```bash 41 | # Clone the repository 42 | git https://github.com/bwz96sco/or_llm_agent.git 43 | cd or_llm_agent 44 | 45 | # Install package 46 | pip install -r requirements.txt 47 | ``` 48 | 49 | ### Getting Started 50 | ```bash 51 | # Start to evaluate current dataset 52 | python or_llm_eval.py --agent 53 | 54 | #if you do not sepcify agent argument, you can use the LLM to solve problems directly 55 | python or_llm_eval.py 56 | 57 | #you can also specify the model 58 | python or_llm_eval.py --agent --model gpt-4o-mini-2024-07-18 59 | 60 | #use async methods to run tasks parallelly 61 | python or_llm_eval_async.py --agent 62 | ``` 63 | Make sure to setup your OpenAI API key in `.env` file! 64 | 65 | ```bash 66 | #setup a .env file 67 | cp .env.example .env 68 | ``` 69 | 70 | You need to set the OPENAI_API_KEY and OPENAI_API_BASE url(if you want to use OpenAI compatible service). You will also need to set the CLAUDE_API_KEY if you want to use claude model. If you want to use the DeepSeek model, I recommend you to use the Volcengine(you can get a tutorial from https://www.volcengine.com/docs/82379/1449737), set the OPENAI_API_KEY to Api Key provided by volcengine and set OPENAI_API_BASE to "https://ark.cn-beijing.volces.com/api/v3". 71 | 72 |


73 | 74 | 75 | ## Create Dataset 76 | 77 | We have already set a dataset under the data/datasets directory for you, you can create your own dataset by the save_json.py, you need to paste your questions and answers in the file manually: 78 | 79 | ```python 80 | #save dataset to a json file 81 | python data/save_json.py 82 | ``` 83 | 84 | You can also get statistic graph for datasets: 85 | 86 | ```bash 87 | #get the length distribution 88 | python data/question_length.py 89 | ``` 90 | 91 |

92 | 93 | ## Set up MCP Server & Client 94 | 95 |
96 | MCP Demo 97 |
98 | 99 | We also add a Model Context Protocol(MCP) server to facilitate the utilization of this tool. According to the official document from claude MCP website, we recommend using the `uv` package manager to set up the MCP server. 100 | 101 | ```bash 102 | # Create virtual environment and activate it 103 | uv venv 104 | source .venv/bin/activate 105 | 106 | #install package 107 | uv add -r requirements.txt 108 | ``` 109 | 110 | For using in the MCP client, here we use the Claude desktop Client as an example, first you need to add MCP path to the `claude_desktop_config.json`: 111 | 112 | ```python 113 | { 114 | "mcpServers": { 115 | "Optimization": { 116 | "command": "/{ABSOLUTE PATH TO UV INSTALLED FOLDER}/uv", 117 | "args": [ 118 | "--directory", 119 | "/{ABSOLUTE PATH TO OR-LLM-AGENT FOLDER}", 120 | "run", 121 | "mcp_server.py.py" 122 | ] 123 | } 124 | } 125 | } 126 | ``` 127 | 128 | Then you can open the Claude desktop Client, check if there is a `get_operation_research_problem_answer` in the hammer icon. 129 | 130 | mcp_client 131 | 132 |

133 | 134 | 135 | ## Authors 136 | - **Bowen Zhang**¹ * (bowen016@e.ntu.edu.sg) 137 | - **Pengcheng Luo**²³ * 138 | 139 | ¹ Nanyang Technological University, Singapore. 140 | ² Ningbo Artificial Intelligence Institute, Shanghai Jiao Tong University, Ningbo, PR, China. 141 | ³ Department of Automation, Shanghai Jiao Tong University, Shanghai, PR China
142 | \* Equal contribution 143 |

144 | 145 | --- 146 |

147 | Made at Shanghai Jiao Tong University and Nanyang Technological University 148 |

149 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | OR-LLM-Agent:基于大型语言模型推理的运筹优化问题建模与求解自动化 5 |

6 | 7 | [英文版本 English Version](./README.md) 8 | 9 |

arXiv GitHub

10 | 11 | ![](assets/dynamic.gif?autoplay=1) 12 |
13 | 14 | 15 | 16 |
17 | 18 | ## 摘要 19 | 运筹学(Operations Research, OR)已被广泛应用于资源分配、生产计划、供应链管理等多个领域。然而,解决实际的运筹优化问题通常需要运筹专家进行数学建模,并由程序员开发求解算法。这种高度依赖专家的传统方法成本高、开发周期长,严重限制了运筹技术的普及应用。当前鲜有尝试使用人工智能(AI)替代专家实现运筹问题的全自动求解。为此,我们提出了 OR-LLM-Agent —— 一个可以实现真实运筹问题端到端自动求解的 AI 智能体。OR-LLM-Agent 利用大型语言模型(LLMs)的链式思维(Chain-of-Thought, CoT)推理能力,将自然语言描述的问题自动转化为数学模型,并自动生成 Gurobi 求解器代码。在 OR-LLM-Agent 中,我们设计了 OR-CodeAgent,用于在沙箱环境中自动执行与修复代码,从而求解最终结果。由于缺乏专门用于评估运筹自动化求解的基准数据集,我们构建了一个包含 83 个真实自然语言描述的运筹问题的基准集。我们与当前先进的推理型 LLM(如 GPT-o3-mini、DeepSeek-R1 和 Gemini 2.0 Flash Thinking)进行了对比实验。OR-LLM-Agent 实现了 100% 的最高通过率和 85% 的最高解答准确率,验证了自动化求解运筹问题的可行性。 20 | 21 |

22 | 23 | ## 简介 📖 24 | 25 | 传统上,企业依赖运筹专家为复杂优化问题开发专门模型,以确保解法的严谨性和针对性。然而,这种方式不仅成本高、速度慢,即便构建了良好模型,也常常在实现阶段面临困难——例如使用 Gurobi、CPLEX 等求解器时,需要具备高级编程和调试能力。 26 | 27 | or-llm-agent 28 | 29 | 我们提出了 OR-LLM-Agent —— 一个基于推理型大型语言模型的运筹优化自动化框架。它可将自然语言描述的问题转化为数学模型,生成并执行求解代码,形成从问题描述到求解结果的全自动端到端流程。OR-LLM-Agent 包含以下模块:用户问题描述输入、LLM 数学建模、LLM 代码生成、以及 OR-CodeAgent。其中,LLM 数学建模模块构建线性规划模型;LLM 代码生成模块基于模型生成求解代码;OR-CodeAgent 实现代码的自动执行与修复,输出最终结果。整体框架如下图所示: 30 | 31 | or-llm-agent 32 | 33 |

34 | 35 | ## 安装方法 36 | ### 环境要求 37 | - Python 3.8+ 38 | - Gurobi优化器 39 | 40 | ### 安装步骤 41 | ```bash 42 | # 克隆代码库 43 | git https://github.com/bwz96sco/or_llm_agent.git 44 | cd or_llm_agent 45 | 46 | # 安装依赖 47 | pip install -r requirements.txt 48 | ``` 49 | 50 | ### 快速开始 51 | ```bash 52 | # 启动评估现有数据集 53 | python or_llm_eval.py --agent 54 | 55 | # 如果不指定 agent 参数,模型将直接用于求解 56 | python or_llm_eval.py 57 | 58 | # 你也可以指定使用的模型 59 | python or_llm_eval.py --agent --model gpt-4o-mini-2024-07-18 60 | 61 | # 使用异步方式并行运行任务 62 | python or_llm_eval_async.py --agent 63 | ``` 64 | 65 | 请确保在 `.env` 文件中设置你的 OpenAI API 密钥! 66 | 67 | ```bash 68 | # 创建 .env 文件 69 | cp .env.example .env 70 | ``` 71 | 72 | 你需要设置 `OPENAI_API_KEY` 和 `OPENAI_API_BASE`(如果使用 OpenAI 兼容服务)。如果希望使用 Claude 模型,则还需设置 `CLAUDE_API_KEY`。若使用 DeepSeek 模型,推荐通过火山引擎(Volcengine)接入(教程见 https://www.volcengine.com/docs/82379/1449737),设置 `OPENAI_API_KEY` 为其提供的 Api Key,并设置 `OPENAI_API_BASE` 为 `https://ark.cn-beijing.volces.com/api/v3`。 73 | 74 |


75 | 76 | ## 创建数据集 77 | 78 | 我们已在 `data/datasets` 目录下提供了一个数据集示例。你可以通过 `save_json.py` 脚本手动粘贴问题和答案,创建自己的数据集: 79 | 80 | ```python 81 | # 将数据保存为 json 格式 82 | python data/save_json.py 83 | ``` 84 | 85 | 你也可以为数据集生成统计图: 86 | 87 | ```bash 88 | # 获取问题长度分布 89 | python data/question_length.py 90 | ``` 91 | 92 |

93 | ## 设置 MCP 服务器与客户端 94 | 95 |
96 | MCP Demo 97 |
98 | 99 | 我们还添加了一个模型上下文协议(Model Context Protocol,简称 MCP)服务器,以便更好地使用此工具。根据 Claude MCP 官网的官方文档,我们推荐使用 `uv` 包管理器来搭建 MCP 服务器。 100 | 101 | ```bash 102 | # 创建虚拟环境并激活 103 | uv venv 104 | source .venv/bin/activate 105 | 106 | # 安装依赖包 107 | uv add -r requirements.txt 108 | ``` 109 | 110 | 为了在 MCP 客户端中使用此功能,我们以 Claude 桌面客户端为例,首先你需要在 `claude_desktop_config.json` 中添加 MCP 路径: 111 | 112 | ```python 113 | { 114 | "mcpServers": { 115 | "Optimization": { 116 | "command": "/{UV 安装文件夹的绝对路径}/uv", 117 | "args": [ 118 | "--directory", 119 | "/{OR-LLM-AGENT 文件夹的绝对路径}", 120 | "run", 121 | "mcp_server.py.py" 122 | ] 123 | } 124 | } 125 | } 126 | ``` 127 | 128 | 然后你就可以打开 Claude 桌面客户端,检查锤子图标中是否出现了`get_operation_research_problem_answer` 项。 129 | 130 | mcp_client 131 | 132 |

133 | 134 | ## 作者 135 | - **张博文**¹ * (bowen016@e.ntu.edu.sg) 136 | - **罗鹏程**²³ * 137 | 138 | ¹ 新加坡南洋理工大学 139 | ² 上海交通大学宁波人工智能研究院 140 | ³ 上海交通大学自动化系 141 | \* 共同第一作者 142 | 143 |

144 | 145 | --- 146 |

147 | 项目由上海交通大学与新加坡南洋理工大学联合完成 148 |

149 | -------------------------------------------------------------------------------- /assets/MCP.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/assets/MCP.gif -------------------------------------------------------------------------------- /assets/dynamic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/assets/dynamic.gif -------------------------------------------------------------------------------- /assets/mcp_client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/assets/mcp_client.png -------------------------------------------------------------------------------- /assets/pic1_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/assets/pic1_2.PNG -------------------------------------------------------------------------------- /assets/pic2_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/assets/pic2_1.PNG -------------------------------------------------------------------------------- /data/analyze_types_problems.py: -------------------------------------------------------------------------------- 1 | import json 2 | from collections import Counter 3 | import matplotlib.pyplot as plt 4 | import matplotlib.colors as mcolors 5 | import matplotlib.font_manager as fm 6 | import numpy as np 7 | 8 | def analyze_json_data(file_path): 9 | # Read the JSON file 10 | with open(file_path, 'r', encoding='utf-8') as file: 11 | data = json.load(file) 12 | 13 | # Initialize counters 14 | types_counter = Counter() 15 | problems_counter = Counter() 16 | 17 | # Count occurrences of each type and problem 18 | for key, item in data.items(): 19 | if isinstance(item, dict) and 'type' in item and 'problem' in item: 20 | types_counter[item['type']] += 1 21 | problems_counter[item['problem']] += 1 22 | 23 | return types_counter, problems_counter 24 | 25 | def print_counts(counter, label): 26 | print(f"\n{label} Distribution:") 27 | print("-" * 50) 28 | for item, count in counter.most_common(): 29 | print(f"{item}: {count}") 30 | print(f"Total unique {label.lower()}: {len(counter)}") 31 | print(f"Total count: {sum(counter.values())}") 32 | 33 | def plot_horizontal_bar(counter, title, filename): 34 | # Get the data sorted by count (highest to lowest) 35 | items_sorted = counter.most_common() 36 | 37 | # Reverse the order so larger values appear at the top when plotted 38 | items_sorted.reverse() 39 | 40 | # Unpack the sorted items 41 | labels, values = zip(*items_sorted) 42 | 43 | # Calculate percentage for each item 44 | total = sum(values) 45 | percentages = [(v/total)*100 for v in values] 46 | 47 | # Set font to Times New Roman for the entire plot 48 | plt.rcParams['font.family'] = 'Times New Roman' 49 | plt.rcParams['font.size'] = 14 # Base font size 50 | 51 | # Set up the plot with a clean, modern style 52 | plt.style.use('seaborn-v0_8-whitegrid') 53 | fig, ax = plt.subplots(figsize=(12, 10)) # Increased figure size 54 | 55 | # Create a teal color map similar to the example 56 | # cmap = plt.colormaps.get('GnBu') 57 | teal_colors = '#2E8B8B' 58 | 59 | # Create horizontal bars 60 | bars = ax.barh(labels, percentages, color=teal_colors, height=0.7, edgecolor='none') 61 | 62 | # Remove all spines 63 | for spine in ax.spines.values(): 64 | spine.set_visible(False) 65 | 66 | # Add percentage labels at the end of each bar 67 | for i, (bar, percentage) in enumerate(zip(bars, percentages)): 68 | ax.text( 69 | percentage + 0.5, # Slight offset from the end of the bar 70 | bar.get_y() + bar.get_height()/2, 71 | f"{percentage:.1f}%", 72 | va='center', 73 | ha='left', 74 | fontsize=28, # Increased font size further 75 | color='#444444', 76 | family='Times New Roman', 77 | fontweight='normal' 78 | ) 79 | 80 | # Set the title with the specified formatting 81 | ax.set_title(title, fontsize=26, color='#2a7f90', pad=20, loc='left', family='Times New Roman') 82 | 83 | # Set x-axis label 84 | ax.set_xlabel('Percentage of Types', fontsize=28, color='#444444', family='Times New Roman') 85 | 86 | # Set y-axis tick font size 87 | ax.tick_params(axis='y', which='both', left=False, labelsize=30) 88 | ax.tick_params(axis='x', labelsize=22) 89 | 90 | # Explicitly set font for y-axis tick labels to Times New Roman 91 | for tick in ax.get_yticklabels(): 92 | tick.set_fontname('Times New Roman') 93 | 94 | # Explicitly set font for x-axis tick labels to Times New Roman 95 | for tick in ax.get_xticklabels(): 96 | tick.set_fontname('Times New Roman') 97 | 98 | # Set x-axis grid to light gray and only on major ticks 99 | ax.grid(axis='x', color='#EEEEEE', linestyle='-', linewidth=0.7, alpha=0.7) 100 | ax.grid(axis='y', visible=False) 101 | 102 | # Set axis limits with a bit of padding 103 | ax.set_xlim(0, max(percentages) * 1.15) 104 | 105 | # Adjust layout 106 | plt.tight_layout() 107 | 108 | # Save the figure with a white background 109 | plt.savefig(filename, dpi=300, bbox_inches='tight', facecolor='white') 110 | print(f"Chart saved as '{filename}'") 111 | 112 | plt.close(fig) 113 | 114 | def plot_pie_chart(counter, title, filename): 115 | # Get the data sorted by count 116 | labels, values = zip(*counter.most_common()) 117 | 118 | # Calculate percentage for each item 119 | total = sum(values) 120 | percentages = [(v/total)*100 for v in values] 121 | 122 | # Set font to Times New Roman for the entire plot 123 | plt.rcParams['font.family'] = 'Times New Roman' 124 | 125 | # Set up the figure with a clean style 126 | plt.figure(figsize=(10, 10), facecolor='white') 127 | ax = plt.subplot(111) 128 | 129 | # Define specific colors for different problem types 130 | # Using teal/blue for the first two and deep red for mixed integer programming 131 | # Create a dictionary to map specific labels to specific colors 132 | color_mapping = { 133 | 'Linear programming': '#2E8B8B', # Teal 134 | 'Integer programming': '#2E318B', # Deep blue 135 | 'Mixed integer programming': '#8B1A1A' # Deep red 136 | } 137 | 138 | # Map the colors to the actual labels in the data 139 | colors = [color_mapping.get(label, '#999999') for label in labels] 140 | 141 | # Create the pie chart as a donut - capture only the wedges 142 | wedges = ax.pie( 143 | values, 144 | colors=colors, 145 | startangle=90, 146 | wedgeprops={'edgecolor': 'white', 'linewidth': 1.5, 'antialiased': True}, 147 | labels=None, 148 | autopct=None 149 | )[0] 150 | 151 | # Draw a white circle at the center to create a donut chart 152 | centre_circle = plt.Circle((0, 0), 0.5, fc='white', edgecolor='none') 153 | ax.add_patch(centre_circle) 154 | 155 | # Add the total count in the center 156 | ax.text(0, 0, f"n = {total}", ha='center', va='center', fontsize=20, family='Times New Roman') 157 | 158 | # Add labels and percentages 159 | for i, (wedge, label, pct) in enumerate(zip(wedges, labels, percentages)): 160 | # Get angle and radius 161 | ang = (wedge.theta2 - wedge.theta1)/2. + wedge.theta1 162 | x = np.cos(np.deg2rad(ang)) 163 | y = np.sin(np.deg2rad(ang)) 164 | 165 | # Determine horizontal alignment based on angle 166 | ha = 'left' if x >= 0 else 'right' 167 | 168 | # Get connection point on the wedge edge 169 | conn_x = 0.75 * x 170 | conn_y = 0.75 * y 171 | 172 | # Text position 173 | text_x = 1.2 * x 174 | text_y = 1.2 * y 175 | 176 | # Draw connecting line 177 | ax.plot([conn_x, text_x], [conn_y, text_y], color='gray', linewidth=0.8) 178 | 179 | # Add label with larger font size 180 | ax.text(text_x, text_y, label, ha=ha, va='center', fontsize=15, color='#444444', family='Times New Roman') 181 | 182 | # Add percentage below label with larger font size 183 | ax.text(text_x, text_y - 0.15, f"{pct:.1f}%", ha=ha, va='center', fontsize=18, color='#666666', family='Times New Roman') 184 | 185 | # Set title with minimal styling 186 | ax.set_title(title, fontsize=22, color='#444444', pad=20, loc='center', y=1.05, family='Times New Roman') 187 | 188 | # Equal aspect ratio ensures that pie is drawn as a circle 189 | ax.axis('equal') 190 | 191 | # Remove all spines and ticks 192 | ax.set_frame_on(False) 193 | ax.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False) 194 | 195 | # Save the figure 196 | plt.tight_layout() 197 | plt.savefig(filename, dpi=300, bbox_inches='tight') 198 | print(f"Chart saved as '{filename}'") 199 | 200 | plt.close() 201 | 202 | def plot_pie_chart_no_text(counter, filename): 203 | # Get the data sorted by count 204 | labels, values = zip(*counter.most_common()) 205 | 206 | # Set font to Times New Roman for the entire plot 207 | plt.rcParams['font.family'] = 'Times New Roman' 208 | 209 | # Set up the figure with a clean style 210 | plt.figure(figsize=(10, 10), facecolor='white') 211 | ax = plt.subplot(111) 212 | 213 | # Define specific colors for different problem types 214 | # Using teal/blue for the first two and deep red for mixed integer programming 215 | # Create a dictionary to map specific labels to specific colors 216 | color_mapping = { 217 | 'Linear programming': '#2E8B8B', # Teal 218 | 'Integer programming': '#2E318B', # Deep blue 219 | 'Mixed integer programming': '#8B1A1A' # Deep red 220 | } 221 | 222 | # Map the colors to the actual labels in the data 223 | colors = [color_mapping.get(label, '#999999') for label in labels] 224 | 225 | # Create the pie chart as a donut - capture only the wedges 226 | ax.pie( 227 | values, 228 | colors=colors, 229 | startangle=90, 230 | wedgeprops={'edgecolor': 'white', 'linewidth': 1.5, 'antialiased': True}, 231 | labels=None, 232 | autopct=None 233 | ) 234 | 235 | # Draw a white circle at the center to create a donut chart 236 | centre_circle = plt.Circle((0, 0), 0.5, fc='white', edgecolor='none') 237 | ax.add_patch(centre_circle) 238 | 239 | # Equal aspect ratio ensures that pie is drawn as a circle 240 | ax.axis('equal') 241 | 242 | # Remove all spines and ticks 243 | ax.set_frame_on(False) 244 | ax.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False) 245 | 246 | # Save the figure 247 | plt.tight_layout() 248 | plt.savefig(filename, dpi=300, bbox_inches='tight') 249 | print(f"Chart saved as '{filename}'") 250 | 251 | plt.close() 252 | 253 | def main(): 254 | file_path = 'data/datasets/dataset_combined_result_mark.json' 255 | types_counter, problems_counter = analyze_json_data(file_path) 256 | 257 | # Print counts 258 | print_counts(types_counter, "Type") 259 | print_counts(problems_counter, "Problem") 260 | 261 | # Create and save bar chart for Type Distribution 262 | plot_horizontal_bar(types_counter, 'Percentage of Cases by Problem Type', 'data/images/types_distribution.png') 263 | 264 | # Create and save pie chart for Problem Distribution 265 | plot_pie_chart(problems_counter, 'Problem Distribution', 'data/images/problems_distribution_pie.png') 266 | 267 | # Create and save pie chart without text for Problem Distribution 268 | plot_pie_chart_no_text(problems_counter, 'data/images/problems_distribution_pie_no_text.png') 269 | 270 | print("\nTo view the charts, open the PNG files in your file browser.") 271 | 272 | if __name__ == "__main__": 273 | main() 274 | -------------------------------------------------------------------------------- /data/datasets/complexor_combined_result.json: -------------------------------------------------------------------------------- 1 | { 2 | "0": { 3 | "index": 0, 4 | "question": "The Aircraft Assignment Problem aims to assign aircraft to routes in order to minimize the total cost while satisfying demand constraints with available aircraft. The problem involves a set of aircraft and a set of routes. Given the costs of assigning an aircraft to a route. The objective is to minimize the total cost of the assignment. There are limited available aircraft. It is constrained that the number of each aircraft allocated does not exceed its available number. Given the demand of each route and the capabilities (the largest number of people can be carried) of an aircraft for a route. The demand constraint ensures that the total allocation for each route satisfies the demand. The problem seeks to find the most cost-effective assignment of aircraft to routes.\n\nInput:\n{\n \"availability\": [\n 2,\n 3,\n 1\n ],\n \"demand\": [\n 100,\n 150\n ],\n \"capabilities\": [\n [\n 50,\n 70\n ],\n [\n 60,\n 80\n ],\n [\n 70,\n 90\n ]\n ],\n \"costs\": [\n [\n 100,\n 200\n ],\n [\n 150,\n 250\n ],\n [\n 200,\n 300\n ]\n ]\n}", 5 | "answer": 700 6 | }, 7 | "1": { 8 | "index": 1, 9 | "question": "The Aircraft Landing Problem (ALP) is the problem of deciding a landing time on an appropriate runway for each aircraft in a given set of aircraft such that each aircraft lands within a predetermined time window; and separation criteria between the landing of an aircraft, and the landing of all successive aircraft, are respected. We are given the earliest landing time, latest landing time, target landing time, and penalties for landing before or after the target landing time for each aircraft. There is also a separation time that represents the minimum time required between the landing of two aircraft. The objective of the problem is to minimize the total penalties of landing before or after the target time for each aircraft. The problem includes several constraints. The order constraint ensures that the aircrafts land in a specific order. The separation constraint ensures that there is enough separation time between the landing of aircraft. The lower and upper time window constraints ensure that each aircraft lands within its respective earliest and latest time windows.\n\nInput:\n{\n \"EarliestLanding\": [\n 1,\n 3,\n 5\n ],\n \"LatestLanding\": [\n 10,\n 12,\n 15\n ],\n \"TargetLanding\": [\n 4,\n 8,\n 14\n ],\n \"PenaltyAfterTarget\": [\n 10,\n 20,\n 30\n ],\n \"PenaltyBeforeTarget\": [\n 5,\n 10,\n 15\n ],\n \"SeparationTime\": [\n [\n 0,\n 2,\n 3\n ],\n [\n 2,\n 0,\n 4\n ],\n [\n 3,\n 4,\n 0\n ]\n ]\n}", 10 | "answer": 0 11 | }, 12 | "2": { 13 | "index": 2, 14 | "question": "The problem aims to determine the optimal amounts of alloys to purchase in order to achieve a desired blend of required elements at the minimum cost. We are given a set of alloys available on the market and a set of required elements for the blend, the percentage composition data of each required element in each alloy, the desired blend percentage of each required element, the price of each alloy. The decision is the amount of each alloy to be purchased, which is continuous. The objective is to minimize the total cost of the alloy purchased. There are two constraints. The first set of constraints ensures that the desired blend percentage of each required element is met. The second constraint ensures that the total amount of alloys purchased is equal to 1.\n\nInput:\n{\n \"alloys_on_market\": [\n 0,\n 1\n ],\n \"required_elements\": [\n \"A\",\n \"B\"\n ],\n \"composition_data\": [\n [\n 0.5,\n 0.1\n ],\n [\n 0.5,\n 0.9\n ]\n ],\n \"desired_blend_percentage\": [\n 0.5,\n 0.5\n ],\n \"alloy_price\": [\n 10.0,\n 20.0\n ]\n}", 15 | "answer": 10 16 | }, 17 | "3": { 18 | "index": 3, 19 | "question": "The Car Selection Problem is a mixed integer programming model that aims to assign participants to cars in a way that maximizes the total number of assignments. The problem involves a set of participants and a set of cars, where each participant is interested in a subset of cars. The objective is to find the optimal assignment of participants to cars that satisfies certain constraints.\n\nInput:\n{\n \"participants\": [\n \"P1\",\n \"P2\",\n \"P3\"\n ],\n \"cars\": [\n \"C1\",\n \"C2\",\n \"C3\"\n ],\n \"possible_assignments\": [\n [\n 1,\n 0,\n 1\n ],\n [\n 0,\n 1,\n 0\n ],\n [\n 1,\n 1,\n 1\n ]\n ]\n}", 20 | "answer": 3 21 | }, 22 | "4": { 23 | "index": 4, 24 | "question": "A telecom company needs to build a set of cell towers to provide signal coverage for the inhabitants of a given city. A number of potential locations where the towers could be built have been identified. The towers have a fixed range, and due to budget constraints only a limited number of them can be built. Given these restrictions, the company wishes to provide coverage to the largest percentage of the population possible. To simplify the problem, the company has split the area it wishes to cover into a set of regions, each of which has a known population. The goal is then to choose which of the potential locations the company should build cell towers on in order to provide coverage to as many people as possible.\n\nInput:\n{\n \"delta\": [\n [\n 1,\n 0,\n 1\n ],\n [\n 0,\n 1,\n 0\n ]\n ],\n \"cost\": [\n 3,\n 4\n ],\n \"population\": [\n 100,\n 200,\n 150\n ],\n \"budget\": 4\n}", 25 | "answer": 200 26 | }, 27 | "5": { 28 | "index": 5, 29 | "question": "This is a cutting stock problem. Given a roll of width `RollWidth` and a set of widths `Width` to be cut. Each width `i` has a certain number of Orders `Orders_{i}`. There are `NumPatterns` patterns and each pattern `j` has a certain number of rolls of each width `i` `NumRollsWidth_{i, j}`. The problem aims to minimize the total number of raw rolls cut. It is constrained that for each width `i`, the total number of rolls cut meets the total Orders. How to decide the number of rolls cut using each pattern `j`?\n\nInput:\n{\n \"roll_width\": 10,\n \"widths\": [\n 2,\n 3,\n 5\n ],\n \"orders\": [\n 4,\n 2,\n 2\n ],\n \"num_patterns\": 2,\n \"num_rolls_width\": [\n [\n 1,\n 2,\n 0\n ],\n [\n 0,\n 0,\n 1\n ]\n ]\n}", 30 | "answer": 6 31 | }, 32 | "6": { 33 | "index": 6, 34 | "question": "Consider a diet problem. Given a set of nutrients `Nutrients` and a set of foods `Foods`. Each food `j` has a cost `Cost_{j}` and a range of amount that can be bought `[MinAmount_{j}, MaxAmount_{j}]`. Each nutrient `i` has a range of amount that should be included in the diet `[MinNutrient_{i}, MaxNutrient_{i}]`. The amount of nutrient `i` in food `j` is `NutrientAmount_{i, j}`. The problem aims to minimize the total cost of buying foods. It is constrained that the total amount of each nutrient `i` in the bought foods should be within its range. How to decide the amount of each food `j` to buy?\n\nInput:\n{\n \"food_set\": [\n \"Apple\",\n \"Banana\"\n ],\n \"nutrient_set\": [\n \"VitaminC\",\n \"Fiber\"\n ],\n \"food_cost\": [\n 2.0,\n 1.5\n ],\n \"min_food_amount\": [\n 0,\n 0\n ],\n \"max_food_amount\": [\n 10,\n 10\n ],\n \"min_nutrient_amount\": [\n 50,\n 30\n ],\n \"max_nutrient_amount\": [\n 100,\n 60\n ],\n \"nutrient_amount\": [\n [\n 10,\n 5\n ],\n [\n 5,\n 10\n ]\n ]\n}", 35 | "answer": 10.333333333452588 36 | }, 37 | "7": { 38 | "index": 7, 39 | "question": "Consider a diet problem. Given a set of foods `Foods` and a set of nutrients `Nutrients` which is the union of nutrients with minimum requirements `MinRequirements` and nutrients with maximum requirements `MaxRequirements`. Each food `j` has a cost `Cost_{j}` and the amount of each nutrient `i` it contains is `NutrientAmount_{i, j}`. The problem aims to minimize the total cost of buying foods. It is constrained that the total amount of each nutrient `i` with minimum requirements in the foods bought is at least `MinRequirement_{i}` and the total amount of each nutrient `i` with maximum requirements in the foods bought is at most `MaxRequirement_{i}`. How to decide the amount of each food `j` to buy?\n\nInput:\n{\n \"cost\": [\n 2,\n 3,\n 1.5\n ],\n \"f_min\": [\n 0,\n 0,\n 0\n ],\n \"f_max\": [\n 100,\n 100,\n 100\n ],\n \"n_min\": [\n 50,\n 60\n ],\n \"n_max\": [\n 200,\n 250\n ],\n \"amt\": [\n [\n 2,\n 1,\n 3\n ],\n [\n 3,\n 4,\n 2\n ]\n ]\n}", 40 | "answer": 45.0 41 | }, 42 | "8": { 43 | "index": 8, 44 | "question": "A set of jobs `Jobs` need to be processed on a set of machines `Machines` in series. All jobs have the same processing order through all the machines from machine 1 to machine M. Each machine can work in parallel. The workflow is the following: the first job of the sequence goes to the first machine to be processed; meanwhile, other jobs wait; when the first machine has processed the first job, the first job goes to the second machine and the second job of the sequence starts to be processed by the first machine; and so on. The time required to process job `j` on machine `m` is `ProcesTime_{j, m}`. The problem aims to minimize the total makespan. The goal is to find a sequence of jobs that minimize the makespan: the time when all jobs have been processed.\n\nInput:\n{\n \"jobs\": [\n 1,\n 2,\n 3\n ],\n \"schedules\": [\n 1,\n 2,\n 3\n ],\n \"machines\": [\n 1,\n 2\n ],\n \"proces_time\": [\n [\n 1,\n 3\n ],\n [\n 2,\n 2\n ],\n [\n 3,\n 1\n ]\n ]\n}", 45 | "answer": 7 46 | }, 47 | "9": { 48 | "index": 9, 49 | "question": "The Knapsack Problem is a classic optimization problem in operations research and computer science. The problem is to determine the most valuable combination of items to include in a knapsack, given a set of items with different values and weights, and a maximum weight capacity of the knapsack. The goal is to maximize the total value of the items in the knapsack without exceeding its weight capacity.\n\nInput:\n{\n \"item_values\": [\n 60,\n 100,\n 120\n ],\n \"item_weights\": [\n 10,\n 20,\n 30\n ],\n \"max_weight_knapsack\": 50\n}", 50 | "answer": 220 51 | }, 52 | "10": { 53 | "index": 10, 54 | "question": "The main media selection problem is a problem of allocating advertising budgets between possible advertising outlets. Given a set of media options, it aims to determine which media should be selected so that all audiences are reached with minimum campaign cost. It does not matter if an audience is covered more than once, as long as it is covered at least once. Moreover, the company does not wish to spend more money on the campaign than necessary.\n\nInput:\n{\n \"target_audiences\": [\n 0,\n 1,\n 2\n ],\n \"advertising_media\": [\n 0,\n 1,\n 2\n ],\n \"incidence_matrix\": [\n [\n 1,\n 0,\n 1\n ],\n [\n 1,\n 1,\n 0\n ],\n [\n 0,\n 1,\n 1\n ]\n ],\n \"media_costs\": [\n 10,\n 15,\n 20\n ]\n}", 55 | "answer": 25.0 56 | }, 57 | "11": { 58 | "index": 11, 59 | "question": "This is a multi-commodity transportation problem. Given a set of origins `Origins`, a set of destinations `Destinations`, and a set of products `Products`. Each origin `i` has a certain supply of each product `p` `Supply_{i,p}` and each destination `j` has a certain demand for each product `p` `Demand_{j,p}`. The cost of shipping one unit of product `p` from origin `i` to destination `j` is `ShippingCost_{i, j, p}`. The problem aims to minimize the total cost of shipping all products from the origins to the destinations. It is constrained that the total amount of each product `p` shipped from each origin `i` equals its supply, the total amount of each product `p` shipped to each destination `j` equals its demand, and the total amount of all products shipped from each origin `i` to each destination `j` does not exceed a certain limit `Limit_{i,j}`. How to decide the number of units of each product `p` to be shipped from each origin `i` to each destination `j`?\n\nInput:\n{\n \"supply\": [\n [\n 20,\n 30\n ],\n [\n 40,\n 10\n ]\n ],\n \"demand\": [\n [\n 30,\n 30\n ],\n [\n 30,\n 10\n ]\n ],\n \"limit\": [\n [\n 35,\n 25\n ],\n [\n 20,\n 30\n ]\n ],\n \"cost\": [\n [\n [\n 2,\n 3\n ],\n [\n 4,\n 1\n ]\n ],\n [\n [\n 3,\n 2\n ],\n [\n 2,\n 4\n ]\n ]\n ]\n}", 60 | "answer": 235 61 | }, 62 | "12": { 63 | "index": 12, 64 | "question": "Consider a project assignment problem. Given a set of people `People` and a set of projects `Projects`. Each person `i` has a certain number of available hours `Supply_{i}` and each project `j` requires a certain number of hours `Demand_{j}`. The cost per hour of work for person `i` on project `j` is `Cost_{i, j}`. Each person `i` can contribute to project `j` up to a maximum limit `Limit_{i, j}`. The problem aims to minimize the total cost of assigning people to projects. It is constrained that the total number of hours assigned from each person `i` equals its supply and the total number of hours assigned to each project `j` equals its demand. How to decide the number of hours to be assigned from each person `i` to each project `j`?\n\nInput:\n{\n \"supply\": [\n 8,\n 7\n ],\n \"demand\": [\n 5,\n 10\n ],\n \"cost\": [\n [\n 10,\n 20\n ],\n [\n 15,\n 25\n ]\n ],\n \"limit\": [\n [\n 5,\n 6\n ],\n [\n 4,\n 7\n ]\n ]\n}", 65 | "answer": 285 66 | }, 67 | "13": { 68 | "index": 13, 69 | "question": "Consider a transportation problem with multiple products. Given a set of cities `Cities` and a set of links `Links` between the cities. Each city `i` has a certain supply of each product `p` `Supply_{i,p}` and a certain demand for each product `p` `Demand_{i,p}`. The cost of shipping one package of product `p` from city `i` to city `j` is `ShipmentCost_{i, j, p}`. Each link `(i, j)` has a certain capacity for each product `p` `Capacity_{i,j,p}` and a joint capacity `JointCapacity_{i, j}` for all products. The problem aims to minimize the total cost of shipping products from the cities to the cities. The total number of packages to be shipped on each link `(i, j)` should not exceed its joint capacity. How to decide the number of packages of each product `p` to be shipped from each city `i` to each city `j`?\n\nInput:\n{\n \"Cities\": [\n \"A\",\n \"B\"\n ],\n \"Links\": [\n [\n \"A\",\n \"B\"\n ]\n ],\n \"Products\": [\n \"Product1\"\n ],\n \"Supply\": [\n [\n 10\n ],\n [\n 0\n ]\n ],\n \"Demand\": [\n [\n 0\n ],\n [\n 10\n ]\n ],\n \"ShipmentCost\": [\n [\n [\n 1\n ]\n ]\n ],\n \"Capacity\": [\n [\n [\n 10\n ]\n ]\n ],\n \"JointCapacity\": [\n [\n 10\n ]\n ]\n}", 70 | "answer": 10 71 | }, 72 | "14": { 73 | "index": 14, 74 | "question": "Consider a transportation problem. Given a set of origins `Origins` and a set of destinations `Destinations`. Each origin `i` has a certain supply of goods `Supply_{i}` and each destination `j` has a certain demand for goods `Demand_{j}`. The cost of shipping one unit of goods from origin `i` to destination `j` is `Rate_{i, j}`. However, the number of units shipped can't exceed the limit `Limit_{i, j}`. The problem aims to minimize the total cost of shipping goods from the origins to the destinations. How to decide the number of units to be shipped from each origin `i` to each destination `j`?\n\nInput:\n{\n \"supply\": [\n 20,\n 30\n ],\n \"demand\": [\n 30,\n 20\n ],\n \"rate\": [\n [\n 8,\n 6\n ],\n [\n 5,\n 10\n ]\n ],\n \"limit\": [\n [\n 15,\n 25\n ],\n [\n 25,\n 20\n ]\n ]\n}", 75 | "answer": 305 76 | }, 77 | "15": { 78 | "index": 15, 79 | "question": "Consider a problem where we have a set `P`. For each element `j` in `P`, we have a parameter `a[j]`, a parameter `c[j]`, and a parameter `u[j]`. We also have a global parameter `b`. We have a variable `X[j]` for each `j` in `P`. The goal is to maximize the total profit, which is the sum of `c[j] * X[j]` for all `j` in `P`. The constraints are that the sum of `(1/a[j]) * X[j]` for all `j` in `P` should be less than or equal to `b`, and `X[j]` should be between 0 and `u[j]` for all `j` in `P`.\n\nInput:\n{\n \"a\": [\n 3,\n 1,\n 2\n ],\n \"c\": [\n 5,\n 10,\n 8\n ],\n \"u\": [\n 4,\n 6,\n 3\n ],\n \"b\": 4\n}", 80 | "answer": 66 81 | }, 82 | "16": { 83 | "index": 16, 84 | "question": "We have a set of flight legs (one-way non-stop flight) with a limited passenger capacity. According to market research, we defined a set of flight itineraries to sell as a package with a given price. For each package, we have an estimated demand. How many units of each package should we sell to maximize the revenue? We reserve the passenger seats according to the number of packages we want to sell.\n\nInput:\n{\n \"available_seats\": [\n 50,\n 60,\n 70\n ],\n \"demand\": [\n 30,\n 40\n ],\n \"revenue\": [\n 100,\n 150\n ],\n \"delta\": [\n [\n 1,\n 1,\n 0\n ],\n [\n 0,\n 1,\n 1\n ]\n ]\n}", 85 | "answer": 8000 86 | }, 87 | "17": { 88 | "index": 17, 89 | "question": "Consider a production problem. Given a set of products `Products` and a set of stages `Stages`. Each product `p` has a certain production rate `Rate_{p, s}` in each stage `s` and a certain profit `Profit_{p}` per ton. Each stage `s` has a certain number of hours `Available_{s}` available per week. There are also lower and upper limits on the tons of each product sold in a week, `Commit_{p}` and `Market_{p}` respectively. The problem aims to maximize the total profit from all products. It is constrained that the total number of hours used by all products in each stage `s` may not exceed the hours available. How to decide the number of tons to be produced for each product `p`?\n\nInput:\n{\n \"products\": [\n \"P1\",\n \"P2\"\n ],\n \"stages\": [\n \"S1\",\n \"S2\"\n ],\n \"rate\": [\n [\n 2,\n 3\n ],\n [\n 3,\n 2\n ]\n ],\n \"profit\": [\n 10,\n 20\n ],\n \"commit\": [\n 1,\n 2\n ],\n \"market\": [\n 5,\n 4\n ],\n \"avail\": [\n 10,\n 8\n ]\n}", 90 | "answer": 110 91 | } 92 | } -------------------------------------------------------------------------------- /data/datasets/dataset_combined_result.json: -------------------------------------------------------------------------------- 1 | { 2 | "0": { 3 | "index": 0, 4 | "question": "\n 某糖果厂用原料 A、B、C 加工成三种不同牌号的糖果甲、乙、丙。已知各种牌号糖果中 A、B、C 含量、原料成本、各种原料的每月限制用量、三种牌号糖果的单位加工费及售价,如表 1-17 所示。问该厂每月生产这三种牌号糖果各多少 kg,才能使其获利最大。试建立这个问题的线性规划的数学模型。\n\\begin{table}[h]\n \\centering\n \\caption{原料及糖果生产数据}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccc|c|c}\n \\toprule\n 原料 & 甲 & 乙 & 丙 & 原料成本(元/kg) & 每月限制用量(kg) \\\\\n \\midrule\n A & $\\geq 60\\%$ & $\\geq 30\\%$ & & 2.00 & 2000 \\\\\n B & & & & 1.50 & 2500 \\\\\n C & $\\leq 20\\%$ & $\\leq 50\\%$ & $\\leq 60\\%$ & 1.00 & 1200 \\\\\n \\midrule\n 加工费(元/kg) & 0.50 & 0.40 & 0.30 & & \\\\\n 售价(元/kg) & 3.40 & 2.85 & 2.25 & & \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 5 | "answer": 5450 6 | }, 7 | "1": { 8 | "index": 1, 9 | "question": "\n 某饲养场饲养动物出售,设每头动物每天至少需 700g 蛋白质、30g 矿物质、100mg 维生素。现有五种饲料可供选用,各种饲料每 kg 营养成分含量及单位价格如表 1-22 所示。\n\n\\begin{table}[h]\n \\centering\n \\caption{饲料营养成分及价格}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|c|c|c|c}\n \\toprule\n 饲料 & 蛋白质 (g) & 矿物质 (g) & 维生素 (mg) & 价格 (元/kg) \\\\\n \\midrule\n 1 & 3 & 1.0 & 0.5 & 0.2 \\\\\n 2 & 2 & 0.5 & 1.0 & 0.7 \\\\\n 3 & 1 & 0.2 & 0.2 & 0.4 \\\\\n 4 & 6 & 2.0 & 2.0 & 0.3 \\\\\n 5 & 18 & 0.5 & 0.8 & 0.8 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n\n要求确定既满足动物生长的营养需要,又使费用最省的选用饲料的方案。\n", 10 | "answer": 32.43 11 | }, 12 | "2": { 13 | "index": 2, 14 | "question": "\n 宏银公司承诺为某建设项目从 2003 年起的 4 年中每年年初分别提供以下数额贷款:\n\\begin{itemize}\n \\item 2003 年——100 万元\n \\item 2004 年——150 万元\n \\item 2005 年——120 万元\n \\item 2006 年——110 万元\n\\end{itemize}\n\n以上贷款资金均需于 2002 年底前筹集。但为了充分发挥这笔资金的作用,在满足每年贷款额情况下,可将多余资金分别用于下列投资项目:\n\n\\begin{enumerate}\n \\item 于 2003 年年初购买 A 种债券,期限 3 年,到期后本息合计为投资额的 140\\%,但限购 60 万元;\n \\item 于 2003 年年初购买 B 种债券,期限 2 年,到期后本息合计为投资额的 125\\%,但限购 90 万元;\n \\item 于 2004 年年初购买 C 种债券,期限 2 年,到期后本息合计为投资额的 130\\%,但限购 50 万元;\n \\item 于每年年初将任意数额的资金存放于银行,年息 4\\%,于每年年底取出。\n\\end{enumerate}\n\n求宏银公司应如何运用好这笔筹集到的资金,使 2002 年底需筹集的资金数额最少。\n", 15 | "answer": 420.3957101 16 | }, 17 | "3": { 18 | "index": 3, 19 | "question": "\n红豆服装厂新推出一款时装,根据经验和市场调查,预测今后6个月对该款时装的需求为:\n1 月——3 000 件,2 月——3 600 件,3 月——4 000 件,4 月——4 600 件,5 月——4 800 件,6 月——5 000 件。\n生产每件需熟练工人工作 4h,耗用原材料 150 元。售价为 240 元/件。该厂 1 月初有熟练工 80 人,每人每月工作 160h。为适应生产需要,该厂可招收新工人培训,\n但培训一名新工人需占用熟练工人 50h 用于指导操作,培训期为一个月,结束后即可上岗。\n熟练工人每月工资 2 000 元,新工人培训期给予生活补贴 800 元,转正后工资与生产效率同熟练工人。\n又熟练工人(含转正一个月后的新工人)每月有 2\\% 因各种原因离职。已知该厂年初加工出 400 件该款时装作为库存,\n要求 6 月末库存不超过 100 件。又每月生产出来的时装如不在当月交货,库存费用为每件每月 10 元。\n试为该厂设计一个满足月及 6 月末存货要求,又使 1—6 月总收入为最大的劳动与生产方案。\n", 20 | "answer": 1000613.89 21 | }, 22 | "4": { 23 | "index": 4, 24 | "question": "\n一艘货轮分前、中、后三个舱位,它们的容积与最大允许载重量如表 \\ref{table1-24} 所示。\n现有三种货物待运,已知有关数据列于表 \\ref{table1-25}。\n\n\\begin{table}[h]\n \\centering\n \\caption{最大允许载重量与容积}\n \\label{table1-24}\n \\begin{tabular}{|c|c|c|}\n \\hline\n \\textbf{项目} & \\textbf{前舱} & \\textbf{中舱} & \\textbf{后舱} \\\\\n \\hline\n 最大允许载重量 (t) & 2000 & 3000 & 1500 \\\\\n \\hline\n 容积 ($m^3$) & 4000 & 5000 & 1500 \\\\\n \\hline\n \\end{tabular}\n\\end{table}\n\n\\begin{table}[h]\n \\centering\n \\caption{货物数据}\n \\label{table1-25}\n \\begin{tabular}{|c|c|c|c|c|}\n \\hline\n \\textbf{商品} & \\textbf{数量 (件)} & \\textbf{每件体积 ($m^3$/件)} & \\textbf{每件重量 (t/件)} & \\textbf{运价 (元/件)} \\\\\n \\hline\n A & 600 & 10 & 8 & 1000 \\\\\n \\hline\n B & 1000 & 5 & 6 & 700 \\\\\n \\hline\n C & 800 & 7 & 4 & 600 \\\\\n \\hline\n \\end{tabular}\n\\end{table}\n\n又为了航运安全,前、中、后舱的实际载重量大体保持各舱最大允许载重量的比例关系。\n具体要求:前、后舱分别与中舱之间载重量比例的偏差不超过 15\\%,前、后舱之间不超过 10\\%。\n问该货轮应装载 A、B、C 各多少件货物以使收入为最大?试建立这个问题的线性规划模型。\n", 25 | "answer": 885000.0 26 | }, 27 | "5": { 28 | "index": 5, 29 | "question": "\n 某工厂生产 I、II、III 三种产品,都分别经 A、B 两道工序加工。设 A 工序可分别在设备 A\\textsubscript{1} 或 A\\textsubscript{2} 上完成,有 B\\textsubscript{1}、B\\textsubscript{2}、B\\textsubscript{3} 三种设备可用于完成 B 工序。已知产品 I 可在 A、B 任何一种设备上加工;产品 II 可在任何规格的 A 设备上加工,但完成 B 工序时,只能在 B\\textsubscript{1} 设备上加工;产品 III 只能在 A\\textsubscript{2} 与 B\\textsubscript{2} 设备上加工。加工单位产品所需工序时间及其他各项数据见表 1-18,试安排最优生产计划,使该厂获利最大。\n\n\\bigskip\n\n\\noindent \\textbf{表 1-18}\n\n\\bigskip\n\n\\begin{tabular}{|c|c|c|c|c|c|}\n\\hline\n\\multirow{2}{*}{\\textbf{设备}} & \\multicolumn{3}{c|}{\\textbf{产品}} & \\multirow{2}{*}{\\textbf{设备有效台时/h}} & \\multirow{2}{*}{\\textbf{设备加工费/(元/h)}} \\\\\n\\cline{2-4}\n& \\textbf{I} & \\textbf{II} & \\textbf{III} & & \\\\\n\\hline\nA\\textsubscript{1} & 5 & 10 & & 6 000 & 0.05 \\\\\n\\hline\nA\\textsubscript{2} & 7 & 9 & 12 & 10 000 & 0.03 \\\\\n\\hline\nB\\textsubscript{1} & 6 & 8 & & 4 000 & 0.06 \\\\\n\\hline\nB\\textsubscript{2} & 4 & & 11 & 7 000 & 0.11 \\\\\n\\hline\nB\\textsubscript{3} & 7 & & & 4 000 & 0.05 \\\\\n\\hline\n\\textbf{原料费/(元/件)} & 0.25 & 0.35 & 0.50 & & \\\\\n\\hline\n\\textbf{售价/(元/件)} & 1.25 & 2.00 & 2.80 & & \\\\\n\\hline\n\\end{tabular}\n", 30 | "answer": 1190.566502 31 | }, 32 | "6": { 33 | "index": 6, 34 | "question": "\n \\noindent\\textbf{例 11} 童心玩具厂下一年度的现金流c值如表1-19所示,表中负号表示该月现金流出大于流入,为此该厂需借款。借款有两种方式:一是于上一年年末借一年期贷款,一次获得全部贷款额,从2月底起每月还息1%,再于次年1月底归还本金和最后一次利息;二是得到短期贷款,每月初获得,于下月初归还本息,月息1.5%。当该厂有多余现金时,可短期存款,月初存人,月末取出,月息0.4%。问该厂应如何进行存贷款操作,既能弥补可能出现的负现金流,又可使下年初现金总量为最大。\n\n\\begin{table}[h]\n \\centering\n \\caption{现金流情况}\n \\label{tab:cashflow}\n \\begin{tabular}{ccccccccccccc}\n \\toprule\n 月份 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 \\\\\n \\midrule\n 现金流 (万元) & -12 & -10 & -8 & -10 & -4 & 5 & -7 & -2 & 15 & 12 & -7 & 45 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 35 | "answer": 12.256 36 | }, 37 | "7": { 38 | "index": 7, 39 | "question": "\n 某公司承担 4 条航线的运输任务,已知:\n\\begin{enumerate}\n \\item 各条航线的起点城市和终点城市及每天的航班数(见表 3-21)。\n \\item 各城市间的航行时间(见表 3-22)。\n \\item 所有航线都使用同一种船只,每次装船和卸船时间均为 1 天。\n\\end{enumerate}\n问该公司至少应配备多少条船才能满足所有航线运输的需要?\n\n\\begin{table}[h]\n \\centering\n \\caption{各航线信息(表 3-21)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|c|c|c}\n \\toprule\n 航线 & 起点城市 & 终点城市 & 每天航班数量 \\\\\n \\midrule\n 1 & E & D & 3 \\\\\n 2 & B & C & 2 \\\\\n 3 & A & F & 1 \\\\\n 4 & D & B & 1 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n\n\\begin{table}[h]\n \\centering\n \\caption{各城市间的航行时间(天)(表 3-22)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|cccccc}\n \\toprule\n 从$\\backslash$至 & A & B & C & D & E & F \\\\\n \\midrule\n A & 0 & 1 & 2 & 14 & 7 & 7 \\\\\n B & 1 & 0 & 3 & 13 & 8 & 8 \\\\\n C & 2 & 3 & 0 & 15 & 5 & 5 \\\\\n D & 14 & 13 & 15 & 0 & 17 & 20 \\\\\n E & 7 & 8 & 5 & 17 & 0 & 3 \\\\\n F & 7 & 8 & 5 & 20 & 3 & 0 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 40 | "answer": 7.0 41 | }, 42 | "8": { 43 | "index": 8, 44 | "question": "\n \\noindent\\textbf{3.8} 某企业和用户签订了设备交货合同,已知该企业各季度的生产能力、每台设备的生产成本和每季度末的交货量(见表 3-30)。\n若生产出的设备当季度不交货,每台设备每季度需支付保管维护费 0.1 万元,试问在遵守合同的条件下,企业应如何安排生产计划,才能使年消耗费用最低?\n\n\\begin{table}[h]\n \\centering\n \\caption{季度生产能力、交货量及生产成本}\n \\label{tab:production}\n \\begin{tabular}{cccc}\n \\toprule\n 季度 & 工厂生产能力/台 & 交货量/台 & 每台设备生产成本/万元 \\\\\n \\midrule\n 1 & 25 & 15 & 12.0 \\\\\n 2 & 35 & 20 & 11.0 \\\\\n 3 & 30 & 25 & 11.5 \\\\\n 4 & 20 & 20 & 12.5 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n ", 45 | "answer": 913.5 46 | }, 47 | "9": { 48 | "index": 9, 49 | "question": "\n 某市有三个面粉厂,它们供给三个面食加工厂所需的面粉。各面粉厂的产量、各面食加工厂加工面粉的能力、各面食加工厂和面粉厂之间的单位运价,均示于表 3-31 中。假定在第 1、2 和 3 面食加工厂制作单位面粉食品的利润分别为 12、16 和 11,试确定使总效益最大的面粉分配计划(假定面粉厂和面食加工厂都属于同一个主管单位)。\n\n\\begin{table}[h]\n \\centering\n \\caption{面粉厂与面食加工厂的运输成本(表 3-31)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccc|c}\n \\toprule\n 面粉厂 & 食品厂 1 & 食品厂 2 & 食品厂 3 & 面粉厂产量 \\\\\n \\midrule\n I & 3 & 10 & 2 & 20 \\\\\n II & 4 & 11 & 8 & 30 \\\\\n III & 8 & 11 & 4 & 20 \\\\\n \\midrule\n 食品厂需求量 & 15 & 25 & 20 & \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 50 | "answer": 425.0 51 | }, 52 | "10": { 53 | "index": 10, 54 | "question": "\n \\noindent\\textbf{3.11} 1, 2, 3 三个城市每年需分别供应电力 320 个单位、250 个单位和 350 个单位,\n由 I、II 两个电站提供,它们的最大可供电量分别为 400 个单位和 450 个单位,单位费用如表 3-33 所示。\n由于需要量大于可供量,决定城市 1 的供应量可减少 0~30 个单位,城市 2 的供应量不变,\n城市 3 的供应量不能少于 270 个单位。试求总费用最低的分配方案(将可供电量用完)。\n\n\\begin{table}[h]\n \\centering\n \\caption{电站对各城市供电费用表}\n \\label{tab:power_supply}\n \\begin{tabular}{cccc}\n \\toprule\n 电站 & 城市 1 & 城市 2 & 城市 3 \\\\\n \\midrule\n I & 15 & 18 & 22 \\\\\n II & 21 & 25 & 16 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 55 | "answer": 14650 56 | }, 57 | "11": { 58 | "index": 11, 59 | "question": "\n \\noindent\\textbf{4.4} 某成品酒有三种商标(红、黄、蓝),都是由三种原料酒(等级 I、II、III)兑制而成。\n三种等级的原料酒的日供应量和成本见表 4-13,三种商标的成品酒的兑制要求和销售价见表 4-14。\n决策者规定:首先是必须严格按比例兑制各商标的酒,其次是获利最大;最后是红商标的酒每天至少生产 $\\geq$ 2000kg。\n\n\\begin{table}[h]\n \\centering\n \\caption{原料酒日供应量和成本}\n \\label{tab:raw_material}\n \\begin{tabular}{ccc}\n \\toprule\n 等级 & 日供应量 (kg) & 成本 (元/kg) \\\\\n \\midrule\n I & 1500 & 6.0 \\\\\n II & 2000 & 4.5 \\\\\n III & 1000 & 3.0 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n\n\\begin{table}[h]\n \\centering\n \\caption{成品酒兑制要求和售价}\n \\label{tab:product_requirements}\n \\begin{tabular}{ccc}\n \\toprule\n 商标 & 兑制要求 (\\%) & 售价 (元/kg) \\\\\n \\midrule\n 红 & III 少于 10\\%,I 多于 50\\% & 5.5 \\\\\n 黄 & III 少于 70\\%,I 多于 20\\% & 5.0 \\\\\n 蓝 & III 少于 50\\%,I 多于 10\\% & 4.8 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 60 | "answer": 2500 61 | }, 62 | "12": { 63 | "index": 12, 64 | "question": "\n 公司决定使用1000万元新产品开发基金开发A、B、C三种新产品。经预测估计,开发A、B、C三种新产品的投资利润率分别为5%、7%、10%。由于新产品开发有一定风险,公司研究后确定了下列优先顺序目标:\n第一,A产品至少投资300万元; 第二,为分散投资风险,任何一种新产品的开发投资不超过开发基金总额的35%;第三,应至少留有10%的开发基金,以备急用;第四,使总的投资利润最大。\n请建立模型使总的投资利润最大\n", 65 | "answer": 67.5 66 | }, 67 | "13": { 68 | "index": 13, 69 | "question": "\n 已知单位牛奶、牛肉、鸡蛋中的维生素及胆固醇含量等有关数据见表 4-15。如果只考虑这三种食物,并且设立了下列三个目标:\n\n\\begin{enumerate}\n \\item 满足三种维生素的每日最小需要量;\n \\item 使每日摄入的胆固醇最少;\n \\item 使每日购买食品的费用最少。\n\\end{enumerate}\n\n要求建立该问题的目标规划模型。\n\n\\begin{table}[h]\n \\centering\n \\caption{食品营养含量(表 4-15)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccc|c}\n \\toprule\n 项目 & 牛奶(500g) & 牛肉(500g) & 鸡蛋(500g) & 每日最小需要量(mg) \\\\\n \\midrule\n 维生素 A/mg & 1 & 1 & 10 & 1 \\\\\n 维生素 C/mg & 100 & 10 & 10 & 30 \\\\\n 维生素 D/mg & 10 & 100 & 10 & 10 \\\\\n \\midrule\n 胆固醇/单位 & 70 & 50 & 120 & \\\\\n 费用/元 & 1.5 & 8 & 4 & \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 70 | "answer": 31.11111111 71 | }, 72 | "14": { 73 | "index": 14, 74 | "question": "\n 金源公司生产三种产品,整个计划期分为三个阶段。现需编制生产计划,确定各个阶段各种产品的生产数量。\n\n计划受市场需求、设备台时、财务资金等方面条件的约束,有关数据如表 4-16 和表 4-17 所示。假设计划期初及期末各种产品的库存量皆为零。\n\n\\begin{table}[h]\n \\centering\n \\caption{各阶段产品需求量(表 4-16)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccc}\n \\toprule\n 需求阶段 & 产品 1 & 产品 2 & 产品 3 \\\\\n \\midrule\n 1 & 500 & 750 & 900 \\\\\n 2 & 680 & 800 & 800 \\\\\n 3 & 800 & 950 & 1000 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n\n\\begin{table}[h]\n \\centering\n \\caption{每台产品资源消耗量及阶段资源限制(表 4-17)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccc|c}\n \\toprule\n 项目 & 产品 1 & 产品 2 & 产品 3 & 每阶段资源限制 \\\\\n \\midrule\n 设备工作台时/h & 2.0 & 1.0 & 3.1 & 5000 \\\\\n 流动资金占用量/元 & 40 & 20 & 55 & 93000 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n\n公司设定以下三个优先级的目标:\n\\begin{enumerate}\n \\item $P_1$:及时供货,保证需求,尽量减少缺货,并且第三种产品及时供货的重要性相当于第一种、第二种产品的 2 倍;\n \\item $P_2$:尽量使各阶段加工设备不超负荷;\n \\item $P_3$:流动资金占用量不超过限额;\n\\end{enumerate}\n请建立其数学模型并优化\n", 75 | "answer": 0 76 | }, 77 | "15": { 78 | "index": 15, 79 | "question": "\n 厂 $A_1$ 和 $A_2$ 生产某种物资。由于该种物资供不应求,故需要再建一家工厂。相应的建厂方案有 $A_3$ 和 $A_4$ 两个。这种物资的需求地有 $B_1, B_2, B_3, B_4$ 四个。各工厂年生产能力、各地年需求量、各厂至各需求地的单位物资运费 $c_{ij} (i,j=1,2,3,4)$ 见表 5-2。\n\n\\begin{table}[h]\n \\centering\n \\caption{工厂至需求地的单位物资运输费用(表 5-2)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|cccc|c}\n \\toprule\n $c_{ij}$ (万元/kt) & $B_1$ & $B_2$ & $B_3$ & $B_4$ & 生产能力 (kt/年) \\\\\n \\midrule\n $A_1$ & 2 & 9 & 3 & 4 & 400 \\\\\n $A_2$ & 8 & 3 & 5 & 7 & 600 \\\\\n $A_3$ & 7 & 6 & 1 & 2 & 200 \\\\\n $A_4$ & 4 & 5 & 2 & 5 & 200 \\\\\n \\midrule\n 需求量 (kt/年) & 350 & 400 & 300 & 150 & \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n\n工厂 $A_3$ 或 $A_4$ 开工后,每年的生产费用估计分别为 1200 万元或 1500 万元。现要决定应建设工厂 $A_3$ 还是 $A_4$,才能使每年的总费用(即全部物资运输费和新工厂生产费用之和)最少。\n", 80 | "answer": 4600 81 | }, 82 | "16": { 83 | "index": 16, 84 | "question": "\n 有三种资源被用于生产三种产品,资源量、产品单位可变费用及售价、资源单位耗量及组织三种产品生产的固定费用见表 5-6。要求制订一个生产计划,使总收益最大。\n\n\\begin{table}[h]\n \\centering\n \\caption{生产计划数据(表 5-6)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccc|c}\n \\toprule\n 单耗量 & \\multicolumn{3}{c|}{产品} & 资源量 \\\\\n \\cmidrule(lr){2-4}\n 资源 & I & II & III & \\\\\n \\midrule\n A & 2 & 4 & 8 & 500 \\\\\n B & 2 & 3 & 4 & 300 \\\\\n C & 1 & 2 & 3 & 100 \\\\\n \\midrule\n 单件可变费用 & 4 & 5 & 6 & \\\\\n 固定费用 & 100 & 150 & 200 & \\\\\n 单件售价 & 8 & 10 & 12 & \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 85 | "answer": 300 86 | }, 87 | "17": { 88 | "index": 17, 89 | "question": "\n 某商业公司计划开办 5 家新商店,决定由 5 家建筑公司分别承建。已知建筑公司 $A_i (i=1,2,\\cdots,5)$ 对新商店 $B_j (j=1,2,\\cdots,5)$ 的建造费用的报价(万元)为 $c_{ij}$,见表 5-10。为了节省费用,商业公司应当对 5 家建筑公司怎样分配建造任务,才能使总的建造费用最少?\n\n\\begin{table}[h]\n \\centering\n \\caption{建筑公司对新商店的建造费用报价(表 5-10)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccccc}\n \\toprule\n $c_{ij}$ & $B_1$ & $B_2$ & $B_3$ & $B_4$ & $B_5$ \\\\\n \\midrule\n $A_1$ & 4 & 8 & 7 & 15 & 12 \\\\\n $A_2$ & 7 & 9 & 17 & 14 & 10 \\\\\n $A_3$ & 6 & 9 & 12 & 8 & 7 \\\\\n $A_4$ & 6 & 7 & 14 & 6 & 10 \\\\\n $A_5$ & 6 & 9 & 12 & 10 & 6 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 90 | "answer": 34 91 | }, 92 | "18": { 93 | "index": 18, 94 | "question": "\n 篮球队需要选择 5 名队员组成出场阵容参加比赛。8 名队员的身高及擅长位置见表 5-11。\n\n\\begin{table}[h]\n \\centering\n \\caption{队员身高及擅长位置(表 5-11)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|cccccccc}\n \\toprule\n 队员 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\\\\n \\midrule\n 身高 (m) & 1.92 & 1.90 & 1.88 & 1.86 & 1.85 & 1.83 & 1.80 & 1.78 \\\\\n 擅长位置 & 中锋 & 中锋 & 前锋 & 前锋 & 前锋 & 后卫 & 后卫 & 后卫 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n\n出场阵容应满足以下条件:\n\\begin{enumerate}\n \\item 必须且只有一名中锋上场;\n \\item 至少有一名前锋上场;\n \\item 如 1 号或 4 号上场,则 6 号也上场,反之如 6 号上场,则 1 号和 4 号均不上场;\n \\item 2 号和 8 号至少有一个不出场。\n\\end{enumerate}\n\n问应当选择哪 5 名队员上场,才能使出场队员平均身高最高,试建立数学模型。\n", 95 | "answer": 9.26 96 | }, 97 | "19": { 98 | "index": 19, 99 | "question": "\n \\noindent\\textbf{5.12 卡车送货问题(覆盖问题)} 龙运公司目前必须向 5 家用户送货,\n需在用户 A 处卸下 1 个单位重量的货物,在用户 B 处卸下 2 个单位重量的货物,\n在用户 C 处卸下 3 个单位重量的货物,在用户 D 处卸下 4 个单位重量的货物,\n在用户 E 处卸下 8 个单位重量的货物。公司有各种卡车四辆:\n1 号车载重能力为 2 个单位,2 号车载重能力为 6 个单位,\n3 号车载重能力为 8 个单位,4 号车载重能力为 11 个单位。\n每辆车只运输一次,卡车 $j$ 的一次运费为 $c_j$。\n假定一辆卡车不能同时给用户 A 和 C 送货;同样,也不能同时给用户 B 和 D 送货。\n请列出一个整数规划模型表达式,以确定装送全部货物应如何配置卡车,使其运费最小。\n", 100 | "answer": 700 101 | }, 102 | "20": { 103 | "index": 20, 104 | "question": "\n 某公司有资金 4 万元,可向 A、B、C 三个项目投资,已知各项目不同投资额的相应效益值如表 7-18 所示,问如何分配资金可使总效益最大。列出数学模型求解。\n\n\\begin{table}[h]\n \\centering\n \\caption{不同投资额对应效益值(表 7-18)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccccc}\n \\toprule\n 项目 & \\multicolumn{5}{c}{投资额(万元)} \\\\\n \\cmidrule(lr){2-6}\n & 0 & 1 & 2 & 3 & 4 \\\\\n \\midrule\n A & 0 & 41 & 48 & 60 & 66 \\\\\n B & 0 & 42 & 50 & 60 & 66 \\\\\n C & 0 & 64 & 68 & 78 & 76 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 105 | "answer": 155 106 | }, 107 | "21": { 108 | "index": 21, 109 | "question": "\n 为保证某设备正常运转,需对串联工作的三种不同零件 $A_1, A_2, A_3$ 分别确定备件数量。若增加备用零件的数量,可提高设备正常运转的可靠性,但费用要增加,而总投资额为 8 千元。已知备用零件数量与它的可靠性和费用关系如表 7-19 所示,求 $A_1, A_2, A_3$ 的备用零件数量各为多少时,可使设备运转的可靠性最高。\n使用数学模型求解\n\\begin{table}[h]\n \\centering\n \\caption{备用零件数量与可靠性及费用关系(表 7-19)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|ccc|ccc}\n \\toprule\n 备件数 & \\multicolumn{3}{c|}{可靠性} & \\multicolumn{3}{c}{备用零件费用 / 千元} \\\\\n \\cmidrule(lr){2-4} \\cmidrule(lr){5-7}\n & $A_1$ & $A_2$ & $A_3$ & $A_1$ & $A_2$ & $A_3$ \\\\\n \\midrule\n 1 & 0.3 & 0.2 & 0.1 & 1 & 3 & 2 \\\\\n 2 & 0.4 & 0.5 & 0.2 & 2 & 5 & 3 \\\\\n 3 & 0.5 & 0.9 & 0.7 & 3 & 6 & 4 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 110 | "answer": 3.170085660699 111 | }, 112 | "22": { 113 | "index": 22, 114 | "question": "\n 已知 4 个城市间距离如表 7-24 所示,求从 $v_1$ 出发,经过其余城市一次且仅一次,最后返回 $v_1$ 的最短路径与距离。要求用动态规划求解。\n\n\\begin{table}[h]\n \\centering\n \\caption{城市间距离矩阵(表 7-24)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|cccc}\n \\toprule\n 距离 $d(v_i, v_j)$ & 1 & 2 & 3 & 4 \\\\\n \\midrule\n 1 & 0 & 6 & 7 & 9 \\\\\n 2 & 8 & 0 & 9 & 7 \\\\\n 3 & 5 & 8 & 0 & 8 \\\\\n 4 & 6 & 5 & 5 & 0 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 115 | "answer": 23.0 116 | }, 117 | "23": { 118 | "index": 23, 119 | "question": "\n 8.19 甲、乙、丙、丁、戊、已6人组成一个小组,检查5个单位的工作,若第1单位和乙、丙、丁三人有工作联系,则用{乙,丙,丁)表示,其余四个单位依次分别为(甲,戊,已),(甲,乙,戊,已〉,(甲,乙,丁,已},(甲,乙,丙}。若到一个单位去检查工作的人只需1人,但必须是和该单位没有联系的人,问应如何安排?", 120 | "answer": 0 121 | }, 122 | "24": { 123 | "index": 24, 124 | "question": "\n 表 \\ref{table14-1} 中列出了 6 个工作分别在设备 A 和 B 上的加工时间 $A_j$ (min) 和 $B_j$ (min),\n所有工作都先在 A 上加工,再在 B 上加工。要求确定使总加工时间最短的工作加工顺序。\n\n\\begin{table}[h]\n \\centering\n \\caption{设备 A 和 B 的加工时间}\n \\label{table14-1}\n \\begin{tabular}{|c|c|c|c|c|c|c|}\n \\hline\n \\textbf{加工时间} & \\textbf{工作 1} & \\textbf{工作 2} & \\textbf{工作 3} & \\textbf{工作 4} & \\textbf{工作 5} & \\textbf{工作 6} \\\\\n \\hline\n A & 30 & 60 & 60 & 20 & 80 & 90 \\\\\n \\hline\n B & 70 & 70 & 50 & 60 & 30 & 40 \\\\\n \\hline\n \\end{tabular}\n\\end{table}\n", 125 | "answer": 370 126 | }, 127 | "25": { 128 | "index": 25, 129 | "question": "\n 表 14-6 给出了 12 个工作在设备 A 和设备 B 上的加工时间,要求:\n\\begin{enumerate}\n \\item 若所有工作都先在 A 上加工,再在 B 上加工,试安排使总加工时间最短的工作加工顺序,并计算总加工时间。\n\\end{enumerate}\n\n\\begin{table}[h]\n \\centering\n \\caption{设备 A 和 B 的加工时间}\n \\label{tab:processing_times}\n \\begin{tabular}{ccccccccccccc}\n \\toprule\n 设备 & 工作 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 \\\\\n \\midrule\n A & 加工时间 & 5 & 8 & 11 & 2 & 7 & 6 & 3 & 9 & 8 & 3 & 6 & 10 \\\\\n B & 加工时间 & 5 & 9 & 4 & 3 & 7 & 9 & 5 & 4 & 9 & 5 & 3 & 4 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 130 | "answer": 81 131 | }, 132 | "26": { 133 | "index": 26, 134 | "question": "\n 表 14-6 给出了 12 个工作在设备 A 和设备 B 上的加工时间,要求:\n\\begin{enumerate}\n \\item 若工作 8$\\sim$12 先在 B 上加工,再在 A 上加工,其他条件同上,以确定尽可能小的总加工时间和安排相应的工作加工顺序。\n\\end{enumerate}\n\n\\begin{table}[h]\n \\centering\n \\caption{设备 A 和 B 的加工时间}\n \\label{tab:processing_times}\n \\begin{tabular}{ccccccccccccc}\n \\toprule\n 设备 & 工作 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 \\\\\n \\midrule\n A & 加工时间 & 5 & 8 & 11 & 2 & 7 & 6 & 3 & 9 & 8 & 3 & 6 & 10 \\\\\n B & 加工时间 & 5 & 9 & 4 & 3 & 7 & 9 & 5 & 4 & 9 & 5 & 3 & 4 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 135 | "answer": 78 136 | }, 137 | "27": { 138 | "index": 27, 139 | "question": "有 10 个城市,它们在坐标系中的位置如表 14-8 所示,试完成以下工作:\n\\begin{enumerate}\n \\item 用数学建模求出经过每个城市一次且仅一次的一条最短线路;\n\\end{enumerate}\n\n\\begin{table}[h]\n \\centering\n \\caption{城市坐标(表 14-8)}\n \\renewcommand{\\arraystretch}{1.2}\n \\begin{tabular}{c|cccccccccc}\n \\toprule\n 坐标 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 \\\\\n \\midrule\n $x$ & 0 & 5 & 8 & 7 & 10 & 12 & 18 & 18 & 18 & 20 \\\\\n $y$ & 0 & 20 & 12 & 4 & 15 & 18 & 18 & 15 & 18 & 17 \\\\\n \\bottomrule\n \\end{tabular}\n\\end{table}\n", 140 | "answer": 66.69019989168 141 | }, 142 | "28": { 143 | "index": 28, 144 | "question": "\n 1.29某医院昼夜 $24~\\mathrm{~h~}$ 各时段内需要的护士数量如下: $2\\!:\\!00\\!\\sim\\!6\\!:\\!00\\!\\longrightarrow\\!10$ 人, $6\\!:\\!00\\!\\sim$ 10:00——15人, $10:00\\!\\sim\\!14:00\\!\\longrightarrow\\!25$ 人, $14:00\\!\\sim\\!18\\!:\\!00\\!\\longrightarrow\\!20$ 人, $18\\,;00\\!\\sim\\!22\\!:\\!00\\!\\longrightarrow\\!18$ 人; $22\\!:\\!00\\!\\sim\\!2\\!:\\!00\\!-\\!\\!\\!-\\!12$ 人。护士分别于 $2:00\\,,6:00\\,,10:00\\,,14:00\\,,18:00\\,,22:00$ 分6批上班,并连续工作 $8\\,\\textrm{h}$ 。试确定: \n\n该医院至少应设多少名护士,才能满足值班需要; \n", 145 | "answer": 53.0 146 | }, 147 | "29": { 148 | "index": 29, 149 | "question": "\n1.29某医院昼夜 $24~\\mathrm{~h~}$ 各时段内需要的护士数量如下: $2\\!:\\!00\\!\\sim\\!6\\!:\\!00\\!\\longrightarrow\\!10$ 人, $6\\!:\\!00\\!\\sim$ 10:00——15人, $10:00\\!\\sim\\!14:00\\!\\longrightarrow\\!25$ 人, $14:00\\!\\sim\\!18\\!:\\!00\\!\\longrightarrow\\!20$ 人, $18\\,;00\\!\\sim\\!22\\!:\\!00\\!\\longrightarrow\\!18$ 人; $22\\!:\\!00\\!\\sim\\!2\\!:\\!00\\!-\\!\\!\\!-\\!12$ 人。护士分别于 $2:00\\,,6:00\\,,10:00\\,,14:00\\,,18:00\\,,22:00$ 分6批上班,并连续工作 $8\\,\\textrm{h}$ 。试确定: \n\n若医院可聘用合同工护士,上班时间同正式工护士。若正式工护士报酬为10 元/h,合同工护士为15元/h,问医院是否应聘合同工护士及聘多少名? \n", 150 | "answer": 4240.0 151 | }, 152 | "30": { 153 | "index": 30, 154 | "question": "\n\n1.32一贸易公司专门经营某种杂粮的批发业务。公司现有库容5000担的仓库。1月1日,公司拥有库存1000担杂粮,并有资金20000元。估计第一季度杂粮价格如表1 -8 所示。 \n\n表1-8 \n\n\n
月份进货价/(元/担)出货价/(元/担)
12.853.10
23.053.25
32.902.95
\n\n如买进的杂粮当月到货,但需到下月才能卖出,且规定“货到付款”。公司希望本季末库存为2000担。问:应采取什么样的买进与卖出的策略使3个月总的获利最大?\n", 155 | "answer": -700.0 156 | }, 157 | "31": { 158 | "index": 31, 159 | "question": "\n\n\n1.33某农场有100hm²(公顷)土地及15000元资金可用于发展生产。农场劳动力情况为秋冬季3500人日,春夏季 $4000$ 人日,如劳动力本身用不了时可外出干活,春夏季收人为2.1元/人日,秋冬季收人为1.8元/人日。该农场种植三种作物:大豆、玉米、小麦,并饲养奶牛和鸡。种作物时不需要专门投资,而饲养动物时每头奶牛投资 400 元,每只鸡投资3元。养奶牛时每头需拨出 $1.~5~\\mathrm{{hm^{2}}}$ 土地种饲草,并占用人工秋冬季为100人日,春夏季为50人日,年净收人400元/头奶牛。养鸡时不占土地,需人工为每只鸡秋冬季需0.6人日,春夏季为0.3人日,年净收人为2元/只鸡。农场现有鸡舍允许最多养3 000只鸡,牛栏允许最多养32头奶牛。三种作物每年需要的人工及收入情况如表1-9所示。 \n\n表1-9 \n\n\n
项目大豆玉米麦子
秋冬季需人日数203510
春夏季需人日数507540
年净收入/(元/hm²)175300120
\n\n试决定该农场的经营方案,使年净收人为最大。\n", 160 | "answer": 20242.0 161 | }, 162 | "32": { 163 | "index": 32, 164 | "question": "\n\n1.34市场对I、Ⅱ两种产品的需求量为:产品I在1~4月每月需10000件,5~9月每月30000件,10~12月每月100000件;产品Ⅱ在3~9月每月15000件,其他月每月50000件。某厂生产这两种产品成本为:产品I在1~5月内生产每件5元,6~12月内生产每件4.50元;产品Ⅱ在1~5月内生产每件8元,6~12月内生产每件7元。该厂每月生产两种产品能力总和应不超过120000件。产品I体积每件0.2 m”,产品Ⅱ每件0.4立方米,而该厂仓库容积为 $15000\\;\\mathrm{~m^{3}~}$ 。要求:(a)说明上述问题无可行解;(b)若该厂仓库不足时,可从外厂租借。若占用本厂每月每m²库容需1元,而租用外厂仓库时上述费用增加为1.5元,试问在满足市场需求情况下,该厂应如何安排生产,使总的生产成本加库存费用为最少。 \n", 165 | "answer": 4910500.0 166 | }, 167 | "33": { 168 | "index": 33, 169 | "question": "\n\n1.35对某厂I,Ⅱ,Ⅲ三种产品下一年各季度的合同预订数如表1-10所示。 \n\n表 1-10 \n\n\n
产品季 度
1234
I1 5001 00020001 200
1 5001 5001 2001 500
1 0002 00015002500
\n\n该三种产品1季度初无库存,要求在4 季度末各库存150 件。已知该厂每季度生产工时为 $15~000~\\mathrm{h}$ ,生产I、Ⅱ、Ⅲ产品每件分别需时 $2, 4, 3\\,\\mathrm{~h~}$ 。因更换工艺装备,产品I在2 季度无法生产。规定当产品不能按期交货时,产品I、Ⅱ每件每迟交一个季度赔偿 20元,产品Ⅲ赔偿10元;又生产出的产品不在本季度交货的,每件每季度的库存费用为5元。问该厂应如何安排生产,使总的赔偿加库存的费用为最小。 \n", 170 | "answer": 8505.0 171 | }, 172 | "34": { 173 | "index": 34, 174 | "question": "\n\n1.38·某厂在今后4个月内需租用仓库堆存物资。已知各个月所需的仓库面积列于表 1-14 。 \n\n表1-14 \n\n\n
月 份1234
所需仓库面积/m1 5001 0002 0001 200
\n\n当租借合同期限越长时,仓库租借费用享受的折扣优待越大,具体数据列于表1-15。 \n\n表 1-15 \n\n\n
合同租借期限/月1234
合同期内仓库面积的 租借费用/(元/m²)28456073
\n\n租借仓库的合同每月初都可办理,每份合同具体规定租用面积数和期限。因此该厂可根据需要在任何一个月初办理租借合同,且每次办理时,可签一份,也可同时签若干份租用面积和租借期限不同的合同·总的目标是使所付的租借费用最小。\n", 175 | "answer": 118400.0 176 | }, 177 | "35": { 178 | "index": 35, 179 | "question": "\n\n\n1.40某战略轰炸机群奉命摧毁敌人军事目标。已知该目标有四个要害部位,只要摧毁其中之一即可达到目的。为完成此项任务的汽油消耗量限制为 48 000 L、重型炸弹48枚、轻型炸弹 32枚。飞机携带重型炸弹时每升汽油可飞行2km,带轻型炸弹时每升汽油可飞行 $3\\ \\mathbf{km}$ 。又知每架飞机每次只能装载一枚炸弹,每出发轰炸一次除来回路程汽油消耗(空载时每升汽油可飞行 $4 km$ )外,起飞和降落每次各消耗 $100\\,\\mathrm{~L~}$ 。有关数据如表1-17 所示。 \n\n表1-17 \n\n\n
要害部位离机场距离/km摧毁可能性
每枚重型弹每枚轻型弹
14500.100.08
24800.200.16
35400.150.12
46000.250.20
\n\n为了使摧毁敌方军事目标的可能性最大,应如何确定飞机轰炸的方案。\n", 180 | "answer": 20.54832236198 181 | }, 182 | "36": { 183 | "index": 36, 184 | "question": "\n\n\n1.42一个木材储运公司有很大的仓库用以储运出售木材。由于木材季度价格的变化,该公司于每季度初购进木材,一部分于本季度内出售,一部分储存起来供以后出售。已知该公司仓库的最大木材储存量为20万 $\\mathbf{m^{3}}$ ,储存费用为 $(a+b\\,u\\,)$ 元/ $\\mathrm{m}^{3}$ ,式中 $a=70$ ,$b=100$ , $u$ 为储存时间(季度数)。已知每季度的买进卖出价及预计的最大销售量如表1-18所示。 \n\n表1-18 \n\n\n
季度买进价/(万元/万m²)卖出价/(万元/万m²)预计最大销售量/万m
410425100
430440140
460465200
450455160
\n\n由于木材不宜长期储存,所有库存木材应于每年秋末售完。试建立这个问题的线性规划模型,使该公司全年利润为最大。 \n", 185 | "answer": 4700.0 186 | }, 187 | "37": { 188 | "index": 37, 189 | "question": "\n1.45某公司有三项工作需分别招收技工和力工来完成。第一项工作可由一个技工单独完成,或由一个技工和两个力工组成的小组来完成。第二项工作可由一个技工或一个力工单独去完成。第三项工作可由五个力工组成的小组完成,或由一个技工领着三个力工来完成。已知技工和力工每周工资分别为100元和80元,他们每周都工作$48\\,\\mathrm{~h~}$ ,但他们每人实际的有效工作时间分别为 $4\\,2\\,\\mathrm{~h~}$ 和 $36\\,\\mathrm{~h~}$ 。为完成这三项工作任务,该公司需要每周总有效工作时间为:第一项工作 $10\\ 000\\ \\mathrm{h}$ 。第二项工作 $20~000~\\mathrm{h}$ ,第三项工作 $30~000~\\mathrm{~h~}$ 。能招收到的工人数为技工不超过400人,力工不超过800人。试建立数学模型,确定招收技工和力工各多少人。使总的工资支出为最少\n", 190 | "answer": null 191 | }, 192 | "38": { 193 | "index": 38, 194 | "question": "\n1.47红升厂生产I、Ⅱ、Ⅲ-种产品,都经过A、B两道工序加工。设A工序有 $\\mathbf{A}_{1}$ 、$\\mathbf{A}_{2}$ 两台设备,B工序有 $\\mathrm{B}_{1},\\mathrm{B}_{2},\\mathrm{B}_{3}$ 三台设备。已知产品I可在A、B任何一种设备上加T,产品 Ⅱ 可在任一规格A设备上加工,但B工序只能在 $\\mathrm{B}_{2}$ 设备上加工,产品Ⅲ两道工序只能在 $\\mathrm{A}_{2}\\,,\\mathrm{B}_{2}$ 设备上加工。加工单位产品所需工序时间及其他有关数据见表1-20。问应如何安排生产计划,使该厂获利最大? \n\n表1-20 \n\n\n
设 备产 品设备有效台时设备加工费 /(元/h)
I
A15106 0000.05
A2791210 0000.03
B1684.0000.06
B241170000.11
B374 0000.05
原料费/(元/件)0.250.350.50
售价/(元/件)1.252.002.80
\n\n", 195 | "answer": 2801.721675 196 | }, 197 | "39": { 198 | "index": 39, 199 | "question": "\n2.42某文教用品厂用原材料白坏纸生产原稿纸、日记本和练习本三种产品。该厂现有工人100人,每月白坯纸供应量为 $30000~kg$ 。已知工.人的劳动生产率为:每人每月可生产原稿纸30捆,或生产日记本30打·或练习本30箱。已知原材料消耗为:每捆原稿纸用白坯纸 $3~{\\frac{1}{3}}~\\mathrm{kg}$ ,每打日记本用白坯纸 $13~{\\frac{1}{3}}~\\mathbf{kg}$ ,每箱练习本用白坯纸 $26~{\\frac{2}{3}}~\\mathbf{kg}$ 。又知每生产一捆原稿纸可获利2元,生产一打日记本获利3元,生产一箱练习本获利1元。试确定: \n现有生产条件下获利最大的方案;\n", 200 | "answer": 8000.0 201 | }, 202 | "40": { 203 | "index": 40, 204 | "question": "\n2.42某文教用品厂用原材料白坏纸生产原稿纸、日记本和练习本三种产品。该厂现有工人100人,每月白坯纸供应量为 $30000~kg$ 。已知工.人的劳动生产率为:每人每月可生产原稿纸30捆,或生产日记本30打·或练习本30箱。已知原材料消耗为:每捆原稿纸用白坯纸 $3~{\\frac{1}{3}}~\\mathrm{kg}$ ,每打日记本用白坯纸 $13~{\\frac{1}{3}}~\\mathbf{kg}$ ,每箱练习本用白坯纸 $26~{\\frac{2}{3}}~\\mathbf{kg}$ 。又知每生产一捆原稿纸可获利2元,生产一打日记本获利3元,生产一箱练习本获利1元。试确定: \n如白坯纸的供应数量不变,当工人数量不足时可招收临时工,临时工工资支出为每人每月40元,则该厂要不要招收临时工,招多少临时工最合适? \n", 205 | "answer": 10000.0 206 | }, 207 | "41": { 208 | "index": 41, 209 | "question": "\n\n3.6某玩具公司分别生产三种新型玩具,每月可供量分别为1000件、2000件和2 000件,它们分别被送到甲、乙、丙三个百货商店销售。已知每月百货商店各类玩具预期销售量均为1500件,由于经营方面原因,各商店销售不同玩具的赢利额不同(见表3-6)。又知丙百货商店要求至少供应C玩具1000件,而拒绝进A种玩具。求满足上述条件下使总赢利额为最大的供销分配方案。 \n\n表3-6 \n\n\n
可供量
A541 000
B16862000
C1210112 000
\n\n", 210 | "answer": 51500.0 211 | }, 212 | "42": { 213 | "index": 42, 214 | "question": "\n3.7已知某运输问题的产销平衡表与单位运价表如表 3-7所示。 \n\n表3-7 \n\n\n
产地/销地 ABCDE产量
I101520204050
2010153030100
3035405525150
销量25115603070
\n\n求最优调拨方案; \n", 215 | "answer": 6625.0 216 | }, 217 | "43": { 218 | "index": 43, 219 | "question": "\n3.8已知某运输问题的产销平衡表和单位运价表如表3-8所示。 \n\n表3-8 \n\n\n
产地/销地 B1B2B3B4B5B6产量
A121333550
A242244440
A335424160
A442212231
销量305020403011
\n\n(a)求最优的运输调拨方案; \n", 220 | "answer": 330.0 221 | }, 222 | "44": { 223 | "index": 44, 224 | "question": "\n3.13如表3-17所示的运输问题中,若产地 $i$有一个单位物资未运出,则将发生储存费用。假定1,2,3产地单位物资储存费用分别为5,4 和 3。又假定产地 2 的物资至少运出 38个单位,产地3的物资至少运出 27个单位,试求解此运输问题的最优解。 \n\n表3-17 \n\n\n
产地/销地ABC产量
112220
214540
323330
销量302020
\n\n", 225 | "answer": 245.0 226 | }, 227 | "45": { 228 | "index": 45, 229 | "question": "\n\n3.14某化学公司有甲、乙、丙、丁四个化工厂生产某种产品,产量分别为200,300,400,100(t),供应I、Ⅱ、Ⅲ、IV、V、VI六个地区的需要,需要量分别为200,150,400,100,150,150(t)。由于工艺、技术等条件差别,各厂每 $\\mathbf{k}\\mathbf{g}$ 产品成本分别为1.2,1.4,1.1,1.5(元),又由于行情不同,各地区销售价分别为2.0,2.4,1.8,2.2,1.6,2.0(元/kg)。已知从各厂运往各销售地区每 $\\mathbf{k}\\mathbf{g}$ 产品运价如表3-18所示。 \n\n表3-18 \n\n\n
工厂\\地区IIIIIIIVVVI
0.50.40.30.40.30. 1
0.30.80.90.50.60.2
0.70.70.30.70.40.4
0.60.40.20.60.50.8
\n\n如第III个地区至少供应100t,第IV个地区的需要必须全部满足,试确定使该公司获利最大的产品调运方案。 \n\n", 230 | "answer": 445000.0 231 | }, 232 | "46": { 233 | "index": 46, 234 | "question": "\n3.15某糖厂每月最多生产糖 $270\\,\\mathfrak{t}$ ,先运至 $\\mathrm{A}_{1},\\mathrm{A}_{2},\\mathrm{A}_{3}$ 三个仓库,然后再分别供应$\\mathrm{B}_{1}\\ ,\\mathrm{B}_{2}\\ ,\\mathrm{B}_{3}\\ ,\\mathrm{B}_{4}\\ ,\\mathrm{B}_{5}$ 五个地区需要。已知各仓库容量分别为50,100,150(t),各地区的需要量分别为 $25\\,,105\\,,60\\,,30\\,,70\\,\\,(\\,\\mathfrak{t}\\,)$ 。已知从糖厂经由各仓库然后供应各地区的运费和储存费如表3-19所示。 \n\n表3-19 \n\n\n
B1B2B3B4B5
A11015202040
A22040153030
A33035405525
\n\n试确定一个使总费用最低的调运方案。 \n\n", 235 | "answer": 6100.0 236 | }, 237 | "47": { 238 | "index": 47, 239 | "question": "\n3.16某造船厂根据合同要在当年算起的连续三年年末各提供三条规格相同的大型货轮。已知该厂今后三年的生产能力及生产成本如表3-20所示。 \n\n表 3-20 \n\n\n
年度正常生产时可完成的货轮数加班生产时可完成的货轮数正常生产时每条货轮成本/万元
第一年23500
第二年42600
第三年13550
\n\n已知加班生产情况下每条货轮成本比正常生产时高出 70万元。又知造出的货轮如当年不交货,每条货轮每积压一年增加维护保养等损失为 40万元。在签订合同时该厂已有两条积压未交货的货轮,该厂希望在第三年年末在交完合同任务后能储存一条备用,问该厂应如何安排计划,使在满足上述要求的条件下,使总的费用支出为最少?\n\n", 240 | "answer": 4650.0 241 | }, 242 | "48": { 243 | "index": 48, 244 | "question": "\n3.18为确保飞行的安全,飞机上的发动机每半年必须强迫更换进行大修。某维修厂估计某种型号战斗机从下一-个半年算起的今后三年内每半年发动机的更换需要量分别为:100,70,80,120,150,140。更换发动机时可以换上新的,也可以用经过大修的旧的发动机。已知每台新发动机的购置费为10万元,而旧发动机的维修有两种方式:快修,每台2万元,半年交货(即本期拆下来送修的下批即可用上);慢修每台1万元,但需一年交货(即本期拆下来送修的需下下批才能用上)。设该厂新接受该项发动机更换维修任务,又知这种型号战斗机三年后将退役·退役后这种发动机将报废。问在今后三年的每半年内,该厂为满足维修需要各新购,送去快修和慢修的发动机数各多少,使总的维修费用为最省?\n\n", 245 | "answer": 2340.0 246 | }, 247 | "49": { 248 | "index": 49, 249 | "question": "\n3.19已知甲、乙两处分别有 70t和 55t物资外运,A、B、C三处各需要物资 $35\\,\\mathrm{t}$ $40\\mathfrak{t},50\\mathfrak{t}$ 。物资可以直接运达目的地,也可以经某些点转运,已知各处之间的距离 $\\left(\\mathtt{k m}\\right)$ 如表 3-23、表 3-24 和表 3-25 所示。试确定一个最优的调运方案。 \n\n表3-23 \n\n\n
从/到
012
100
\n\n表3-24 \n\n\n
从/到ABC
101412
151218
\n\n表3-25 \n\n\n
从/到ABC
A01411
B1004
C8120
\n\n\n", 250 | "answer": 1490.0 251 | }, 252 | "50": { 253 | "index": 50, 254 | "question": "\n5.11已知下列五名运动员各种姿势的游泳成绩(各为 $50\\,\\textrm{m})$ 如表5-2所示:试问:如何从中选拔一个参加 $200\\,\\mathrm{~m~}$ 混合泳的接力队,使预期比赛成绩为最好? \n\n表5-2 \n\n\n
游泳姿势
仰泳37.732.933.837.035.4
蛙泳43.433.142.234.741.8
蝶泳33.328.538.930.433.6
自由泳29.226.429.628.531.1
\n\n", 255 | "answer": 126.2 256 | }, 257 | "51": { 258 | "index": 51, 259 | "question": "\n5.12有甲、乙、丙、丁四人和A、B、C、D、E五项任务。每人完成各项任务时间如表5-3所示。由于任务数多于人数,故规定(a)其中有一人可兼完成两项任务,其余三人每人完成一项;(b)甲或丙之中有--完成两项任务,乙、丁各完成一项;(c)每人完成一项任务,其中A和B必须完成,C、D、E中可以有一项不完成。试分别确定总花费时间为最少的指派方案。 \n\n表5-3 \n\n\n
人/任务ABCDF
2529314237
3938262033
3427284032
2442362345
\n", 260 | "answer": 131.0 261 | }, 262 | "52": { 263 | "index": 52, 264 | "question": "\n\n5.19一种产品可分别在A,B,C,D四种设备的任一种上加工。已知每种设备启用时的准备结束费用,生产上述产品时的单件成本以及每种设备的最大加工能力如表5-7所示。如需生产该产品2000件,如何使总的费用最少?试建立数学模型。 \n\n表5-7 \n\n\n
设备准备结束费/元生产成本/(元/件)最大加工能力/件
A100020900
B920241 000
C800161 200
D700281 600
\n\n", 265 | "answer": 37000.0 266 | }, 267 | "53": { 268 | "index": 53, 269 | "question": "\n5.23某大学计算机实验室聘用4名大学生(代号1,2,3,4)和2名研究生(代号5,6)值班答疑。已知每人从周一至周互最多可安排的值班时间及每人每小时值班报酬如表 5-9 所示。 \n\n表 5-9 \n\n\n
学生代号报酬/(元/h)每天最多可安排的值班时间/h
周一周二周三周四周五
110.060907
210.009060
39.948305
49.855604
510.830480
611.309063
\n\n该实验室开放时间为上午8:00至晚上10:00,开放时间内必须有且仅需一名学生值班。又规定每名大学生每周值班不少于 $8h$ ,研究生每周不少于 $7h$ 。要求: \n建立使该实验室总支付报酬为最小的数学模型 \n\n", 270 | "answer": 708.8 271 | }, 272 | "54": { 273 | "index": 54, 274 | "question": "\n5.23某大学计算机实验室聘用4名大学生(代号1,2,3,4)和2名研究生(代号5,6)值班答疑。已知每人从周一至周互最多可安排的值班时间及每人每小时值班报酬如表 5-9 所示。 \n\n表 5-9 \n\n\n
学生代号报酬/(元/h)每天最多可安排的值班时间/h
周一周二周三周四周五
110.060907
210.009060
39.948305
49.855604
510.830480
611.309063
\n\n该实验室开放时间为上午8:00至晚上10:00,开放时间内必须有且仅需一名学生值班。又规定每名大学生每周值班不少于 $8h$ ,研究生每周不少于 $7h$ 。要求: \n在上述基础上补充下面要求:一是每名学生每周值班不超过2次,二是每天安排值班的学生不超过3人。\n\n建立使该实验室总支付报酬为最小的数学模型 \n\n", 275 | "answer": null 276 | }, 277 | "55": { 278 | "index": 55, 279 | "question": "\n5.24红豆服装厂利用三种专用设备分别生产衬衣、短袖衫和休闲服。已知上述三种产品的每件用工量、用料量、销售价及可变费用如表5-10所示。 \n\n表5-10 \n\n\n
产品名称单件用工单件用料销售价可变费用
衬衣3412060
短袖衫238040
休闲服6618080
\n\n已知该厂每周可用工量为150 单位,可用料量为160单位,生产衬衣、短袖衫和休闲服三种专用设备的每周固定费用分别为 2 000、1500和1000。要求为该厂设计一个周的生产计划,使其获利为最大。 \n", 280 | "answer": 1500.0 281 | }, 282 | "56": { 283 | "index": 56, 284 | "question": "\n\n5.25某大学运筹学专业硕士:生要求从微积分、运筹学、数据结构、管理统计、计算机模拟、计算机程序、预测共7门课程中必须选修两门数学类、两门运筹学类和两门计算机类课程,课程中有些只归属某一类:微积分归属数学类,计算机程序归属计算机类;但有些课程是跨类的:运筹学可归为运筹学类和数学类,数据结构归属计算机类和数学类,管理统计归属数学和运筹学类,计算机模拟归属计算机类和运筹学类,预测归属运筹学类和数学类,凡归属两类的课程选学后可认为两类中各学了一门课。此外有些课程要求先学习先修课:计算机模拟或数据结构必须先修计算机程序,学管理统计须先修微积分,学预测必须先修管理统计。问:一个硕士生最少应学几门及哪几门,才能满足上述要求?\n\n", 285 | "answer": 4.0 286 | }, 287 | "57": { 288 | "index": 57, 289 | "question": "\n5.26红星塑料厂生产6种规格的塑料容器,每种容器的容量、需求量及可变费用如表5-11所示。 \n\n表 5-11 \n\n\n
容器代号123456
容量/cm1500250040006000900012000
需求量/件500550700900400300
可变费用/(元/件)5810121618
\n\n每种容器分别用不同专用设备生产,其固定费用均为1200元。当某种容器数量上不能满足需要时,可用容量大的代替。问:在满足需求情况下,如何组织生产,使总的费用为最小? \n\n", 290 | "answer": 43200.0 291 | }, 292 | "58": { 293 | "index": 58, 294 | "question": "\n5.27长江综合商场有 $5~000~\\mathrm{{m}^{2}}$ 面积招租,拟吸收以下5类商店人租。已知各类商店开设一个店铺占用的面积,在该商场内最少与最多开设的个数,以及每类商店开设不同个数时每个商店的全年预期利润(万元)如表5-12所示。各商店以年赢利的$20\\,\\%$ 作为租金上交商场。问:该商场应招租上述各类商店各多少个,使总租金的收人为最大? \n\n表5-12 \n\n\n
代号商店类别一个店铺面积/m开 设数不同开设数时一个店铺利润/万元
最少最多123
1珠宝25013987
2鞋帽35012109\\
3百货80013272120
4书店400021610\\
5餐饮50013171512
\n\n", 295 | "answer": 28.0 296 | }, 297 | "59": { 298 | "index": 59, 299 | "question": "\n5.30汉光汽车制造厂生产珠汇、松花江、黄河三种品牌的汽车,已知各生产一台时的钢材、劳动力的消耗和利润值,每月可供使用的钢材及劳动力小时数如表5-13所示。 \n\n表5-13 \n\n\n| 项目 | 珠江 | 松花江 | 黄河 | 每月可供量 |\n| -------- | ----- | ----- | ----- | ------- |\n| 钢材 / t | 1.5 | 3.0 | 5.0 | 6 000 |\n| 劳动力 / h | 300 | 250 | 400 | 600 000 |\n| 预期利润 / 元 | 2 000 | 3 000 | 4 000 | |\n\n\n已知这三种汽车生产的经济批量为月产量1000台以上,即各牌号汽车月产量或大于1000台,或不生产。试为该厂找出一个使总利润为最大的生产计划安排。 \n\n", 300 | "answer": 6000000.0 301 | }, 302 | "60": { 303 | "index": 60, 304 | "question": "\n5.31团结乡有8个村镇,各村镇位置坐标及小学生人数如表5-14所示。 \n\n表5-14 \n\n\n
村镇代号坐标位置小学生人数
xy
10060
210380
31215100
41413120
516980
618660
781240
861080
\n\n考虑到学校的规模效益,拟选其中两个村镇各建一所小学。问两所小学各建于何处,使小学生上学所走路程为最短(小学生所走路程按两村镇之间的欧氏距离计算)。 \n\n", 305 | "answer": 2582 306 | }, 307 | "61": { 308 | "index": 61, 309 | "question": "\n 7.9某公司去一所大学招聘一名管理专业应届毕业生。从众多应聘学生中,初选3名决定依次单独面试。面试规则为:当对第1人或第2人面试时,如满意(记3分),并决定聘用,面试不再继续;如不满意(记1分),决定不聘用,找下一人继续面试;如较满意(记2分)时,有两种选择,或决定聘用·面试不再继续,或不聘用,面试继续。但对决定不聘用者,不能同在后面面试的人比较后再回过头来聘用。故在前两名面试者都决定不聘用时,第三名面试者不论属何种情况均需聘用。根据以往经验,面试中满意的占 $20\\,\\%$ ,较满意的占 $50\\,\\%$ ,不满意者占 $30\\,\\%$ 。要求使聘用到的毕业生期望的分值为最高。 \n", 310 | "answer": 2.336 311 | }, 312 | "62": { 313 | "index": 62, 314 | "question": "\n 7.10某公司打算在三个不同的地区设置4个销售点,根据市场预测部门估计,在不同的地区设置不同数量的销售店,每月可得到的利润如表7-2所示。试问在各个地区应如何设置销售点,才能使每月获得的总利润最大?其值是多少? \n\n 表7-2 \n\n\n
地区\\销售店01234
1016253032
2012172122
3010141617
\n", 315 | "answer": 47.0 316 | }, 317 | "63": { 318 | "index": 63, 319 | "question": "\n\n 7.12设有两种资源,第一种资源有 $\\mathcal{x}$ 单位,第二种资源有 $y$ 单位,计划分配给 $n$ 个部门。把第一种资源 $x_{i}$ 单位,第二种资源 $y,$ 单位分配给部门 $_i$ 所得的利润记为 $r_{i}\\,(\\,x,\\,$ $y)$ 。如设 ${x\\!=\\!3}\\,,y\\!=\\!3$ $n\\!=\\!3$ ,其利润 $r_{i}(\\,x\\,,\\,y)$ 列于表7-3中。试用计算如何分配这两种资源到 $i$ 个部门去,使总的利润最大? \n\n 表7-3 \n\n\n
x\\yr(x,y)r2(.x,y)r3(x,y)
012301230123
0013602460358
1456714672579
25678468947911
36789681011691113
\n", 320 | "answer": 16.0 321 | }, 322 | "64": { 323 | "index": 64, 324 | "question": "\n\n 7.13某公司有三个工厂,它们都可以考虑改造扩建。每个工厂都有若干种方案可供选择,各种方案的投资及所能取得的收益如表7-4所示。现公司有资金5000万元。问应如何分配投资使公司的总收益最大? \n\n 表 7-4 \n 千万元 \n\n\n
m_{ij} (方案)工厂i=1i=2工厂i=3
((投资)R(收益)C(投资)R(收益)C(投资)R(收益)
1000000
2152813
32639--
4--412--
\n\n (注:表中“-”表示无此方案) \n", 325 | "answer": 17.0 326 | }, 327 | "65": { 328 | "index": 65, 329 | "question": "\n\n 7.14某T厂的交货任务如表7-5所示。表中数字为月底的交货量。该厂的生产能力为每月400件,该厂仓库的存货能力为300件,已知每100件货物的生产费用为10000元,在进行生产的月份,T厂要支出经常费用4000元,仓库保管费用为每百件货物每月1000元。假定开始时及6月底交货后无存货。试问应在每个月各生产多少件物品,才能既满足交货任务又使总费用最小? \n\n 表7-5 \n\n\n
月 份123456
交货量/百件125321
\n", 330 | "answer": 161000.0 331 | }, 332 | "66": { 333 | "index": 66, 334 | "question": "\n\n 7.15某商店在未来的4个月里·准备利用商店里一个仓库来专门经销某种商品,该仓库最多能储存这种商品1000单位。假定商店每月只能卖出它仓库现有的货。当商店决定在某个月购货时,只有在该月的下个月开始才能得到该货。据估计未来4个月这种商品买卖价格如表7-6所示。假定商店在1月开始经销时,仓库已储存商品500单位。试问:如何制订这 4个月的订购与销售计划,使获得利润最大?(不考虑仓库的存储费用,商品为整数) \n\n 表 7-6 \n\n\n
月份(k)买价卖价
11012
299
31113
41517
\n", 335 | "answer": 6000.0 336 | }, 337 | "67": { 338 | "index": 67, 339 | "question": "\n\n 7.16某厂准备连续3个月生产A种产品,每月初开始生产。A的生产成本费为 $x^{2}$ 其中 $x$ 是A产品当月的生产数量。仓库存货成本费是每月每单位为1元。估计3个月的需求量分别为 $d_{\\mathrm{l}}=100$ , $d_{2}=110$ , $d_{\\mathrm{3}}=120$ 。现设开始时第一个月月初存货 $s_{0}\\!=\\!0$ ,第三个月的月末存货 $s_{3}\\!=\\!0$ 。试问:每月的生产数量应是多少,才使总的生产和存货费用为最小? \n\n", 340 | "answer": 36319.5 341 | }, 342 | "68": { 343 | "index": 68, 344 | "question": "\n\n 7.17某鞋店出售橡胶雪靴,热销季节是从10月1日至次年3月31日,销售部门对 \n\n 这段时间的需求量预测如表7-7所示。 \n\n 表7-7 \n\n\n
月份101112123
需求/双402030403020
\n\n 每月订货数目只有10,20,30,40,50几种可能性,所需费用相应地为48,86,118,138,160元。每月末的存货不应超过 40双,存储费用按月末存靴数计算,每月每双为0.2元。因为雪靴季节性强,且式样要变化,希望热销前后存货均为零。假定每月的需求率为常数,储存费用按月存货量计算,订购一次的费用为10元。求使热销季节的总费用为最小的订货方案。 \n\n", 345 | "answer": 646.0 346 | }, 347 | "69": { 348 | "index": 69, 349 | "question": "\n\n 7.19某工厂生产三种产品,各种产品重量与利润关系如表7-8所示。现将此三种产品运往市场出售,运输能力总重量不超过 $10\\,\\mathfrak{t}$ 。问如何安排运输使总利润最大? \n\n 表7-8 \n\n\n
种类重量/(t/件)利润 /(元/件)
12100
23140
34180
\n\n", 350 | "answer": 500.0 351 | }, 352 | "70": { 353 | "index": 70, 354 | "question": "\n\n 7.20设有一辆载重卡车,现有 4 种货物均可用此车运输。已知这 4 种货物的重量、容积及价值关系如表7-9所示。 \n\n 表7-9 \n\n\n
货物代号重量/t容积/m^3价值/千元
1223
2324
3425
4536
\n\n 若该卡车的最大载重为 $15\\,\\mathrm{~t~}$ ,最大允许装载容积为 $10\\,\\mathrm{\\,m^{3}}$ ,在许可的条件下,每车装载每一种货物的件数不限。问应如何搭配这四种货物.才能使每车装载货物的价值最大? \n\n", 355 | "answer": 20.0 356 | }, 357 | "71": { 358 | "index": 71, 359 | "question": "\n\n 7.21设某台机床每天可用工时为 $5\\,\\textrm{h}$ ,生产每单位产品A或B都需要 $1\\,\\mathrm{~h~}$ ,其成本分别为4元和3元。已知各种单位产品的售价与该产品的产量具有如下线性关系: \n\n $$\n \\begin{array}{l}{p_{1}\\,=\\,12-x_{1}}\\\\ {p_{2}\\,=\\,13-2x_{2}}\\end{array}\n $$ \n\n 其中 $x_{1},x_{2}$ 分别为产品 A,B的产量。问如果要求机床每天必须工作 $5\\,\\textrm{h}$ ,产品 $\\mathrm{A}$ 和B各应生产多少,才能使总的利润最大?\n\n", 360 | "answer": 27.0 361 | }, 362 | "72": { 363 | "index": 72, 364 | "question": "\n\n 7.23为保证某一设备的正常运转,需备有三种不同的零件 $\\mathbf{E}_{1}\\,,\\mathbf{E}_{2}\\,,\\mathbf{E}_{3}$ 。若增加备用零件的数量,可提高设备正常运转的可靠性,但增加了费用,而投资额仅为8000元。已知备用零件数与它的可靠性和费用的关系如表7-10所示。 \n\n 表7-10 \n\n\n
备件数增加的可靠性设备的费用/千元
E1E2E3E1E2E3
z=10.30.20.1132
z=20.40.50.2253
z=30.50.90.7364
\n\n 现要求在既不超出投资额的限制,又能尽量提高设备运转的可靠性的条件下,试问各种零件的备件数量应是多少为好? \n\n", 365 | "answer": 1.2 366 | }, 367 | "73": { 368 | "index": 73, 369 | "question": "\n\n 7.25某警卫部门有 12支巡逻队负责4个仓库的巡逻。按规定对每个仓库可分别派2~4支队伍巡逻。由于所派队伍数量上的差别·各仓库一年内预期发生事故的次数如表 7-11所示。试应用动态规划的方法确定派往各仓库的巡逻队数,使预期事故的总次数为最少。 \n\n 表 7-11 \n\n\n
巡逻队数\\仓库 1234
218381434
316361231
412301125
\n\n", 370 | "answer": 87.0 371 | }, 372 | "74": { 373 | "index": 74, 374 | "question": "\n\n 8.15某项大型考试有 50 000人参加,按得分高低在试卷上分别标记 A、B、C、D、E。按历年同类考试成绩,这5档成绩的得分比例为 $10\\,\\%\\,,25\\,\\%\\,,30\\,\\%\\,,20\\,\\%\\,,15\\,\\%$ 。若用计算机按得分标记将5档试卷分检(计算机每次只能识别一个标记)。问应按什么顺序,使分检的总工作量为最小? \n\n", 375 | "answer": 2.5 376 | }, 377 | "75": { 378 | "index": 75, 379 | "question": "\n\n 8.16已知8口海上油井,相互间距离如表8-4所示。已知1号井离海岸最近,为5mile(海里)。问从海岸经1号井铺设油管将各油井连接起来,应如何铺设使输油管长度为最短(为便于计量和检修,油管只准在各井位处分叉)? \n\n 表8-4各油井间距离 (mile) \n\n\n
从\\到2345678
11.32.10.90.71.82.01.5
20.91.81.22.62.31.1
32.61.72.51.91.0
40.71.61.50.9
50.91.10.8
60.61.0
70.5
\n\n", 380 | "answer": 10.2 381 | }, 382 | "76": { 383 | "index": 76, 384 | "question": "\n\n 8.23某台机器可连续工作4年,也可于每年末卖掉,换一台新的。已知于各年初购置一台新机器的价格及不同役龄机器年末的处理价如表8-7所示。又新机器第一年运行及维修费为0.3万元,使用 $1-3$ 年后机器每年的运行及维修费用分别为0.8万元、1.5万元和2.0万元。试确定该机器的最优更新策略,使4 年内用于更换、购买及运行维修的总费用为最省。 \n\n 表8-7 \n 万元 \n\n\n
j第一年第二年第三年第四年
年初购置价2.52.62.83.1
使用了j年的机器处理价2.01.61.31.1
\n\n", 385 | "answer": 4.0 386 | }, 387 | "77": { 388 | "index": 77, 389 | "question": "\n\n 8.37一条流水线有5个岗位,分别完成某产品装配的5道工序。现分配甲、乙、丙、丁、戊5个工人去操作。由于每人专长不同,各个工人在不同岗位上生产效率不一样,具体数字见表8-10(单位:件/min)。问到底怎样分配每个工人的操作岗位,使这条流水线的生产能力为最大? \n\n 表8-10 \n\n\n
工人\\工位IIIIVV
23417
34256
25341
52325
37624
\n\n", 390 | "answer": 5.0 391 | }, 392 | "78": { 393 | "index": 78, 394 | "question": "\n 9.5表9-3给出了-个汽车库及引道的施工计划。 \n\n 表9-3 \n\n\n
工序代号工序名称工序时间/d紧前工序
a清理场地,准备施工10--
b备料8--
c车库地面施工6a,b
d预制墙及房顶的桁架16b
e车库混凝土地面保养24c
f立墙架4d,e
g立房顶桁架4f
\n\n 续表 \n\n\n
工序代号工序名称工序时间/d紧前工序
h装窗及边墙10f
i装门4f
j装天花板12g
k油漆16h,i,j
L引道混凝土施厂8c
m引道混凝土保养24L
n清理场地,交T验收4k,m
\n\n 要求回答,该项工程从施工开始到全部结束的最短周期是多长? \n\n", 395 | "answer": 80.0 396 | }, 397 | "79": { 398 | "index": 79, 399 | "question": "\n 1 长征医院是长宁区的一所区级医院,该院每天各时间区段内需求的值班护士数如表C-2所示。 \n\n 表C-2 \n\n\n
时间区段6:00--10:0010:0--14:0014:00--18:0018:00--22:0022:00--6:00(次日)
需求数1820191712
\n\n 该医院护士上班分五个班次,每班 8h ,具体上班时间为第一班 $2:00-10:00$ ,第二班6:00—14:00,第三班10:00-18:00,第四班 $14:00-22:00$ ,第五班18:00-2:00(次日)。每名护士每周上5个班,并被安排在不同日子。有一名总护士长负责护士的值班安排。值班方案要做到在人员或经济上比较节省,又做到尽可能合情合理。下面是一些正在考虑中的值班方案: \n\n 方案1每名护士连续上班5天,休息2天,并从上班第一天起按从上第一班到第五班顺序安排。例如一名护士从周一开始上班,则她于周一上第一班,周二上第二班-···周五上第五班;另一名护士若从周三起上班,则她于周三上第一班,周四上第二班··-·周日上第五班,等等。 \n\n 如何使得方案1中值班护士最少\n\n", 400 | "answer": 70.0 401 | }, 402 | "80": { 403 | "index": 80, 404 | "question": "\n 某厂有 4 台磨床、2 台立钻、3 台水平钻、1台镗床和1 台刨床,用来生产 7 种产品。已知生产单位各种产品所需的有关设备台时以及它们的利润如表C-3所示。 \n\n 表C-3 \n \\begin{tabular}{@{}ccccccccc@{}}\n \\toprule\n \\multicolumn{2}{c}{\\multirow{2}{*}{\\begin{tabular}{c}单位所需台时\\\\ 设备\\end{tabular}}} & \\multicolumn{7}{c}{产品} \\\\\n \\cmidrule(lr){3-9}\n \\multicolumn{2}{c}{} & I & II & III & IV & V & VI & VII \\\\\n \\midrule\n \\multirow{5}{*}{\\RaggedRight 设备} & 磨床 & 0.5 & 0.7 & -- & -- & 0.3 & 0.2 & 0.5 \\\\\n & 立钻 & 0.1 & 0.2 & -- & 0.3 & -- & 0.6 & -- \\\\\n & 水平钻 & 0.2 & -- & 0.8 & -- & -- & -- & 0.6 \\\\\n & 镗床 & 0.05 & 0.03 & -- & 0.07 & 0.1 & -- & 0.08 \\\\\n & 刨床 & -- & -- & 0.01 & -- & 0.05 & -- & 0.05 \\\\\n \\midrule\n \\multicolumn{2}{c}{单件利润/元} & 100 & 60 & 80 & 40 & 110 & 90 & 30 \\\\\n \\bottomrule\n \\end{tabular}\n \\end{table}\n\n 从1月到6月份,下列设备需进行维修:1月一1台磨床,2月-2台水平钻,3月一1台镗床,4月—1台立钻,5月—1台磨床和1台立钻,6月一1台刨床和1台水平钻,被维修的设备在当月内不能安排生产。 \n\n 又知从 1-6 月份市场对上述7种产品最大需求量如表C-4所示。 \n\n 表C-4 \n\n \\begin{table}[h]\n \\centering\n \\caption{Combined Table}\n \\begin{tabular}{ccccccccc}\n \\toprule\n Month & I & II & III & IV & V & VI & VII \\\\\n \\midrule\n 1月 & 500 & 1000 & 300 & 300 & 800 & 200 & 100 \\\\\n 2月 & 600 & 500 & 200 & 0 & 400 & 300 & 150 \\\\\n 3月 & 300 & 600 & 0 & 0 & 500 & 400 & 100 \\\\\n 4月 & 200 & 300 & 400 & 500 & 200 & 0 & 100 \\\\\n 5月 & 0 & 100 & 500 & 100 & 1000 & 300 & 0 \\\\\n 6月 & 500 & 500 & 100 & 300 & 1100 & 500 & 60 \\\\\n \\bottomrule\n \\end{tabular}\n \\end{table}\n 每种产品当月销售不了的每件每月储存费为5元,但规定任何时候每种产品的储存量均不得超过100件。1月初无库存,要求6月末各种产品各储存50件。 \n\n 若该厂每月工作24天,每天两班,每班8个小时,假定不考虑产品在各种设备上的加工顺序,要求:(1)该厂如何安排计划·使总利润最大; \n\n", 405 | "answer": 937151.7857 406 | }, 407 | "81": { 408 | "index": 81, 409 | "question": "\n 甜甜食品公司下属的一个食品厂生产两种点心I和Ⅱ,采用原料A和B。已知生产每盒产品I和Ⅱ时消耗的原料 $\\mathbf{kg}$ 数,原料月供应量、原料单价及两种点心的批发价(千元/千盒)如表C-5所示。 \n\n 表C-5 \n\n \\begin{table}[h]\n \\centering\n \\caption{Table C-5}\n \\begin{tabular}{cccccc}\n \\toprule\n \\multicolumn{2}{c}{\\textbf{产品}} & \\multirow{2}{*}{\\textbf{I}} & \\multirow{2}{*}{\\textbf{II}} & \\textbf{月供应量/t} & \\textbf{单价(千元/t)} \\\\\n \\cmidrule(lr){1-2} \\cmidrule(lr){5-6}\n \\textbf{原料} & & & & & \\\\\n \\midrule\n A & & 1 & 2 & 6 & 9.9 \\\\\n B & & 2 & 1 & 8 & 6.6 \\\\\n \\midrule\n \\multicolumn{2}{c}{\\textbf{批发价}} & 30 & 20 & & \\\\\n \\bottomrule\n \\end{tabular}\n \\end{table}\n\n 据对市场估计,产品Ⅱ月销量不超过2千盒,产品Ⅱ销量不会超过产品11千盒以上。 要求计算最大批发收入 \n\n", 410 | "answer": 126.6666667 411 | }, 412 | "82": { 413 | "index": 82, 414 | "question": "\n 某厂计划将它的一部分在市区的生产车间搬迁至该市的卫星城镇,好处是土地、房租费及排污处理费用等都较便宜,但这样做会增加车间之间的交通运输费用。 \n\n 设该厂原在市区车间有 A、B、C、D、E五个,计划搬迁去的卫星城镇有甲、乙两处。规定无论留在市区或甲、乙两卫星城镇均不得多于3个车间。 \n\n 从市区搬至卫星城带来的年费用节约如表C-18所示。 \n\n 表C-18 万元/年 \n\n\n
车间ABCDE
搬至甲10015010020050
搬至乙100200150150150
\n\n 但搬迁后带来运输费用增加由 $C_{i k}$ 和 $D_{jl}$ 值决定, $\\boldsymbol{C}_{i k}$ 为 i和 $\\pmb{k}$ 车间之间的年运量, $D_{jl}$为市区同卫星城镇间单位运量的运费,具体数据分别见表C-19 和C-20。 \n\n \\begin{table}[h]\n \\centering\n \\caption{表 C-19 $C_{ik}$ 值 (Table C-19 $C_{ik}$ value) t/年 (t/year)}\n \\begin{tabular}{ccccc}\n \\toprule\n & B & C & D & E \\\\\n \\midrule\n A & 0 & 1000 & 1500 & 0 \\\\\n B & & 1400 & 1200 & 0 \\\\\n C & & & 0 & 2000 \\\\\n D & & & & 700 \\\\\n \\bottomrule\n \\end{tabular}\n \\end{table}\n\n \\begin{table}[h]\n \\centering\n \\caption{表 C-20 $D_{jl}$ 值 (Table C-20 $D_{jl}$ value) 元/t (Yuan/t)}\n \\begin{tabular}{cccc}\n \\toprule\n & 甲 & 乙 & 市区 \\\\\n \\midrule\n 甲 & 500 & 1400 & 1300 \\\\\n 乙 & & 500 & 900 \\\\\n 市区 & & & 1000 \\\\\n \\bottomrule\n \\end{tabular}\n \\end{table}\n\n 试为该厂计算最低的搬迁费用\n\n", 415 | "answer": -1990500.0 416 | } 417 | } -------------------------------------------------------------------------------- /data/datasets/dataset_md_result.json: -------------------------------------------------------------------------------- 1 | { 2 | "0": { 3 | "index": 0, 4 | "question": "\n\n\u8868 1 \u7ed9\u51fa\u4e86 12 \u4e2a\u5de5\u4ef6\u5728\u8bbe\u5907 \u8f66\u5e8a\u3001\u5228\u5e8a\u3001 \u94e3\u5e8a\u3001\u78e8\u5e8a \u4e0a\u7684\u52a0\u5de5\u65f6\u95f4\uff0c\u8981\u6c42\uff1a\n\n\u82e5\u6240\u6709\u5de5\u4ef6\u5747\u4f9d\u6b21\u5728\u8bbe\u5907 \u8f66\u5e8a\u3001\u5228\u5e8a\u3001 \u94e3\u5e8a\u3001\u78e8\u5e8a \u4e0a\u52a0\u5de5\uff08\u5373\u6bcf\u4e2a\u5de5\u4ef6\u5fc5\u987b\u5148\u5728 \u8f66\u5e8a \u4e0a\u52a0\u5de5\uff0c\u968f\u540e\u4f9d\u6b21\u5728\u5228\u5e8a\u3001 \u94e3\u5e8a\u3001\u78e8\u5e8a \u4e0a\u8fdb\u884c\u52a0\u5de5\uff09\uff0c\u8bd5\u5b89\u6392\u4f7f\u603b\u52a0\u5de5\u65f6\u95f4\u6700\u77ed\u7684\u5de5\u4ef6\u52a0\u5de5\u987a\u5e8f\uff0c\u5e76\u8ba1\u7b97\u603b\u52a0\u5de5\u65f6\u95f4\u3002\n\n## \u8868 1 \u8bbe\u5907 \u8f66\u5e8a\u3001\u5228\u5e8a\u3001 \u94e3\u5e8a\u3001\u78e8\u5e8a \u7684\u52a0\u5de5\u65f6\u95f4\n\n| \u8bbe\u5907 | \u5de5\u4ef6 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |\n|-----|----------|----|----|----|----|----|----|----|----|----|----|----|----|\n| \u8f66\u5e8a | \u52a0\u5de5\u65f6\u95f4 | 5 | 8 | 11 | 2 | 7 | 6 | 3 | 9 | 8 | 3 | 6 | 10 |\n| \u5228\u5e8a | \u52a0\u5de5\u65f6\u95f4 | 5 | 9 | 4 | 3 | 7 | 9 | 5 | 4 | 9 | 5 | 3 | 4 |\n| \u94e3\u5e8a | \u52a0\u5de5\u65f6\u95f4 | 4 | 7 | 8 | 3 | 6 | 5 | 4 | 8 | 7 | 4 | 5 | 9 |\n| \u78e8\u5e8a | \u52a0\u5de5\u65f6\u95f4 | 6 | 8 | 5 | 4 | 7 | 8 | 6 | 5 | 8 | 6 | 4 | 7 |\n", 5 | "answer": 50 6 | }, 7 | "1": { 8 | "index": 1, 9 | "question": "\n\n\n\u4e00\u8258\u8d27\u8f6e\u5206\u524d\u3001\u4e2d\u3001\u540e\u4e09\u4e2a\u8231\u4f4d\uff0c\u5b83\u4eec\u7684\u5bb9\u79ef\u4e0e\u6700\u5927\u5141\u8bb8\u8f7d\u91cd\u91cf\u5982 **\u8868 1** \u6240\u793a\u3002 \n\u73b0\u6709\u4e09\u79cd\u8d27\u7269\u5f85\u8fd0\uff0c\u5df2\u77e5\u6709\u5173\u6570\u636e\u5217\u4e8e **\u8868 2**\u3002\n\n## \u8868 1 \u6700\u5927\u5141\u8bb8\u8f7d\u91cd\u91cf\u4e0e\u5bb9\u79ef\n\n| \u9879\u76ee | \u524d\u8231 | \u4e2d\u8231 | \u540e\u8231 |\n|--------------------|------|------|------|\n| \u6700\u5927\u5141\u8bb8\u8f7d\u91cd\u91cf (t) | 2000 | 3000 | 1500 |\n| \u5bb9\u79ef (m^3) | 4000 | 5000 | 1500 |\n\n## \u8868 2 \u8d27\u7269\u6570\u636e\n\n| \u5546\u54c1 | \u6570\u91cf (\u4ef6) | \u6bcf\u4ef6\u4f53\u79ef (m^3/\u4ef6) | \u6bcf\u4ef6\u91cd\u91cf (t/\u4ef6) | \u8fd0\u4ef7 (\u5143/\u4ef6) |\n|------|-----------|---------------------|-----------------|--------------|\n| A | 600 | 10 | 8 | 1000 |\n| B | 1000 | 5 | 6 | 700 |\n| C | 800 | 7 | 4 | 600 |\n\n\u53c8\u4e3a\u4e86\u822a\u8fd0\u5b89\u5168\uff0c\u524d\u3001\u4e2d\u3001\u540e\u8231\u7684\u5b9e\u9645\u8f7d\u91cd\u91cf\u5927\u4f53\u4fdd\u6301\u5404\u8231\u6700\u5927\u5141\u8bb8\u8f7d\u91cd\u91cf\u7684\u6bd4\u4f8b\u5173\u7cfb\u3002 \n\u5177\u4f53\u8981\u6c42\uff1a\u524d\u3001\u540e\u8231\u5206\u522b\u4e0e\u4e2d\u8231\u4e4b\u95f4\u8f7d\u91cd\u91cf\u6bd4\u4f8b\u7684\u504f\u5dee\u4e0d\u8d85\u8fc7 15%\uff0c\u524d\u3001\u540e\u8231\u4e4b\u95f4\u4e0d\u8d85\u8fc7 10%\u3002\n\n**\u95ee\u9898\uff1a** \n\u8be5\u8d27\u8f6e\u5e94\u88c5\u8f7d A\u3001B\u3001C \u5404\u591a\u5c11\u4ef6\u8d27\u7269\u4ee5\u4f7f\u6536\u5165\u4e3a\u6700\u5927\uff1f\u8bd5\u5efa\u7acb\u8fd9\u4e2a\u95ee\u9898\u7684\u7ebf\u6027\u89c4\u5212\u6a21\u578b\u3002\n\n", 10 | "answer": 885000.0 11 | }, 12 | "2": { 13 | "index": 2, 14 | "question": "\n\n\n\u67d0\u5316\u5b66\u516c\u53f8\u6709\u7532\u3001\u4e59\u3001\u4e19\u3001\u4e01\u56db\u4e2a\u5316\u5de5\u5382\u751f\u4ea7\u67d0\u79cd\u4ea7\u54c1\uff0c\u4ea7\u91cf\u5206\u522b\u4e3a 200, 300, 400, 100\uff08t\uff09\uff0c\u4f9b\u5e94 I\u3001\u2161\u3001\u2162\u3001IV\u3001V\u3001VI \u516d\u4e2a\u5730\u533a\u7684\u9700\u8981\uff0c\u9700\u8981\u91cf\u5206\u522b\u4e3a 200, 150, 400, 100, 150, 150\uff08t\uff09\u3002\u7531\u4e8e\u5de5\u827a\u3001\u6280\u672f\u7b49\u6761\u4ef6\u5dee\u522b\uff0c\u5404\u5382\u6bcf kg \u4ea7\u54c1\u6210\u672c\u5206\u522b\u4e3a 1.2, 1.4, 1.1, 1.5\uff08\u5143\uff09\uff0c\u53c8\u7531\u4e8e\u884c\u60c5\u4e0d\u540c\uff0c\u5404\u5730\u533a\u9500\u552e\u4ef7\u5206\u522b\u4e3a 2.0, 2.4, 1.8, 2.2, 1.6, 2.0\uff08\u5143/kg\uff09\u3002\u5df2\u77e5\u4ece\u5404\u5382\u8fd0\u5f80\u5404\u9500\u552e\u5730\u533a\u6bcf kg \u4ea7\u54c1\u8fd0\u4ef7\u5982\u8868 1 \u6240\u793a\u3002\n\n## \u8868 1 \u6bcfkg\u4ea7\u54c1\u7684\u8fd0\u4ef7\n\n| \u5de5\u5382\\\u5730\u533a | I | II | III | IV | V | VI |\n|-----------|-----|-----|-----|-----|-----|-----|\n| \u7532 | 0.5 | 0.4 | 0.3 | 0.4 | 0.3 | 0.1 |\n| \u4e59 | 0.3 | 0.8 | 0.9 | 0.5 | 0.6 | 0.2 |\n| \u4e19 | 0.7 | 0.7 | 0.3 | 0.7 | 0.4 | 0.4 |\n| \u4e01 | 0.6 | 0.4 | 0.2 | 0.6 | 0.5 | 0.8 |\n\n\u5982\u7b2c III \u4e2a\u5730\u533a\u81f3\u5c11\u4f9b\u5e94 100 t\uff0c\u7b2c IV \u4e2a\u5730\u533a\u7684\u9700\u8981\u5fc5\u987b\u5168\u90e8\u6ee1\u8db3\uff0c\u8bd5\u786e\u5b9a\u4f7f\u8be5\u516c\u53f8\u83b7\u5229\u6700\u5927\u7684\u4ea7\u54c1\u8c03\u8fd0\u65b9\u6848\u3002\n\n", 15 | "answer": 445000.0 16 | }, 17 | "3": { 18 | "index": 3, 19 | "question": "\n\n8 \u6708\u521d\u7684\u4e00\u4e2a\u661f\u671f\u4e00\uff0c\u526f\u8463\u4e8b\u957f\u5b8b\u6301\u5e73\u8bf7\u8d22\u52a1\u3001\u9500\u552e\u548c\u751f\u4ea7\u7ecf\u7406\u5230\u4ed6\u7684\u529e\u516c\u5ba4\uff0c\u8ba8\u8bba\u672c\u751f\u4ea7\u5b63\u8282**\u805a\u4e19\u70ef\u7c89\u6599**\u7684\u751f\u4ea7\u6570\u91cf\u95ee\u9898\u3002\u4eca\u5e74\u6309\u7167\u91c7\u8d2d\u8ba1\u5212\u8d2d\u4e70\u7684 **300,000 kg** \u805a\u4e19\u70ef\u7c89\u6599\u5df2\u5168\u90e8\u8fd0\u62b5\u5de5\u5382\uff0c\u751f\u4ea7\u5c06\u4e8e\u4e0b\u5468\u4e00\u6b63\u5f0f\u5f00\u59cb\u3002\u7ea2\u7261\u4e39\u5316\u5de5\u516c\u53f8\u662f\u4e00\u5bb6\u4e2d\u578b\u5316\u5de5\u4f01\u4e1a\uff0c\u4e3b\u8981\u4ece\u4e8b\u9ad8\u5206\u5b50\u6539\u6027\u6750\u6599\u7684\u751f\u4ea7\u4e0e\u9500\u552e\uff0c\u5728\u4e1c\u5317\u5730\u533a\u62e5\u6709\u4e00\u5b9a\u7684\u5e02\u573a\u77e5\u540d\u5ea6\u3002\n\n\u8d22\u52a1\u7ecf\u7406\u94b1\u6e90\u548c\u9500\u552e\u7ecf\u7406\u8096\u901a\u5148\u884c\u5230\u8fbe\u3002\u751f\u4ea7\u7ecf\u7406\u5218\u534e\u968f\u540e\u8d76\u5230\uff0c\u5e76\u5e26\u6765\u4e86\u6700\u65b0\u7684\u539f\u6599\u68c0\u9a8c\u62a5\u544a\u3002\u62a5\u544a\u663e\u793a\uff1a\u5728 **300,000 kg** \u7684\u805a\u4e19\u70ef\u7c89\u6599\u4e2d\uff0c\u5927\u7ea6\u6709 **20%**\uff08\u5373 60,000 kg\uff09\u4e3a **\u9ad8\u7eaf\u5ea6\uff08A \u7ea7\uff09**\uff0c\u5176\u4f59\u7ea6 **80%**\uff08240,000 kg\uff09\u4e3a **\u666e\u901a\u7eaf\u5ea6\uff08B \u7ea7\uff09**\u3002\n\n---\n\n### \u4e0d\u540c\u805a\u4e19\u70ef\u6539\u6027\u4ea7\u54c1\u7684\u5e02\u573a\u9700\u6c42\n\n\u5b8b\u6301\u5e73\u5411\u8096\u901a\u8be2\u95ee\u4e0b\u4e00\u5e74\u6539\u6027\u805a\u4e19\u70ef\u4ea7\u54c1\u7684\u5e02\u573a\u9700\u6c42\u60c5\u51b5\u3002\u8096\u901a\u8868\u793a\uff0c\u6839\u636e\u5b9e\u9645\u9700\u8981\u91cf\u4f30\u8ba1\uff0c\u516c\u53f8\u751f\u4ea7\u7684 **\u6539\u6027\u805a\u4e19\u70ef A** \u80fd\u5168\u90e8\u552e\u51fa\uff0c\u4f46 **\u6539\u6027\u805a\u4e19\u70ef B** \u548c **\u6539\u6027\u805a\u4e19\u70ef C** \u7684\u9700\u6c42\u6709\u4e00\u5b9a\u4e0a\u9650\u3002\u5177\u4f53\u9884\u8ba1\u9700\u6c42\u548c\u57fa\u672c\u6570\u636e\u89c1\u8868 1\u3002\u9500\u552e\u4ef7\u683c\u662f\u6839\u636e\u516c\u53f8\u957f\u671f\u5e02\u573a\u89c4\u5212\u800c\u786e\u5b9a\uff0c\u9500\u552e\u9700\u6c42\u6765\u81ea\u5bf9\u8be5\u5b9a\u4ef7\u7b56\u7565\u7684\u5e02\u573a\u9884\u6d4b\u3002\n\n#### \u8868 1 \u9700\u6c42\u9884\u6d4b\u4e0e\u539f\u6599\u7528\u91cf\n\n| \u4ea7\u54c1 | \u9500\u552e\u4ef7\u683c\uff08\u5143/\u6876\uff09 | \u539f\u6599\u7528\u91cf\uff08kg/\u6876\uff09 | \u9700\u6c42\u9884\u6d4b\uff08\u6876\uff09 |\n|--------------------|-------------------|-------------------|----------------|\n| \u6539\u6027\u805a\u4e19\u70ef A\uff08A\uff09 | 4.00 | 1.8 | 800,000 |\n| \u6539\u6027\u805a\u4e19\u70ef B\uff08B\uff09 | 4.50 | 2.0 | 50,000 |\n| \u6539\u6027\u805a\u4e19\u70ef C\uff08C\uff09 | 3.80 | 2.5 | 80,000 |\n\n\n\u770b\u5b8c\u8096\u901a\u7684\u9700\u6c42\u9884\u6d4b\u540e\uff0c\u8d22\u52a1\u7ecf\u7406\u94b1\u6e90\u63d0\u51fa\uff1a\u201c\u5e94\u8be5\u5c3d\u53ef\u80fd\u628a\u6240\u6709\u805a\u4e19\u70ef\u7c89\u6599\u7528\u4e8e**\u6539\u6027\u805a\u4e19\u70ef A** \u7684\u751f\u4ea7\uff0c\u4eca\u5e74\u7684\u5f62\u52bf\u76f8\u5f53\u4e0d\u9519\u3002\u201d\u4ed6\u901a\u8fc7\u65b0\u5efa\u7acb\u7684\u4f1a\u8ba1\u7cfb\u7edf\u8ba1\u7b97\u4e86\u5404\u7c7b\u4ea7\u54c1\u7684\u5229\u6da6\u8d21\u732e\uff0c\u53d1\u73b0 **\u6539\u6027\u805a\u4e19\u70ef A** \u7684\u5229\u6da6\u660e\u663e\u9ad8\u4e8e\u5176\u4ed6\u4ea7\u54c1\u3002\u516c\u53f8\u5728\u4eca\u5e74 5 \u6708\u4e0e\u4f9b\u5e94\u5546\u7b7e\u8ba2\u7684\u5e73\u5747\u91c7\u8d2d\u4ef7\u683c\u4e3a **0.6 \u5143/kg**\uff0c\u94b1\u6e90\u8fd8\u7f16\u5236\u4e86\u5404\u4ea7\u54c1\u7684\u5229\u6da6\u8d21\u732e\u5206\u6790\u8868\uff08\u89c1\u8868 2\uff09\u3002\n\n---\n\n### A \u7ea7\u539f\u6599\u9650\u5236\u4e0e\u54c1\u8d28\u8bc4\u5206\n\n\u8fd9\u65f6\uff0c\u751f\u4ea7\u7ecf\u7406\u5218\u534e\u63d0\u9192\u5927\u5bb6\uff1a\u201c\u867d\u7136\u516c\u53f8\u4ea7\u80fd\u603b\u4f53\u4e0a\u8db3\u591f\uff0c\u4f46\u4e0d\u53ef\u80fd\u5c06\u6240\u6709\u539f\u6599\u90fd\u505a\u6210 **\u6539\u6027\u805a\u4e19\u70ef A**\uff0c\u56e0\u4e3a\u9ad8\u7eaf\u5ea6\uff08A \u7ea7\uff09\u539f\u6599\u7684\u6bd4\u4f8b\u6709\u9650\u3002\u201d\u7ea2\u7261\u4e39\u5316\u5de5\u516c\u53f8\u91c7\u7528\u6570\u5b57\u5316\u8bc4\u5206\u6765\u8bc4\u4f30\u805a\u4e19\u70ef\u7c89\u6599\u54c1\u8d28\uff1a**A \u7ea7\u539f\u6599**\u5e73\u5747\u8bc4\u5206 9 \u5206\uff0c**B \u7ea7\u539f\u6599**\u5e73\u5747\u8bc4\u5206 5 \u5206\u3002\u6839\u636e\u516c\u53f8\u7684\u5de5\u827a\u6807\u51c6\uff1a\n\n- **\u6539\u6027\u805a\u4e19\u70ef A** \u7684\u539f\u6599\u5e73\u5747\u5f97\u5206\u8981\u6c42 \u2265 8 \u5206\n- **\u6539\u6027\u805a\u4e19\u70ef B** \u7684\u539f\u6599\u5e73\u5747\u5f97\u5206\u8981\u6c42 \u2265 6 \u5206\n- **\u6539\u6027\u805a\u4e19\u70ef C** \u53ef\u4ee5\u5168\u90e8\u7528 B \u7ea7\u539f\u6599\u751f\u4ea7\n\n\u8fd9\u610f\u5473\u7740\uff0c\u5982\u679c\u53ea\u4f9d\u8d56\u73b0\u6709\u7684 60,000 kg A \u7ea7\u539f\u6599\uff0c\u5373\u4f7f\u5168\u90e8\u7528\u4e8e\u751f\u4ea7 A \u4ea7\u54c1\uff0c\u4e5f\u53ea\u80fd\u4fdd\u8bc1 **\u6539\u6027\u805a\u4e19\u70ef A** \u7684\u4ea7\u91cf\u4e0d\u8d85\u8fc7 44,500 \u6876\u5de6\u53f3\u3002\n\n\u4e0d\u8fc7\uff0c\u5b8b\u6301\u5e73\u8ba4\u4e3a\u8fd9\u5e76\u975e\u552f\u4e00\u9009\u62e9\u3002\u4ed6\u8bf4\uff0c\u66fe\u6709\u4eba\u63d0\u51fa\u4ee5 **0.85 \u5143/kg** \u7684\u4ef7\u683c\u63d0\u4f9b 80,000 kg \u989d\u5916\u7684 A \u7ea7\u539f\u6599\uff0c\u5f53\u65f6\u516c\u53f8\u6ca1\u6709\u91c7\u8d2d\uff0c\u4f46\u5982\u679c\u9700\u8981\uff0c\u4ecd\u53ef\u5c1d\u8bd5\u8054\u7cfb\u5bf9\u65b9\u518d\u6b21\u8d2d\u4e70\u3002\n\n---\n\n### \u8868 2 \u4ea7\u54c1\u83b7\u5229\u5206\u6790\u8868 (\u5355\u4f4d\uff1a\u5143/\u6876)\n\n| \u6210\u672c | \u6539\u6027\u805a\u4e19\u70ef A | \u6539\u6027\u805a\u4e19\u70ef B | \u6539\u6027\u805a\u4e19\u70ef C |\n|----------------------|-------------|-------------|-------------|\n| \u9500\u552e\u4ef7\u683c | 4.00 | 4.50 | 3.80 |\n| **\u53d8\u52a8\u6210\u672c** | | | |\n| \u76f4\u63a5\u4eba\u5de5 | 1.18 | 1.32 | 0.54 |\n| \u53ef\u53d8\u7ba1\u7406\u6210\u672c | 0.24 | 0.36 | 0.26 |\n| \u53ef\u53d8\u9500\u552e\u6210\u672c | 0.40 | 0.85 | 0.38 |\n| \u5305\u88c5\u6750\u6599 | 0.70 | 0.65 | 0.77 |\n| \u539f\u6750\u6599\uff08\u7edf\u4e00\u6309 0.6\uff09 | 1.08 | 1.20 | 1.50 |\n| \u53d8\u52a8\u6210\u672c\u5c0f\u8ba1 | 3.60 | 4.38 | 3.45 |\n| **\u51c0\u5229\u6da6\u6bcf\u6876** | 0.40 | 0.12 | 0.35 |\n\n\u5728\u6b64\u57fa\u7840\u4e0a\uff0c\u9500\u552e\u7ecf\u7406\u8096\u901a\u63d0\u51fa\u4e86\u4e0d\u540c\u89c2\u70b9\u3002\u4ed6\u8ba4\u4e3a\u4e0d\u8be5\u53ea\u6309\u91cd\u91cf\u7b80\u5355\u5206\u644a\u539f\u6599\u6210\u672c\uff0c\u800c\u5e94\u8003\u8651 A \u7ea7\u548c B \u7ea7\u539f\u6599\u7684\u771f\u5b9e\u4ef7\u503c\u5dee\u5f02\uff0c\u5e76\u636e\u6b64\u91cd\u65b0\u6838\u7b97\u8fb9\u9645\u5229\u6da6\uff08\u8868 3\uff09\u3002\u4ed6\u63d0\u51fa\uff0c\u5982\u679c\u53ea\u7528 200,000 kg \u7684 B \u7ea7\u539f\u6599\u751f\u4ea7 **\u6539\u6027\u805a\u4e19\u70ef C**\uff0c\u7136\u540e\u7528\u5269\u4f59 40,000 kg \u7684 B \u7ea7\u4e0e\u5168\u90e8 A \u7ea7\u539f\u6599\u53bb\u751f\u4ea7 **\u6539\u6027\u805a\u4e19\u70ef B**\uff0c\u5219\u53ef\u5728\u9700\u6c42\u5168\u90e8\u6ee1\u8db3\u7684\u524d\u63d0\u4e0b\u8fbe\u5230\u6700\u9ad8\u5229\u6da6 \u2014\u2014 \u7ea6 **4.8 \u4e07\u5143**\u3002\n\n---\n\n### \u8868 3 \u6539\u6027\u805a\u4e19\u70ef\u4ea7\u54c1\u7684\u8fb9\u9645\u5229\u6da6\u5206\u6790 (\u5355\u4f4d\uff1a\u5143/\u6876)\n\n| \u4ea7\u54c1 | \u6539\u6027\u805a\u4e19\u70ef A | \u6539\u6027\u805a\u4e19\u70ef B | \u6539\u6027\u805a\u4e19\u70ef C |\n|----------------------------|-------------|-------------|-------------|\n| \u9500\u552e\u4ef7\u683c | 4.00 | 4.50 | 3.80 |\n| \u53d8\u52a8\u6210\u672c (\u4e0d\u542b\u539f\u6599\u6210\u672c) | 2.52 | 3.18 | 1.95 |\n| \u539f\u6599\u6210\u672c (\u533a\u5206 A/B \u7ea7) | 1.48 | 1.32 | 1.85 |\n| \u539f\u6599\u6210\u672c\u5c0f\u8ba1 | 1.49 | 1.24 | 1.30 |\n| **\u8fb9\u9645\u5229\u6da6** | -0.01 | 0.08 | 0.55 |\n\n---\n\n#### \u8096\u901a\u7684\u8ba1\u7b97\u4f9d\u636e\n\n- \\( Z = \\) \u6bcf kg A \u7ea7\u805a\u4e19\u70ef\u7c89\u6599\u7684\u6298\u7b97\u6210\u672c\uff08\u5143/kg\uff09\n- \\( Y = \\) \u6bcf kg B \u7ea7\u805a\u4e19\u70ef\u7c89\u6599\u7684\u6298\u7b97\u6210\u672c\uff08\u5143/kg\uff09\n\n\u6839\u636e\u516c\u53f8\u603b\u6210\u672c\u548c\u8bc4\u5206\u7ea6\u675f\uff0c\u5217\u51fa\u65b9\u7a0b\uff1a\n\n\\[\n60000Z + 240000Y = 300000 * 0.6\n\\]\n\n\\[\n9Y = 5Z\n\\]\n\n\u8054\u7acb\u6c42\u89e3\uff0c\u5f97\u5230\uff1a\n\n\\[\nZ = 0.931 (\u5143/kg), Y = 0.517 (\u5143/kg)\n\\]\n\n---\n\n### \u95ee\u9898\uff1a\u6784\u5efa\u7ebf\u6027\u89c4\u5212\u6a21\u578b\n\n\u6839\u636e\u4e0a\u8ff0\u80cc\u666f\uff0c\u7ea2\u7261\u4e39\u5316\u5de5\u516c\u53f8\u60f3\u8981\u786e\u5b9a\u6700\u4f18\u7684\u751f\u4ea7\u65b9\u6848\uff0c\u4ee5\u6700\u5927\u5316\u5229\u6da6\u3002\u5047\u8bbe\u4f60\u662f\u8be5\u516c\u53f8\u7684\u8fd0\u8425\u7ba1\u7406\u987e\u95ee\uff0c\u8bf7\uff1a\n\n1. **\u5efa\u7acb\u51b3\u7b56\u53d8\u91cf**\uff1a\u5206\u522b\u7528\u6765\u8868\u793a\u751f\u4ea7\u4e09\u79cd\u4ea7\u54c1\uff08\u6539\u6027\u805a\u4e19\u70ef A\u3001B\u3001C\uff09\u7684\u6570\u91cf\uff1b\n2. **\u5217\u51fa\u76ee\u6807\u51fd\u6570**\uff1a\u5728\u6ee1\u8db3\u9700\u6c42\u9884\u6d4b\u3001\u539f\u6599\u4f9b\u5e94\u4ee5\u53ca\u54c1\u8d28\u9650\u5236\u7684\u524d\u63d0\u4e0b\uff0c\u4f7f\u5f97\u516c\u53f8\u5229\u6da6\u6700\u5927\u5316\uff1b\n3. **\u8bbe\u7f6e\u7ea6\u675f\u6761\u4ef6**\uff1a\n - \u539f\u6599\u603b\u91cf\u7ea6\u675f\uff08A \u7ea7\u3001B \u7ea7\u4ee5\u53ca\u53ef\u80fd\u5916\u8d2d\u7684 A \u7ea7\u539f\u6599\uff09\uff1b\n - \u4e0d\u540c\u4ea7\u54c1\u5bf9\u539f\u6599\u54c1\u8d28\uff08\u8bc4\u5206\uff09\u7684\u7ea6\u675f\uff1b\n - \u5404\u4ea7\u54c1\u7684\u6700\u5927\u9700\u6c42\u91cf\u7ea6\u675f\uff1b\n - \u975e\u8d1f\u6027\u7ea6\u675f\u7b49\u3002\n\n\u8bf7\u5199\u51fa\u5b8c\u6574\u7684\u7ebf\u6027\u89c4\u5212\u6a21\u578b\uff0c\u5e76\u7ed9\u51fa\u516c\u53f8\u5728\u4f55\u79cd\u6761\u4ef6\u4e0b\u5e94\u8003\u8651\u5916\u8d2d\u66f4\u591a A \u7ea7\u539f\u6599\uff08\u4ee5\u53ca\u6700\u4f73\u91c7\u8d2d\u6570\u91cf\uff09\u3002\u7531\u6b64\u5e2e\u52a9\u7ea2\u7261\u4e39\u5316\u5de5\u516c\u53f8\u627e\u5230\u6700\u4f18\u7684\u751f\u4ea7\u51b3\u7b56\u65b9\u6848\u3002\n\n", 20 | "answer": 50 21 | } 22 | } -------------------------------------------------------------------------------- /data/datasets/question_lengths.txt: -------------------------------------------------------------------------------- 1 | [677, 574, 565, 464, 996, 1062, 592, 1051, 530, 584, 520, 875, 210, 669, 1019, 798, 609, 648, 663, 361, 515, 716, 456, 158, 541, 564, 577, 506, 429, 473, 415, 677, 373, 654, 605, 694, 638, 405, 1066, 311, 363, 490, 528, 666, 492, 842, 687, 524, 326, 839, 577, 598, 466, 910, 958, 492, 314, 563, 918, 405, 696, 299, 462, 1106, 715, 407, 475, 244, 481, 336, 504, 301, 702, 443, 174, 934, 459, 617, 1075, 664, 1539, 641, 1236] -------------------------------------------------------------------------------- /data/images/problems_distribution_pie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/data/images/problems_distribution_pie.png -------------------------------------------------------------------------------- /data/images/problems_distribution_pie_no_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/data/images/problems_distribution_pie_no_text.png -------------------------------------------------------------------------------- /data/images/question_length_histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/data/images/question_length_histogram.png -------------------------------------------------------------------------------- /data/images/types_distribution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwz96sco/or_llm_agent/5c908db82e865b29380c99141280f91f0369d10e/data/images/types_distribution.png -------------------------------------------------------------------------------- /data/process_complexor_dataset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import json 4 | import glob 5 | 6 | def process_complexor_dataset(): 7 | # Path to the ComplexOR dataset 8 | complexor_path = "data/datasets/ComplexOR" 9 | 10 | # Get all problem directories 11 | prob_dirs = glob.glob(os.path.join(complexor_path, "*")) 12 | # Filter out any non-directory items 13 | prob_dirs = [d for d in prob_dirs if os.path.isdir(d)] 14 | 15 | # Sort directories alphabetically 16 | prob_dirs.sort() 17 | 18 | # Dictionary to store all the processed problems 19 | combined_data = {} 20 | 21 | # Process each problem directory 22 | for i, prob_dir in enumerate(prob_dirs): 23 | # Extract problem name (directory name) 24 | prob_name = os.path.basename(prob_dir) 25 | 26 | # Paths to the description and sample files 27 | description_path = os.path.join(prob_dir, "description.txt") 28 | sample_path = os.path.join(prob_dir, "sample.json") 29 | 30 | # Check if both files exist 31 | if not (os.path.exists(description_path) and os.path.exists(sample_path)): 32 | print(f"Warning: Missing files in {prob_dir}. Skipping.") 33 | continue 34 | 35 | # Read the question from description.txt 36 | with open(description_path, 'r', encoding='utf-8') as f: 37 | question = f.read().strip() 38 | 39 | # Read the answer and input from sample.json 40 | try: 41 | with open(sample_path, 'r', encoding='utf-8') as f: 42 | sample_data = json.load(f) 43 | # Assuming the output is the answer we want 44 | if isinstance(sample_data, list) and len(sample_data) > 0: 45 | if 'output' in sample_data[0]: 46 | answer = sample_data[0]['output'] 47 | # If answer is a list with one item, extract that item 48 | if isinstance(answer, list) and len(answer) == 1: 49 | answer = answer[0] 50 | else: 51 | print(f"Warning: No 'output' field in {prob_dir}/sample.json. Skipping.") 52 | continue 53 | 54 | # Add input data to the question if available 55 | if 'input' in sample_data[0]: 56 | input_data = sample_data[0]['input'] 57 | # Format input data as a string and append to question 58 | input_str = json.dumps(input_data, indent=2) 59 | question += f"\n\nInput:\n{input_str}" 60 | else: 61 | print(f"Warning: Unexpected sample.json format in {prob_dir}. Skipping.") 62 | continue 63 | except json.JSONDecodeError: 64 | print(f"Warning: Invalid JSON in {prob_dir}/sample.json. Skipping.") 65 | continue 66 | 67 | # Add to combined data 68 | combined_data[str(i)] = { 69 | "index": i, 70 | "question": question, 71 | "answer": answer 72 | } 73 | 74 | # Write the combined data to a JSON file 75 | output_path = "data/datasets/complexor_combined_result.json" 76 | with open(output_path, 'w', encoding='utf-8') as f: 77 | json.dump(combined_data, f, indent=4, ensure_ascii=False) 78 | 79 | print(f"Processing complete. Output written to {output_path}") 80 | print(f"Processed {len(combined_data)} problems out of {len(prob_dirs)} directories") 81 | 82 | if __name__ == "__main__": 83 | process_complexor_dataset() -------------------------------------------------------------------------------- /data/process_dataset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import json 4 | import glob 5 | import argparse 6 | 7 | def process_dataset(dataset_path, output_file, is_numbered=True): 8 | """ 9 | Process a dataset containing problem directories with description.txt and sample.json files. 10 | 11 | Args: 12 | dataset_path (str): Path to the dataset directory 13 | output_file (str): Path to the output JSON file 14 | is_numbered (bool): Whether the directories have numeric indices (e.g., prob_10) or names 15 | """ 16 | # Get all problem directories 17 | if is_numbered: 18 | prob_dirs = glob.glob(os.path.join(dataset_path, "prob_*")) 19 | # Sort directories by problem number for numbered directories 20 | prob_dirs.sort(key=lambda x: int(x.split("_")[-1])) 21 | else: 22 | prob_dirs = glob.glob(os.path.join(dataset_path, "*")) 23 | # Filter out any non-directory items 24 | prob_dirs = [d for d in prob_dirs if os.path.isdir(d)] 25 | # Sort directories alphabetically for named directories 26 | prob_dirs.sort() 27 | 28 | # Dictionary to store all the processed problems 29 | combined_data = {} 30 | 31 | # Process each problem directory 32 | for i, prob_dir in enumerate(prob_dirs): 33 | # Extract problem identifier (directory name or number) 34 | prob_id = os.path.basename(prob_dir) 35 | 36 | # Paths to the description and sample files 37 | description_path = os.path.join(prob_dir, "description.txt") 38 | sample_path = os.path.join(prob_dir, "sample.json") 39 | 40 | # Check if both files exist 41 | if not (os.path.exists(description_path) and os.path.exists(sample_path)): 42 | print(f"Warning: Missing files in {prob_dir}. Skipping.") 43 | continue 44 | 45 | # Read the question from description.txt 46 | with open(description_path, 'r', encoding='utf-8') as f: 47 | question = f.read().strip() 48 | 49 | # Read the answer and input from sample.json 50 | try: 51 | with open(sample_path, 'r', encoding='utf-8') as f: 52 | sample_data = json.load(f) 53 | # Assuming the output is the answer we want 54 | if isinstance(sample_data, list) and len(sample_data) > 0: 55 | if 'output' in sample_data[0]: 56 | answer = sample_data[0]['output'] 57 | # If answer is a list with one item, extract that item 58 | if isinstance(answer, list) and len(answer) == 1: 59 | answer = answer[0] 60 | else: 61 | print(f"Warning: No 'output' field in {prob_dir}/sample.json. Skipping.") 62 | continue 63 | 64 | # Add input data to the question if available 65 | if 'input' in sample_data[0]: 66 | input_data = sample_data[0]['input'] 67 | # Format input data as a string and append to question 68 | input_str = json.dumps(input_data, indent=2) 69 | question += f"\n\nInput:\n{input_str}" 70 | else: 71 | print(f"Warning: Unexpected sample.json format in {prob_dir}. Skipping.") 72 | continue 73 | except json.JSONDecodeError: 74 | print(f"Warning: Invalid JSON in {prob_dir}/sample.json. Skipping.") 75 | continue 76 | 77 | # Add to combined data 78 | combined_data[str(i)] = { 79 | "index": i, 80 | "question": question, 81 | "answer": answer 82 | } 83 | 84 | # Create directories if they don't exist 85 | os.makedirs(os.path.dirname(output_file), exist_ok=True) 86 | 87 | # Write the combined data to a JSON file 88 | with open(output_file, 'w', encoding='utf-8') as f: 89 | json.dump(combined_data, f, indent=4, ensure_ascii=False) 90 | 91 | print(f"Processing complete. Output written to {output_file}") 92 | print(f"Processed {len(combined_data)} problems out of {len(prob_dirs)} directories") 93 | 94 | if __name__ == "__main__": 95 | # Set up command line arguments 96 | parser = argparse.ArgumentParser(description='Process a dataset of problems into a combined JSON file.') 97 | parser.add_argument('dataset_path', help='Path to the dataset directory') 98 | parser.add_argument('output_file', help='Path to the output JSON file') 99 | parser.add_argument('--named', action='store_true', help='Use if directories have names instead of numeric indices') 100 | 101 | args = parser.parse_args() 102 | 103 | # Process the dataset 104 | process_dataset(args.dataset_path, args.output_file, not args.named) -------------------------------------------------------------------------------- /data/process_lpwp_dataset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import json 4 | import glob 5 | 6 | def process_lpwp_dataset(): 7 | # Path to the LPWP dataset 8 | lpwp_path = "data/datasets/LPWP" 9 | 10 | # Get all problem directories 11 | prob_dirs = glob.glob(os.path.join(lpwp_path, "prob_*")) 12 | 13 | # Sort directories by problem number 14 | prob_dirs.sort(key=lambda x: int(x.split("_")[-1])) 15 | 16 | # Dictionary to store all the processed problems 17 | combined_data = {} 18 | 19 | # Process each problem directory 20 | for i, prob_dir in enumerate(prob_dirs): 21 | # Extract problem number 22 | prob_number = prob_dir.split("_")[-1] 23 | 24 | # Paths to the description and sample files 25 | description_path = os.path.join(prob_dir, "description.txt") 26 | sample_path = os.path.join(prob_dir, "sample.json") 27 | 28 | # Check if both files exist 29 | if not (os.path.exists(description_path) and os.path.exists(sample_path)): 30 | print(f"Warning: Missing files in {prob_dir}. Skipping.") 31 | continue 32 | 33 | # Read the question from description.txt 34 | with open(description_path, 'r', encoding='utf-8') as f: 35 | question = f.read().strip() 36 | 37 | # Read the answer and input from sample.json 38 | try: 39 | with open(sample_path, 'r', encoding='utf-8') as f: 40 | sample_data = json.load(f) 41 | # Assuming the output is the answer we want 42 | if isinstance(sample_data, list) and len(sample_data) > 0: 43 | if 'output' in sample_data[0]: 44 | answer = sample_data[0]['output'] 45 | # If answer is a list with one item, extract that item 46 | if isinstance(answer, list) and len(answer) == 1: 47 | answer = answer[0] 48 | else: 49 | print(f"Warning: No 'output' field in {prob_dir}/sample.json. Skipping.") 50 | continue 51 | 52 | # Add input data to the question if available 53 | if 'input' in sample_data[0]: 54 | input_data = sample_data[0]['input'] 55 | # Format input data as a string and append to question 56 | input_str = json.dumps(input_data, indent=2) 57 | question += f"\n\nInput:\n{input_str}" 58 | else: 59 | print(f"Warning: Unexpected sample.json format in {prob_dir}. Skipping.") 60 | continue 61 | except json.JSONDecodeError: 62 | print(f"Warning: Invalid JSON in {prob_dir}/sample.json. Skipping.") 63 | continue 64 | 65 | # Add to combined data 66 | combined_data[str(i)] = { 67 | "index": i, 68 | "question": question, 69 | "answer": answer 70 | } 71 | 72 | # Write the combined data to a JSON file 73 | output_path = "data/datasets/lpwp_combined_result.json" 74 | with open(output_path, 'w', encoding='utf-8') as f: 75 | json.dump(combined_data, f, indent=4, ensure_ascii=False) 76 | 77 | print(f"Processing complete. Output written to {output_path}") 78 | print(f"Processed {len(combined_data)} problems out of {len(prob_dirs)} directories") 79 | 80 | if __name__ == "__main__": 81 | process_lpwp_dataset() -------------------------------------------------------------------------------- /data/question_length.py: -------------------------------------------------------------------------------- 1 | import json 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | from scipy import stats 5 | 6 | # Path to the JSON file 7 | json_file_path = "data/datasets/dataset_combined_result_mark.json" 8 | 9 | # Read the JSON file 10 | with open(json_file_path, 'r', encoding='utf-8') as file: 11 | data = json.load(file) 12 | 13 | # Extract question lengths 14 | question_lengths = [] 15 | 16 | # Iterate through each item in the JSON 17 | for key, item in data.items(): 18 | if "question" in item: 19 | # Calculate the length of the question 20 | question_length = len(item["question"]) 21 | question_lengths.append(question_length) 22 | 23 | # Print the result 24 | print(f"Number of questions processed: {len(question_lengths)}") 25 | print(f"Question lengths: {question_lengths}") 26 | 27 | # Optionally, save the result to a file 28 | with open("data/datasets/question_lengths.txt", 'w') as output_file: 29 | output_file.write(str(question_lengths)) 30 | 31 | # Set the style for a cleaner look 32 | plt.style.use('seaborn-v0_8-whitegrid') 33 | plt.rcParams['axes.facecolor'] = 'white' 34 | plt.rcParams['figure.facecolor'] = 'white' 35 | 36 | # Set font to Times New Roman and increase font sizes 37 | plt.rcParams['font.family'] = 'Times New Roman' 38 | plt.rcParams['font.size'] = 16 39 | plt.rcParams['axes.titlesize'] = 24 40 | plt.rcParams['axes.labelsize'] = 20 41 | plt.rcParams['xtick.labelsize'] = 18 42 | plt.rcParams['ytick.labelsize'] = 18 43 | 44 | # Generate histogram 45 | fig, ax = plt.subplots(figsize=(10, 6)) 46 | 47 | # Create bins of size 100 48 | min_length = min(question_lengths) 49 | max_length = max(question_lengths) 50 | bin_edges = np.arange(min_length - min_length % 100, max_length + 100, 100) 51 | 52 | # Create the histogram with density=True to normalize for KDE comparison 53 | histogram = ax.hist(question_lengths, bins=bin_edges.tolist(), alpha=1.0, color='#2E8B8B', 54 | edgecolor='white', linewidth=0.5, density=True) 55 | 56 | # Generate x values for smooth curve (more points than our bins) 57 | x_values = np.linspace(min_length, max_length, 1000) 58 | 59 | # Create kernel density estimation for smooth curve 60 | kde = stats.gaussian_kde(question_lengths, bw_method='scott') 61 | density_curve = kde(x_values) 62 | 63 | # Plot the KDE curve 64 | ax.plot(x_values, density_curve, color='#2A2E8C', linewidth=2) 65 | 66 | # Clean up the plot - remove spines 67 | for spine in ['top', 'right']: 68 | ax.spines[spine].set_visible(False) 69 | 70 | # Add labels and title 71 | ax.set_xlabel('Question Length (characters)', fontsize=20) 72 | ax.set_ylabel('Frequency Distribution', fontsize=20) 73 | ax.set_title('Question Length Distribution', fontsize=24, color='#2E8B57') 74 | 75 | # Remove the legend as it's not in the example 76 | # plt.legend() 77 | 78 | # Add text with statistics in a neater format 79 | stats_text = (f"Total Questions: {len(question_lengths)}\n" 80 | f"Min Length: {min_length}\n" 81 | f"Max Length: {max_length}\n" 82 | f"Average Length: {sum(question_lengths)/len(question_lengths):.2f}\n" 83 | f"Median Length: {np.median(question_lengths):.2f}") 84 | 85 | # Position and display the statistics text with the Times New Roman font 86 | ax.text(0.73, 0.95, stats_text, transform=ax.transAxes, fontsize=16, verticalalignment='top', 87 | fontfamily='Times New Roman', bbox=dict(facecolor='white', alpha=0.8, edgecolor='none', pad=5)) 88 | 89 | # Add lighter horizontal grid lines only 90 | ax.yaxis.grid(True, linestyle='-', alpha=0.2) 91 | ax.xaxis.grid(False) # Turn off vertical grid lines 92 | 93 | # Set y-axis to start at 0 94 | ax.set_ylim(bottom=0) 95 | 96 | # Adjust spacing to make it cleaner 97 | plt.tight_layout() 98 | 99 | # Save the histogram with higher DPI for better quality 100 | plt.savefig('data/images/question_length_histogram.png', dpi=300, bbox_inches='tight') 101 | print("Histogram with density curve saved as 'question_length_histogram.png'") 102 | 103 | # Show the histogram (this won't display in terminal, but useful if running in interactive environment) 104 | plt.show() -------------------------------------------------------------------------------- /data/save_json.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | 4 | a = [ 5 | r""" 6 | 7 | 表 1 给出了 12 个工件在设备 车床、刨床、 铣床、磨床 上的加工时间,要求: 8 | 9 | 若所有工件均依次在设备 车床、刨床、 铣床、磨床 上加工(即每个工件必须先在 车床 上加工,随后依次在刨床、 铣床、磨床 上进行加工),试安排使总加工时间最短的工件加工顺序,并计算总加工时间。 10 | 11 | ## 表 1 设备 车床、刨床、 铣床、磨床 的加工时间 12 | 13 | | 设备 | 工件 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | |-----|----------|----|----|----|----|----|----|----|----|----|----|----|----| 15 | | 车床 | 加工时间 | 5 | 8 | 11 | 2 | 7 | 6 | 3 | 9 | 8 | 3 | 6 | 10 | 16 | | 刨床 | 加工时间 | 5 | 9 | 4 | 3 | 7 | 9 | 5 | 4 | 9 | 5 | 3 | 4 | 17 | | 铣床 | 加工时间 | 4 | 7 | 8 | 3 | 6 | 5 | 4 | 8 | 7 | 4 | 5 | 9 | 18 | | 磨床 | 加工时间 | 6 | 8 | 5 | 4 | 7 | 8 | 6 | 5 | 8 | 6 | 4 | 7 | 19 | """, 20 | 21 | r""" 22 | 23 | 24 | 一艘货轮分前、中、后三个舱位,它们的容积与最大允许载重量如 **表 1** 所示。 25 | 现有三种货物待运,已知有关数据列于 **表 2**。 26 | 27 | ## 表 1 最大允许载重量与容积 28 | 29 | | 项目 | 前舱 | 中舱 | 后舱 | 30 | |--------------------|------|------|------| 31 | | 最大允许载重量 (t) | 2000 | 3000 | 1500 | 32 | | 容积 (m^3) | 4000 | 5000 | 1500 | 33 | 34 | ## 表 2 货物数据 35 | 36 | | 商品 | 数量 (件) | 每件体积 (m^3/件) | 每件重量 (t/件) | 运价 (元/件) | 37 | |------|-----------|---------------------|-----------------|--------------| 38 | | A | 600 | 10 | 8 | 1000 | 39 | | B | 1000 | 5 | 6 | 700 | 40 | | C | 800 | 7 | 4 | 600 | 41 | 42 | 又为了航运安全,前、中、后舱的实际载重量大体保持各舱最大允许载重量的比例关系。 43 | 具体要求:前、后舱分别与中舱之间载重量比例的偏差不超过 15%,前、后舱之间不超过 10%。 44 | 45 | **问题:** 46 | 该货轮应装载 A、B、C 各多少件货物以使收入为最大?试建立这个问题的线性规划模型。 47 | 48 | """, 49 | 50 | r""" 51 | 52 | 53 | 某化学公司有甲、乙、丙、丁四个化工厂生产某种产品,产量分别为 200, 300, 400, 100(t),供应 I、Ⅱ、Ⅲ、IV、V、VI 六个地区的需要,需要量分别为 200, 150, 400, 100, 150, 150(t)。由于工艺、技术等条件差别,各厂每 kg 产品成本分别为 1.2, 1.4, 1.1, 1.5(元),又由于行情不同,各地区销售价分别为 2.0, 2.4, 1.8, 2.2, 1.6, 2.0(元/kg)。已知从各厂运往各销售地区每 kg 产品运价如表 1 所示。 54 | 55 | ## 表 1 每kg产品的运价 56 | 57 | | 工厂\地区 | I | II | III | IV | V | VI | 58 | |-----------|-----|-----|-----|-----|-----|-----| 59 | | 甲 | 0.5 | 0.4 | 0.3 | 0.4 | 0.3 | 0.1 | 60 | | 乙 | 0.3 | 0.8 | 0.9 | 0.5 | 0.6 | 0.2 | 61 | | 丙 | 0.7 | 0.7 | 0.3 | 0.7 | 0.4 | 0.4 | 62 | | 丁 | 0.6 | 0.4 | 0.2 | 0.6 | 0.5 | 0.8 | 63 | 64 | 如第 III 个地区至少供应 100 t,第 IV 个地区的需要必须全部满足,试确定使该公司获利最大的产品调运方案。 65 | 66 | """, 67 | 68 | r""" 69 | 70 | 8 月初的一个星期一,副董事长宋持平请财务、销售和生产经理到他的办公室,讨论本生产季节**聚丙烯粉料**的生产数量问题。今年按照采购计划购买的 **300,000 kg** 聚丙烯粉料已全部运抵工厂,生产将于下周一正式开始。红牡丹化工公司是一家中型化工企业,主要从事高分子改性材料的生产与销售,在东北地区拥有一定的市场知名度。 71 | 72 | 财务经理钱源和销售经理肖通先行到达。生产经理刘华随后赶到,并带来了最新的原料检验报告。报告显示:在 **300,000 kg** 的聚丙烯粉料中,大约有 **20%**(即 60,000 kg)为 **高纯度(A 级)**,其余约 **80%**(240,000 kg)为 **普通纯度(B 级)**。 73 | 74 | --- 75 | 76 | ### 不同聚丙烯改性产品的市场需求 77 | 78 | 宋持平向肖通询问下一年改性聚丙烯产品的市场需求情况。肖通表示,根据实际需要量估计,公司生产的 **改性聚丙烯 A** 能全部售出,但 **改性聚丙烯 B** 和 **改性聚丙烯 C** 的需求有一定上限。具体预计需求和基本数据见表 1。销售价格是根据公司长期市场规划而确定,销售需求来自对该定价策略的市场预测。 79 | 80 | #### 表 1 需求预测与原料用量 81 | 82 | | 产品 | 销售价格(元/桶) | 原料用量(kg/桶) | 需求预测(桶) | 83 | |--------------------|-------------------|-------------------|----------------| 84 | | 改性聚丙烯 A(A) | 4.00 | 1.8 | 800,000 | 85 | | 改性聚丙烯 B(B) | 4.50 | 2.0 | 50,000 | 86 | | 改性聚丙烯 C(C) | 3.80 | 2.5 | 80,000 | 87 | 88 | 89 | 看完肖通的需求预测后,财务经理钱源提出:“应该尽可能把所有聚丙烯粉料用于**改性聚丙烯 A** 的生产,今年的形势相当不错。”他通过新建立的会计系统计算了各类产品的利润贡献,发现 **改性聚丙烯 A** 的利润明显高于其他产品。公司在今年 5 月与供应商签订的平均采购价格为 **0.6 元/kg**,钱源还编制了各产品的利润贡献分析表(见表 2)。 90 | 91 | --- 92 | 93 | ### A 级原料限制与品质评分 94 | 95 | 这时,生产经理刘华提醒大家:“虽然公司产能总体上足够,但不可能将所有原料都做成 **改性聚丙烯 A**,因为高纯度(A 级)原料的比例有限。”红牡丹化工公司采用数字化评分来评估聚丙烯粉料品质:**A 级原料**平均评分 9 分,**B 级原料**平均评分 5 分。根据公司的工艺标准: 96 | 97 | - **改性聚丙烯 A** 的原料平均得分要求 ≥ 8 分 98 | - **改性聚丙烯 B** 的原料平均得分要求 ≥ 6 分 99 | - **改性聚丙烯 C** 可以全部用 B 级原料生产 100 | 101 | 这意味着,如果只依赖现有的 60,000 kg A 级原料,即使全部用于生产 A 产品,也只能保证 **改性聚丙烯 A** 的产量不超过 44,500 桶左右。 102 | 103 | 不过,宋持平认为这并非唯一选择。他说,曾有人提出以 **0.85 元/kg** 的价格提供 80,000 kg 额外的 A 级原料,当时公司没有采购,但如果需要,仍可尝试联系对方再次购买。 104 | 105 | --- 106 | 107 | ### 表 2 产品获利分析表 (单位:元/桶) 108 | 109 | | 成本 | 改性聚丙烯 A | 改性聚丙烯 B | 改性聚丙烯 C | 110 | |----------------------|-------------|-------------|-------------| 111 | | 销售价格 | 4.00 | 4.50 | 3.80 | 112 | | **变动成本** | | | | 113 | | 直接人工 | 1.18 | 1.32 | 0.54 | 114 | | 可变管理成本 | 0.24 | 0.36 | 0.26 | 115 | | 可变销售成本 | 0.40 | 0.85 | 0.38 | 116 | | 包装材料 | 0.70 | 0.65 | 0.77 | 117 | | 原材料(统一按 0.6) | 1.08 | 1.20 | 1.50 | 118 | | 变动成本小计 | 3.60 | 4.38 | 3.45 | 119 | | **净利润每桶** | 0.40 | 0.12 | 0.35 | 120 | 121 | 在此基础上,销售经理肖通提出了不同观点。他认为不该只按重量简单分摊原料成本,而应考虑 A 级和 B 级原料的真实价值差异,并据此重新核算边际利润(表 3)。他提出,如果只用 200,000 kg 的 B 级原料生产 **改性聚丙烯 C**,然后用剩余 40,000 kg 的 B 级与全部 A 级原料去生产 **改性聚丙烯 B**,则可在需求全部满足的前提下达到最高利润 —— 约 **4.8 万元**。 122 | 123 | --- 124 | 125 | ### 表 3 改性聚丙烯产品的边际利润分析 (单位:元/桶) 126 | 127 | | 产品 | 改性聚丙烯 A | 改性聚丙烯 B | 改性聚丙烯 C | 128 | |----------------------------|-------------|-------------|-------------| 129 | | 销售价格 | 4.00 | 4.50 | 3.80 | 130 | | 变动成本 (不含原料成本) | 2.52 | 3.18 | 1.95 | 131 | | 原料成本 (区分 A/B 级) | 1.48 | 1.32 | 1.85 | 132 | | 原料成本小计 | 1.49 | 1.24 | 1.30 | 133 | | **边际利润** | -0.01 | 0.08 | 0.55 | 134 | 135 | --- 136 | 137 | #### 肖通的计算依据 138 | 139 | - \( Z = \) 每 kg A 级聚丙烯粉料的折算成本(元/kg) 140 | - \( Y = \) 每 kg B 级聚丙烯粉料的折算成本(元/kg) 141 | 142 | 根据公司总成本和评分约束,列出方程: 143 | 144 | \[ 145 | 60000Z + 240000Y = 300000 * 0.6 146 | \] 147 | 148 | \[ 149 | 9Y = 5Z 150 | \] 151 | 152 | 联立求解,得到: 153 | 154 | \[ 155 | Z = 0.931 (元/kg), Y = 0.517 (元/kg) 156 | \] 157 | 158 | --- 159 | 160 | ### 问题:构建线性规划模型 161 | 162 | 根据上述背景,红牡丹化工公司想要确定最优的生产方案,以最大化利润。假设你是该公司的运营管理顾问,请: 163 | 164 | 1. **建立决策变量**:分别用来表示生产三种产品(改性聚丙烯 A、B、C)的数量; 165 | 2. **列出目标函数**:在满足需求预测、原料供应以及品质限制的前提下,使得公司利润最大化; 166 | 3. **设置约束条件**: 167 | - 原料总量约束(A 级、B 级以及可能外购的 A 级原料); 168 | - 不同产品对原料品质(评分)的约束; 169 | - 各产品的最大需求量约束; 170 | - 非负性约束等。 171 | 172 | 请写出完整的线性规划模型,并给出公司在何种条件下应考虑外购更多 A 级原料(以及最佳采购数量)。由此帮助红牡丹化工公司找到最优的生产决策方案。 173 | 174 | """ 175 | 176 | ] 177 | 178 | b = [50, 885000.0, 445000.0, 50] 179 | 180 | 181 | def list_to_dict_and_save_to_json(my_list, filename): 182 | """ 183 | 将列表转换为字典并存储为本地JSON文件。 184 | 185 | Args: 186 | my_list: 要转换的列表。 187 | filename: JSON文件的名称。 188 | """ 189 | 190 | # 检查列表是否为空 191 | if not my_list: 192 | print("列表为空,无法转换为字典。") 193 | return 194 | 195 | # 将列表转换为字典 196 | my_dict = {} 197 | for i, item in enumerate(my_list): 198 | my_dict[str(i)] = item # 使用索引作为键 199 | 200 | # 将字典保存为JSON文件 201 | with open(filename, 'w') as f: 202 | json.dump(my_dict, f, indent=4) # 使用indent参数美化JSON输出 203 | 204 | print(f"列表已转换为字典并保存到 {filename} 文件。") 205 | 206 | # 示例 207 | #my_list = ['apple', 'banana', 'cherry'] 208 | # filename = 'data_question_0214.json' 209 | # list_to_dict_and_save_to_json(a, filename) 210 | 211 | merged_list = [{"index":i, "question": q, "answer": a} for i, (q, a) in enumerate(zip(a, b))] 212 | list_to_dict_and_save_to_json(merged_list, 'data/datasets/dataset_md_result.json') 213 | # 214 | -------------------------------------------------------------------------------- /mcp_server.py: -------------------------------------------------------------------------------- 1 | from mcp.server.fastmcp import FastMCP 2 | from or_llm_eval import or_llm_agent 3 | import io 4 | from contextlib import redirect_stdout 5 | # Initialize FastMCP server 6 | mcp = FastMCP("or_llm_agent") 7 | 8 | @mcp.tool() 9 | def get_operation_research_problem_answer(user_question: str) -> str: 10 | """ 11 | Use the agent to solve the optimization problem. Agent will generate python gurobi code and run it to get the result. 12 | 13 | Args: 14 | user_question: The user's question 15 | 16 | Returns: 17 | The result of the optimization problem, including math model, gurobi code and result. 18 | """ 19 | buffer2 = io.StringIO() 20 | with redirect_stdout(buffer2): 21 | or_llm_agent(user_question) 22 | return buffer2.getvalue() 23 | 24 | if __name__ == "__main__": 25 | mcp.run() 26 | -------------------------------------------------------------------------------- /or_llm_eval.py: -------------------------------------------------------------------------------- 1 | import openai 2 | import anthropic 3 | from dotenv import load_dotenv 4 | import os 5 | import re 6 | import subprocess 7 | import sys 8 | import tempfile 9 | import copy 10 | import json 11 | import argparse 12 | from itertools import zip_longest 13 | from utils import ( 14 | is_number_string, 15 | convert_to_number, 16 | extract_best_objective, 17 | extract_and_execute_python_code, 18 | eval_model_result 19 | ) 20 | 21 | # Load environment variables from .env file 22 | load_dotenv() 23 | 24 | # OpenAI API setup 25 | openai_api_data = dict( 26 | api_key = os.getenv("OPENAI_API_KEY"), 27 | base_url = os.getenv("OPENAI_API_BASE") 28 | ) 29 | 30 | # Anthropic API setup 31 | anthropic_api_data = dict( 32 | api_key = os.getenv("CLAUDE_API_KEY"), 33 | ) 34 | 35 | # Initialize clients 36 | openai_client = openai.OpenAI( 37 | api_key=openai_api_data['api_key'], 38 | base_url=openai_api_data['base_url'] if openai_api_data['base_url'] else None 39 | ) 40 | 41 | anthropic_client = anthropic.Anthropic( 42 | api_key=anthropic_api_data['api_key'] 43 | ) 44 | 45 | def query_llm(messages, model_name="o3-mini", temperature=0.2): 46 | """ 47 | Call LLM to get response results. 48 | 49 | Args: 50 | messages (list): List of conversation context. 51 | model_name (str): LLM model name, default is "o3-mini". 52 | temperature (float): Controls the randomness of output, default is 0.2. 53 | 54 | Returns: 55 | str: Response content generated by the LLM. 56 | """ 57 | # Check if model is Claude (Anthropic) 58 | if model_name.lower().startswith("claude"): 59 | # Convert OpenAI message format to Anthropic format 60 | system_message = next((m["content"] for m in messages if m["role"] == "system"), "") 61 | user_messages = [m["content"] for m in messages if m["role"] == "user"] 62 | assistant_messages = [m["content"] for m in messages if m["role"] == "assistant"] 63 | 64 | # Combine messages into a single conversation string 65 | conversation = system_message + "\n\n" 66 | for user_msg, asst_msg in zip_longest(user_messages, assistant_messages, fillvalue=None): 67 | if user_msg: 68 | conversation += f"Human: {user_msg}\n\n" 69 | if asst_msg: 70 | conversation += f"Assistant: {asst_msg}\n\n" 71 | 72 | # Add the final user message if there is one 73 | if len(user_messages) > len(assistant_messages): 74 | conversation += f"Human: {user_messages[-1]}\n\n" 75 | 76 | response = anthropic_client.messages.create( 77 | model=model_name, 78 | max_tokens=8192, 79 | temperature=temperature, 80 | messages=[{ 81 | "role": "user", 82 | "content": conversation 83 | }] 84 | ) 85 | return response.content[0].text 86 | else: 87 | # Use OpenAI API 88 | response = openai_client.chat.completions.create( 89 | model=model_name, 90 | messages=messages, 91 | temperature=temperature 92 | ) 93 | return response.choices[0].message.content 94 | 95 | def generate_or_code_solver(messages_bak, model_name, max_attempts): 96 | messages = copy.deepcopy(messages_bak) 97 | 98 | gurobi_code = query_llm(messages, model_name) 99 | print("【Python Gurobi Code】:\n", gurobi_code) 100 | 101 | # 4. Code execution & fixes 102 | text = f"{gurobi_code}" 103 | attempt = 0 104 | while attempt < max_attempts: 105 | success, error_msg = extract_and_execute_python_code(text) 106 | if success: 107 | messages_bak.append({"role": "assistant", "content": gurobi_code}) 108 | return True, error_msg, messages_bak 109 | 110 | print(f"\nAttempt {attempt + 1} failed, requesting LLM to fix code...\n") 111 | 112 | # Build repair request 113 | messages.append({"role": "assistant", "content": gurobi_code}) 114 | messages.append({"role": "user", "content": f"Code execution encountered an error, error message is as follows:\n{error_msg}\nPlease fix the code and provide the complete executable code again."}) 115 | 116 | # Get the fixed code 117 | gurobi_code = query_llm(messages, model_name) 118 | text = f"{gurobi_code}" 119 | 120 | print("\nReceived fixed code, preparing to execute again...\n") 121 | attempt += 1 122 | # not add gurobi code 123 | messages_bak.append({"role": "assistant", "content": gurobi_code}) 124 | print(f"Reached maximum number of attempts ({max_attempts}), could not execute code successfully.") 125 | return False, None, messages_bak 126 | 127 | def or_llm_agent(user_question, model_name="o3-mini", max_attempts=3): 128 | """ 129 | Request Gurobi code solution from LLM and execute it, attempt to fix if it fails. 130 | 131 | Args: 132 | user_question (str): User's problem description. 133 | model_name (str): LLM model name to use, default is "gpt-4". 134 | max_attempts (int): Maximum number of attempts, default is 3. 135 | 136 | Returns: 137 | tuple: (success: bool, best_objective: float or None, final_code: str) 138 | """ 139 | # Initialize conversation history 140 | messages = [ 141 | {"role": "system", "content": ( 142 | "You are an operations research expert. Based on the optimization problem provided by the user, construct a mathematical model that effectively models the original problem using mathematical (linear programming) expressions." 143 | "Focus on obtaining a correct mathematical model expression without too much concern for explanations." 144 | "This model will be used later to guide the generation of Gurobi code, and this step is mainly used to generate effective linear scale expressions." 145 | )}, 146 | {"role": "user", "content": user_question} 147 | ] 148 | 149 | # 1. Generate mathematical model 150 | math_model = query_llm(messages, model_name) 151 | print("【Mathematical Model】:\n", math_model) 152 | 153 | # # 2. Validate mathematical model 154 | # messages.append({"role": "assistant", "content": math_model}) 155 | # messages.append({"role": "user", "content": ( 156 | # "Please check if the above mathematical model matches the problem description. If there are errors, make corrections; if there are no errors, check if it can be optimized." 157 | # "In any case, please output the final mathematical model again." 158 | # )}) 159 | 160 | # validate_math_model = query_llm(messages, model_name) 161 | # print("【Validated Mathematical Model】:\n", validate_math_model) 162 | 163 | validate_math_model = math_model 164 | messages.append({"role": "assistant", "content": validate_math_model}) 165 | 166 | # ------------------------------ 167 | messages.append({"role": "user", "content": ( 168 | "Based on the above mathematical model, write complete and reliable Python code using Gurobi to solve this operations research optimization problem." 169 | "The code should include necessary model construction, variable definitions, constraint additions, objective function settings, as well as solving and result output." 170 | "Output in the format ```python\n{code}\n```, without code explanations." 171 | )}) 172 | # copy msg; solve; add the laset gurobi code 173 | is_solve_success, result, messages = generate_or_code_solver(messages, model_name,max_attempts) 174 | print(f'Stage result: {is_solve_success}, {result}') 175 | if is_solve_success: 176 | if not is_number_string(result): 177 | print('!![No available solution warning]!!') 178 | # no solution 179 | messages.append({"role": "user", "content": ( 180 | "The current model resulted in *no feasible solution*. Please carefully check the mathematical model and Gurobi code for errors that might be causing the infeasibility." 181 | "After checking, please reoutput the Gurobi Python code." 182 | "Output in the format ```python\n{code}\n```, without code explanations." 183 | )}) 184 | is_solve_success, result, messages = generate_or_code_solver(messages, model_name, max_attempts=1) 185 | else: 186 | print('!![Max attempt debug error warning]!!') 187 | messages.append({"role": "user", "content": ( 188 | "The model code still reports errors after multiple debugging attempts. Please carefully check if there are errors in the mathematical model." 189 | "After checking, please rebuild the Gurobi Python code." 190 | "Output in the format ```python\n{code}\n```, without code explanations." 191 | )}) 192 | is_solve_success, result, messages = generate_or_code_solver(messages, model_name, max_attempts=2) 193 | 194 | return is_solve_success, result 195 | 196 | def gpt_code_agent_simple(user_question, model_name="o3-mini", max_attempts=3): 197 | """ 198 | Request Gurobi code solution from LLM and execute it, attempt to fix if it fails. 199 | 200 | Args: 201 | user_question (str): User's problem description. 202 | model_name (str): LLM model name to use, default is "gpt-4". 203 | max_attempts (int): Maximum number of attempts, default is 3. 204 | 205 | Returns: 206 | tuple: (success: bool, best_objective: float or None, final_code: str) 207 | """ 208 | # Initialize conversation history 209 | messages = [ 210 | {"role": "system", "content": ( 211 | "You are an operations research expert. Based on the optimization problem provided by the user, construct a mathematical model and write complete, reliable Python code using Gurobi to solve the operations research optimization problem." 212 | "The code should include necessary model construction, variable definitions, constraint additions, objective function settings, as well as solving and result output." 213 | "Output in the format ```python\n{code}\n```, without code explanations." 214 | )}, 215 | {"role": "user", "content": user_question} 216 | ] 217 | 218 | # copy msg; solve; add the laset gurobi code 219 | gurobi_code = query_llm(messages, model_name) 220 | print("【Python Gurobi Code】:\n", gurobi_code) 221 | text = f"{gurobi_code}" 222 | is_solve_success, result = extract_and_execute_python_code(text) 223 | 224 | print(f'Stage result: {is_solve_success}, {result}') 225 | 226 | return is_solve_success, result 227 | 228 | def parse_args(): 229 | """ 230 | Parse command line arguments. 231 | 232 | Returns: 233 | argparse.Namespace: The parsed arguments 234 | """ 235 | parser = argparse.ArgumentParser(description='Run optimization problem solving with LLMs') 236 | parser.add_argument('--agent', action='store_true', 237 | help='Use the agent. If not specified, directly use the model to solve the problem') 238 | parser.add_argument('--model', type=str, default='o3-mini', 239 | help='Model name to use for LLM queries. Use "claude-..." for Claude models.') 240 | parser.add_argument('--data_path', type=str, default='data/datasets/dataset_combined_result.json', 241 | help='Path to the dataset JSON file') 242 | return parser.parse_args() 243 | 244 | if __name__ == "__main__": 245 | args = parse_args() 246 | 247 | with open(args.data_path, 'r') as f: 248 | dataset = json.load(f) 249 | #print(dataset['0']) 250 | 251 | model_name = args.model 252 | 253 | pass_count = 0 254 | correct_count = 0 255 | error_datas = [] 256 | for i, d in dataset.items(): 257 | print(f"=============== num {i} ==================") 258 | user_question, answer = d['question'], d['answer'] 259 | print(user_question) 260 | print('-------------') 261 | 262 | if args.agent: 263 | is_solve_success, llm_result = or_llm_agent(user_question, model_name) 264 | else: 265 | is_solve_success, llm_result = gpt_code_agent_simple(user_question, model_name) 266 | 267 | if is_solve_success: 268 | print(f"Successfully executed code, optimal solution value: {llm_result}") 269 | else: 270 | print("Failed to execute code.") 271 | print('------------------') 272 | pass_flag, correct_flag = eval_model_result(is_solve_success, llm_result, answer) 273 | 274 | pass_count += 1 if pass_flag else 0 275 | correct_count += 1 if correct_flag else 0 276 | 277 | if not pass_flag or not correct_flag: 278 | error_datas.append(i) 279 | 280 | print(f'solve: {is_solve_success}, llm: {llm_result}, ground truth: {answer}') 281 | print(f'[Final] run pass: {pass_flag}, solve correct: {correct_flag}') 282 | print(' ') 283 | 284 | print(f'[Total {len(dataset)}] run pass: {pass_count}, solve correct: {correct_count}') 285 | print(f'[Total fails {len(error_datas)}] error datas: {error_datas}') -------------------------------------------------------------------------------- /or_llm_eval_async.py: -------------------------------------------------------------------------------- 1 | import openai 2 | import anthropic 3 | from dotenv import load_dotenv 4 | import os 5 | import re 6 | import subprocess 7 | import sys 8 | import tempfile 9 | import copy 10 | import json 11 | import asyncio 12 | import argparse 13 | from itertools import zip_longest 14 | from utils import ( 15 | is_number_string, 16 | convert_to_number, 17 | extract_best_objective, 18 | eval_model_result 19 | ) 20 | 21 | # Load environment variables from .env file 22 | load_dotenv() 23 | 24 | # OpenAI API setup 25 | openai_api_data = dict( 26 | api_key = os.getenv("OPENAI_API_KEY"), 27 | base_url = os.getenv("OPENAI_API_BASE") 28 | ) 29 | 30 | # Anthropic API setup 31 | anthropic_api_data = dict( 32 | api_key = os.getenv("CLAUDE_API_KEY"), 33 | ) 34 | 35 | # Initialize clients 36 | openai_client = openai.AsyncOpenAI( 37 | api_key=openai_api_data['api_key'], 38 | base_url=openai_api_data['base_url'] if openai_api_data['base_url'] else None 39 | ) 40 | 41 | anthropic_client = anthropic.AsyncAnthropic( 42 | api_key=anthropic_api_data['api_key'] 43 | ) 44 | 45 | async def async_query_llm(messages, model_name="o3-mini", temperature=0.2): 46 | """ 47 | Async version of query_llm that supports both OpenAI and Claude models 48 | """ 49 | # Check if model is Claude (Anthropic) 50 | if model_name.lower().startswith("claude"): 51 | # Convert OpenAI message format to Anthropic format 52 | system_message = next((m["content"] for m in messages if m["role"] == "system"), "") 53 | user_messages = [m["content"] for m in messages if m["role"] == "user"] 54 | assistant_messages = [m["content"] for m in messages if m["role"] == "assistant"] 55 | 56 | # Combine messages into a single conversation string 57 | conversation = system_message + "\n\n" 58 | for user_msg, asst_msg in zip_longest(user_messages, assistant_messages, fillvalue=None): 59 | if user_msg: 60 | conversation += f"Human: {user_msg}\n\n" 61 | if asst_msg: 62 | conversation += f"Assistant: {asst_msg}\n\n" 63 | 64 | # Add the final user message if there is one 65 | if len(user_messages) > len(assistant_messages): 66 | conversation += f"Human: {user_messages[-1]}\n\n" 67 | 68 | response = await anthropic_client.messages.create( 69 | model=model_name, 70 | max_tokens=8192, 71 | temperature=temperature, 72 | messages=[{ 73 | "role": "user", 74 | "content": conversation 75 | }] 76 | ) 77 | return response.content[0].text 78 | else: 79 | # Use OpenAI API 80 | response = await openai_client.chat.completions.create( 81 | model=model_name, 82 | messages=messages, 83 | temperature=temperature 84 | ) 85 | return response.choices[0].message.content 86 | 87 | async def async_extract_and_execute_python_code(text_content): 88 | """ 89 | Async version of extract_and_execute_python_code 90 | """ 91 | python_code_blocks = re.findall(r'```python\s*([\s\S]*?)```', text_content) 92 | 93 | if not python_code_blocks: 94 | print("未找到Python代码块。") 95 | return False, "No Python code blocks found" 96 | 97 | for code_block in python_code_blocks: 98 | code_block = code_block.strip() 99 | if not code_block: 100 | print("找到一个空的Python代码块,已跳过。") 101 | continue 102 | 103 | print("找到Python代码块,开始执行...") 104 | try: 105 | with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as tmp_file: 106 | tmp_file.write(code_block) 107 | temp_file_path = tmp_file.name 108 | 109 | proc = await asyncio.create_subprocess_exec( 110 | sys.executable, 111 | temp_file_path, 112 | stdout=asyncio.subprocess.PIPE, 113 | stderr=asyncio.subprocess.PIPE 114 | ) 115 | stdout, stderr = await proc.communicate() 116 | 117 | if proc.returncode == 0: 118 | print("Python 代码执行成功,输出:\n") 119 | stdout_str = stdout.decode() 120 | print(stdout_str) 121 | 122 | best_obj = extract_best_objective(stdout_str) 123 | if best_obj is not None: 124 | print(f"\n最优解值 (Best objective): {best_obj}") 125 | else: 126 | print("\n未找到最优解值") 127 | return True, str(best_obj) 128 | else: 129 | print(f"Python 代码执行出错,错误信息:\n") 130 | print(stderr.decode()) 131 | return False, stderr.decode() 132 | 133 | except Exception as e: 134 | print(f"执行Python代码块时发生错误: {e}") 135 | return False, str(e) 136 | finally: 137 | if 'temp_file_path' in locals() and os.path.exists(temp_file_path): 138 | os.remove(temp_file_path) 139 | print("-" * 30) 140 | 141 | return False, "No valid code blocks executed" 142 | 143 | async def async_gpt_code_agent_simple(user_question, model_name="o3-mini", max_attempts=3): 144 | """ 145 | Async version of gpt_code_agent_simple 146 | """ 147 | messages = [ 148 | {"role": "system", "content": ( 149 | "你是一个运筹优化专家。请根据用户提供的运筹优化问题构建数学模型,并写出完整、可靠的 Python 代码,使用 Gurobi 求解该运筹优化问题。" 150 | "代码中请包含必要的模型构建、变量定义、约束添加、目标函数设定以及求解和结果输出。" 151 | "以 ```python\n{code}\n``` 形式输出,无需输出代码解释。" 152 | )}, 153 | {"role": "user", "content": user_question} 154 | ] 155 | 156 | gurobi_code = await async_query_llm(messages, model_name) 157 | print("【Python Gurobi 代码】:\n", gurobi_code) 158 | text = f"{gurobi_code}" 159 | is_solve_success, result = await async_extract_and_execute_python_code(text) 160 | 161 | print(f'Stage result: {is_solve_success}, {result}') 162 | 163 | return is_solve_success, result 164 | 165 | async def async_generate_or_code_solver(messages_bak, model_name, max_attempts): 166 | messages = copy.deepcopy(messages_bak) 167 | 168 | gurobi_code = await async_query_llm(messages, model_name) 169 | print("【Python Gurobi 代码】:\n", gurobi_code) 170 | 171 | text = f"{gurobi_code}" 172 | attempt = 0 173 | while attempt < max_attempts: 174 | success, error_msg = await async_extract_and_execute_python_code(text) 175 | if success: 176 | messages_bak.append({"role": "assistant", "content": gurobi_code}) 177 | return True, error_msg, messages_bak 178 | 179 | print(f"\n第 {attempt + 1} 次尝试失败,请求 LLM 修复代码...\n") 180 | 181 | messages.append({"role": "assistant", "content": gurobi_code}) 182 | messages.append({"role": "user", "content": f"代码执行出现错误,错误信息如下:\n{error_msg}\n请修复代码并重新提供完整的可执行代码。"}) 183 | 184 | gurobi_code = await async_query_llm(messages, model_name) 185 | text = f"{gurobi_code}" 186 | 187 | print("\n获取到修复后的代码,准备重新执行...\n") 188 | attempt += 1 189 | 190 | messages_bak.append({"role": "assistant", "content": gurobi_code}) 191 | print(f"达到最大尝试次数 ({max_attempts}),未能成功执行代码。") 192 | return False, None, messages_bak 193 | 194 | async def async_or_llm_agent(user_question, model_name="o3-mini", max_attempts=3): 195 | """ 196 | Async version of or_llm_agent function. 197 | """ 198 | # Initialize conversation history 199 | messages = [ 200 | {"role": "system", "content": ( 201 | "你是一个运筹优化专家。请根据用户提供的运筹优化问题构建数学模型,以数学(线性规划)模型对原问题进行有效建模。" 202 | "尽量关注获得一个正确的数学模型表达式,无需太关注解释。" 203 | "该模型后续用作指导生成gurobi代码,这一步主要用作生成有效的线性规模表达式。" 204 | )}, 205 | {"role": "user", "content": user_question} 206 | ] 207 | 208 | # 1. Generate mathematical model 209 | math_model = await async_query_llm(messages, model_name) 210 | print("【数学模型】:\n", math_model) 211 | 212 | validate_math_model = math_model 213 | messages.append({"role": "assistant", "content": validate_math_model}) 214 | 215 | messages.append({"role": "user", "content": ( 216 | "请基于以上的数学模型,写出完整、可靠的 Python 代码,使用 Gurobi 求解该运筹优化问题。" 217 | "代码中请包含必要的模型构建、变量定义、约束添加、目标函数设定以及求解和结果输出。" 218 | "以 ```python\n{code}\n``` 形式输出,无需输出代码解释。" 219 | )}) 220 | 221 | # copy msg; solve; add the last gurobi code 222 | is_solve_success, result, messages = await async_generate_or_code_solver(messages, model_name, max_attempts) 223 | print(f'Stage result: {is_solve_success}, {result}') 224 | 225 | if is_solve_success: 226 | if not is_number_string(result): 227 | print('!![No available solution warning]!!') 228 | messages.append({"role": "user", "content": ( 229 | "现有模型运行结果为*无可行解*,请认真仔细地检查数学模型和gurobi代码,是否存在错误,以致于造成无可行解" 230 | "检查完成后,最终请重新输出gurobi python代码" 231 | "以 ```python\n{code}\n``` 形式输出,无需输出代码解释。" 232 | )}) 233 | is_solve_success, result, messages = await async_generate_or_code_solver(messages, model_name, max_attempts=1) 234 | else: 235 | print('!![Max attempt debug error warning]!!') 236 | messages.append({"role": "user", "content": ( 237 | "现在模型代码多次调试仍然报错,请认真仔细地检查数学模型是否存在错误" 238 | "检查后最终请重新构建gurobi python代码" 239 | "以 ```python\n{code}\n``` 形式输出,无需输出代码解释。" 240 | )}) 241 | is_solve_success, result, messages = await async_generate_or_code_solver(messages, model_name, max_attempts=2) 242 | 243 | return is_solve_success, result 244 | 245 | async def process_single_case(i, d, args): 246 | """ 247 | Process a single test case 248 | """ 249 | print(f"=============== num {i} ==================") 250 | user_question, answer = d['question'], d['answer'] 251 | print(user_question) 252 | print('-------------') 253 | 254 | if args.agent: 255 | is_solve_success, llm_result = await async_or_llm_agent(user_question, args.model) 256 | else: 257 | is_solve_success, llm_result = await async_gpt_code_agent_simple(user_question, args.model) 258 | 259 | if is_solve_success: 260 | print(f"成功执行代码,最优解值: {llm_result}") 261 | else: 262 | print("执行代码失败。") 263 | print('------------------') 264 | 265 | pass_flag, correct_flag = eval_model_result(is_solve_success, llm_result, answer) 266 | 267 | print(f'solve: {is_solve_success}, llm: {llm_result}, ground truth: {answer}') 268 | print(f'[Final] run pass: {pass_flag}, solve correct: {correct_flag}') 269 | print(' ') 270 | 271 | return llm_result, pass_flag, correct_flag, i 272 | 273 | def parse_args(): 274 | """ 275 | Parse command line arguments. 276 | 277 | Returns: 278 | argparse.Namespace: The parsed arguments 279 | """ 280 | parser = argparse.ArgumentParser(description='Run optimization problem solving with LLMs (async version)') 281 | parser.add_argument('--agent', action='store_true', 282 | help='Use the agent. If not specified, directly use the model to solve the problem') 283 | parser.add_argument('--model', type=str, default='o3-mini', 284 | help='Model name to use for LLM queries. Use "claude-..." for Claude models.') 285 | parser.add_argument('--data_path', type=str, default='data/datasets/dataset_combined_result.json', 286 | help='Path to the dataset JSON file') 287 | return parser.parse_args() 288 | 289 | async def main(): 290 | # Load dataset from JSON file 291 | args = parse_args() 292 | 293 | with open(args.data_path, 'r') as f: 294 | dataset = json.load(f) 295 | 296 | # Create tasks for all test cases 297 | tasks = [] 298 | for i, d in dataset.items(): 299 | task = process_single_case(i, d, args) 300 | tasks.append(task) 301 | 302 | # Run all tasks concurrently and gather results 303 | results = await asyncio.gather(*tasks) 304 | 305 | # Process results 306 | pass_count = sum(1 for _, pass_flag, _, _ in results if pass_flag) 307 | correct_count = sum(1 for _, _, correct_flag, _ in results if correct_flag) 308 | error_datas = [i for _, pass_flag, correct_flag, i in results if not pass_flag or not correct_flag] 309 | 310 | print(f'[Total {len(dataset)}] run pass: {pass_count}, solve correct: {correct_count}') 311 | print(f'[Total fails {len(error_datas)}] error datas: {error_datas}') 312 | 313 | if __name__ == "__main__": 314 | # Running as script 315 | asyncio.run(main()) -------------------------------------------------------------------------------- /or_llm_show.py: -------------------------------------------------------------------------------- 1 | import openai 2 | from dotenv import load_dotenv 3 | import os 4 | import re 5 | import subprocess 6 | import sys 7 | import tempfile 8 | import copy 9 | import json 10 | import shutil 11 | import wcwidth 12 | import json 13 | from rich.console import Console 14 | from rich.markdown import Markdown 15 | import io 16 | from contextlib import redirect_stdout 17 | import time 18 | from utils import ( 19 | is_number_string, 20 | convert_to_number, 21 | extract_best_objective, 22 | extract_and_execute_python_code, 23 | eval_model_result 24 | ) 25 | # Load environment variables from .env file 26 | load_dotenv() 27 | 28 | # api_data = dict( 29 | # api_key = 'sk-sbxihlsgrzsjfknusvrxiokzdwxofzbhjdyfznqgqifguclu', #os.getenv("OPENAI_API_KEY") 30 | # base_url = 'https://api.siliconflow.cn/v1' #os.getenv("OPENAI_API_BASE") 31 | # ) 32 | 33 | # api_data = dict( 34 | # api_key = os.getenv("OPENAI_API_KEY"), 35 | # base_url = os.getenv("OPENAI_API_BASE") 36 | # ) 37 | 38 | api_data = dict( 39 | api_key = os.getenv("OPENAI_API_KEY") 40 | ) 41 | 42 | # Initialize OpenAI client 43 | client = openai.OpenAI( 44 | api_key=api_data['api_key'], 45 | ) 46 | 47 | def get_display_width(text): 48 | """ 49 | Calculate the display width of a string, accounting for wide characters like Chinese. 50 | Uses the wcwidth module for accurate width calculation. 51 | 52 | Args: 53 | text (str): The text to calculate the width for. 54 | 55 | Returns: 56 | int: The display width of the text. 57 | """ 58 | return wcwidth.wcswidth(text) 59 | 60 | 61 | def print_header(text="", add_newline_before=True, add_newline_after=True, 62 | border_char="=", side_char="||"): 63 | """ 64 | Print a header with customizable text in the middle, adjusted to the console window width. 65 | Properly handles wide characters like Chinese. 66 | 67 | Args: 68 | text (str): The text to display in the middle of the header. 69 | add_newline_before (bool): Whether to add a newline before the header. 70 | add_newline_after (bool): Whether to add a newline after the header. 71 | border_char (str): Character to use for the top and bottom borders. 72 | side_char (str): Character to use for the side borders. 73 | """ 74 | # Add a newline before the header if requested 75 | if add_newline_before: 76 | print() 77 | 78 | # Get terminal width 79 | # try: 80 | terminal_width = shutil.get_terminal_size().columns 81 | # except Exception: 82 | # # Fallback width if terminal size cannot be determined 83 | # terminal_width = 80 84 | 85 | # Ensure minimum width 86 | terminal_width = max(terminal_width, 40) 87 | 88 | # Calculate side character padding 89 | side_char_len = len(side_char) 90 | 91 | # Print the top border 92 | print(border_char * terminal_width) 93 | 94 | # Print the empty line 95 | print(side_char + " " * (terminal_width - 2 * side_char_len) + side_char) 96 | 97 | # Print the middle line with text 98 | text_display_width = get_display_width(text) 99 | available_space = terminal_width - 2 * side_char_len 100 | 101 | if text_display_width <= available_space: 102 | left_padding = (available_space - text_display_width) // 2 103 | right_padding = available_space - text_display_width - left_padding 104 | # print(terminal_width, text_display_width, available_space, left_padding, right_padding) 105 | print(side_char + " " * left_padding + text + " " * right_padding + side_char) 106 | else: 107 | # If text is too long, we need to truncate it 108 | # This is more complex with wide characters, so we'll do it character by character 109 | truncated_text = "" 110 | truncated_width = 0 111 | for char in text: 112 | char_width = get_display_width(char) 113 | if truncated_width + char_width + 3 > available_space: # +3 for the "..." 114 | break 115 | truncated_text += char 116 | truncated_width += char_width 117 | 118 | truncated_text += "..." 119 | right_padding = available_space - get_display_width(truncated_text) 120 | print(side_char + truncated_text + " " * right_padding + side_char) 121 | 122 | # Print the empty line 123 | print(side_char + " " * (terminal_width - 2 * side_char_len) + side_char) 124 | 125 | # Print the bottom border 126 | print(border_char * terminal_width) 127 | 128 | # Add a newline after the header if requested 129 | if add_newline_after: 130 | print() 131 | 132 | def query_llm(messages, model_name="o3-mini", temperature=0.2): 133 | """ 134 | 调用 LLM 获取响应结果,使用流式输出方式。 135 | 136 | Args: 137 | messages (list): 对话上下文列表。 138 | model_name (str): LLM模型名称,默认为"gpt-4"。 139 | temperature (float): 控制输出的随机性,默认为 0.2。 140 | 141 | Returns: 142 | str: LLM 生成的响应内容。 143 | """ 144 | # 使用stream=True启用流式输出 145 | response = client.chat.completions.create( 146 | model=model_name, 147 | messages=messages, 148 | temperature=temperature, 149 | stream=True 150 | ) 151 | 152 | # 用于累积完整响应 153 | full_response = "" 154 | 155 | # 用于控制打印格式 156 | print("LLM Output: ", end="", flush=True) 157 | 158 | # 逐块处理流式响应 159 | for chunk in response: 160 | # 首先检查choices列表是否非空 161 | if hasattr(chunk, 'choices') and len(chunk.choices) > 0: 162 | # 然后检查是否有delta和content 163 | if hasattr(chunk.choices[0], 'delta') and hasattr(chunk.choices[0].delta, 'content'): 164 | content = chunk.choices[0].delta.content 165 | if content: 166 | print(content, end="", flush=True) 167 | full_response += content 168 | 169 | # 输出完成后换行 170 | print() 171 | 172 | return full_response 173 | 174 | def generate_or_code_solver(messages_bak, model_name, max_attempts): 175 | messages = copy.deepcopy(messages_bak) 176 | 177 | print_header("LLM生成Python Gurobi 代码") 178 | 179 | gurobi_code = query_llm(messages, model_name) 180 | 181 | print_header("自动执行python代码") 182 | # 4. 代码执行 & 修复 183 | text = f"{gurobi_code}" 184 | attempt = 0 185 | while attempt < max_attempts: 186 | buffer2 = io.StringIO() 187 | with redirect_stdout(buffer2): 188 | success, error_msg = extract_and_execute_python_code(text) 189 | captured_output2 = buffer2.getvalue() 190 | for c in captured_output2: 191 | print(c, end="", flush=True) 192 | time.sleep(0.005) 193 | 194 | if success: 195 | messages_bak.append({"role": "assistant", "content": gurobi_code}) 196 | return True, error_msg, messages_bak 197 | 198 | print(f"\n第 {attempt + 1} 次尝试失败,请求 LLM 修复代码...\n") 199 | 200 | # 构建修复请求 201 | messages.append({"role": "assistant", "content": gurobi_code}) 202 | messages.append({"role": "user", "content": f"代码执行出现错误,错误信息如下:\n{error_msg}\n请修复代码并重新提供完整的可执行代码。"}) 203 | 204 | # 获取修复后的代码 205 | gurobi_code = query_llm(messages, model_name) 206 | text = f"{gurobi_code}" 207 | 208 | print("\n获取到修复后的代码,准备重新执行...\n") 209 | attempt += 1 210 | # not add gurobi code 211 | messages_bak.append({"role": "assistant", "content": gurobi_code}) 212 | print(f"达到最大尝试次数 ({max_attempts}),未能成功执行代码。") 213 | return False, None, messages_bak 214 | 215 | 216 | def or_llm_agent(user_question, model_name="o3-mini", max_attempts=3): 217 | """ 218 | 向 LLM 请求 Gurobi 代码解决方案并执行,如果失败则尝试修复。 219 | 220 | Args: 221 | user_question (str): 用户的问题描述。 222 | model_name (str): 使用的 LLM 模型名称,默认为"gpt-4"。 223 | max_attempts (int): 最大尝试次数,默认为3。 224 | 225 | Returns: 226 | tuple: (success: bool, best_objective: float or None, final_code: str) 227 | """ 228 | # 初始化对话记录 229 | messages = [ 230 | {"role": "system", "content": ( 231 | "你是一个运筹优化专家。请根据用户提供的运筹优化问题构建数学模型,以数学(线性规划)模型对原问题进行有效建模。" 232 | "尽量关注获得一个正确的数学模型表达式,无需太关注解释。" 233 | "该模型后续用作指导生成gurobi代码,这一步主要用作生成有效的线性规模表达式。" 234 | )}, 235 | {"role": "user", "content": user_question} 236 | ] 237 | 238 | # 1. 生成数学模型 239 | print_header("LLM推理构建线性规划模型") 240 | math_model = query_llm(messages, model_name) 241 | # print("【数学模型】:\n", math_model) 242 | 243 | # # 2. 校验数学模型 244 | # messages.append({"role": "assistant", "content": math_model}) 245 | # messages.append({"role": "user", "content": ( 246 | # "请基于上面的数学模型是否符合问题描述,如果存在错误,则进行修正;如果不存在错误则检查是否能进行优化。" 247 | # "无论何种情况,最终请重新输出该数学模型。" 248 | # )}) 249 | 250 | # validate_math_model = query_llm(messages, model_name) 251 | # print("【校验后的数学模型】:\n", validate_math_model) 252 | 253 | validate_math_model = math_model 254 | messages.append({"role": "assistant", "content": validate_math_model}) 255 | 256 | # ------------------------------ 257 | messages.append({"role": "user", "content": ( 258 | "请基于以上的数学模型,写出完整、可靠的 Python 代码,使用 Gurobi 求解该运筹优化问题。" 259 | "代码中请包含必要的模型构建、变量定义、约束添加、目标函数设定以及求解和结果输出。" 260 | "以 ```python\n{code}\n``` 形式输出,无需输出代码解释。" 261 | )}) 262 | # copy msg; solve; add the laset gurobi code 263 | is_solve_success, result, messages = generate_or_code_solver(messages, model_name,max_attempts) 264 | print(f'Stage result: {is_solve_success}, {result}') 265 | if is_solve_success: 266 | if not is_number_string(result): 267 | print('!![No available solution warning]!!') 268 | # no solution 269 | messages.append({"role": "user", "content": ( 270 | "现有模型运行结果为*无可行解*,请认真仔细地检查数学模型和gurobi代码,是否存在错误,以致于造成无可行解" 271 | "检查完成后,最终请重新输出gurobi python代码" 272 | "以 ```python\n{code}\n``` 形式输出,无需输出代码解释。" 273 | )}) 274 | is_solve_success, result, messages = generate_or_code_solver(messages, model_name, max_attempts=1) 275 | else: 276 | print('!![Max attempt debug error warning]!!') 277 | messages.append({"role": "user", "content": ( 278 | "现在模型代码多次调试仍然报错,请认真仔细地检查数学模型是否存在错误" 279 | "检查后最终请重新构建gurobi python代码" 280 | "以 ```python\n{code}\n``` 形式输出,无需输出代码解释。" 281 | )}) 282 | is_solve_success, result, messages = generate_or_code_solver(messages, model_name, max_attempts=2) 283 | 284 | return is_solve_success, result 285 | 286 | 287 | 288 | if __name__ == "__main__": 289 | with open('data/datasets/dataset_md_result.json', 'r') as f: 290 | dataset = json.load(f) 291 | # print(dataset['0']) 292 | console = Console() 293 | 294 | model_name = 'o3-mini' 295 | # model_name = '' 296 | 297 | # model_name = 'Pro/deepseek-ai/DeepSeek-R1' 298 | # model_name = 'deepseek-reasoner' 299 | 300 | pass_count = 0 301 | correct_count = 0 302 | for i, d in dataset.items(): 303 | #print(i) 304 | # if int(i) in [0]: 305 | print_header("运筹优化问题") 306 | user_question, answer = d['question'], d['answer'] 307 | # print(user_question) 308 | buffer2 = io.StringIO() 309 | with redirect_stdout(buffer2): 310 | md = Markdown(user_question) 311 | console.print(md) 312 | print('-------------') 313 | 314 | captured_output2 = buffer2.getvalue() 315 | for c in captured_output2: 316 | print(c, end="", flush=True) 317 | time.sleep(0.005) 318 | is_solve_success, llm_result = or_llm_agent(user_question, model_name) 319 | # is_solve_success, llm_result = gpt_code_agent_simple(user_question, model_name) 320 | if is_solve_success: 321 | print(f"成功执行代码,最优解值: {llm_result}") 322 | else: 323 | print("执行代码失败。") -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "or-llm-agent" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.10" 7 | dependencies = [ 8 | "anthropic==0.49.0", 9 | "gurobipy==12.0.1", 10 | "matplotlib==3.10.1", 11 | "mcp[cli]>=1.6.0", 12 | "numpy==2.2.3", 13 | "openai==1.66.3", 14 | "python-dotenv==1.0.1", 15 | "scipy==1.15.2", 16 | ] 17 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | anthropic==0.49.0 2 | matplotlib==3.10.1 3 | numpy==2.2.3 4 | openai==1.66.3 5 | python-dotenv==1.0.1 6 | scipy==1.15.2 7 | gurobipy==12.0.1 -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | import re 2 | import subprocess 3 | import sys 4 | import tempfile 5 | import os 6 | 7 | def is_number_string(s): 8 | """ 9 | Determine if a string is a numeric string, including integers and decimals. 10 | 11 | Args: 12 | s: The string to be checked. 13 | 14 | Returns: 15 | True if the string is a numeric string, otherwise False. 16 | """ 17 | pattern = r"^[-+]?\d+(\.\d+)?$" # Regular expression to match integers or decimals 18 | return re.match(pattern, s) is not None 19 | 20 | def convert_to_number(s): 21 | """ 22 | Convert a string to a number (integer or float). 23 | 24 | Args: 25 | s: The string to be converted. 26 | 27 | Returns: 28 | int or float: Returns int if the string represents an integer, float if it represents a decimal. 29 | Returns None if conversion fails. 30 | """ 31 | try: 32 | # Try to convert to integer 33 | if s.isdigit() or (s.startswith('-') and s[1:].isdigit()): 34 | return int(s) 35 | # Try to convert to float 36 | num = float(s) 37 | return num 38 | except (ValueError, TypeError): 39 | return None 40 | 41 | def extract_best_objective(output_text): 42 | """ 43 | Extract Best objective or Optimal objective value from Gurobi output. 44 | 45 | Args: 46 | output_text: Gurobi output text 47 | 48 | Returns: 49 | float or None: Optimal solution value, returns None if not found 50 | """ 51 | # First check if model is infeasible 52 | if "Model is infeasible" in output_text: 53 | return None 54 | 55 | # Try to find Best objective 56 | match = re.search(r'Best objective\s+([\d.e+-]+)', output_text) 57 | if not match: 58 | # If not found, try to find Optimal objective 59 | match = re.search(r'Optimal objective\s+([\d.e+-]+)', output_text) 60 | 61 | if match: 62 | try: 63 | return float(match.group(1)) 64 | except ValueError: 65 | return None 66 | 67 | return None 68 | 69 | def extract_and_execute_python_code(text_content): 70 | """ 71 | Extract Python code blocks from text and execute them. 72 | 73 | Args: 74 | text_content: Text content containing code blocks. 75 | 76 | Returns: 77 | bool: True if execution was successful, False otherwise 78 | str: Error message if execution failed, best objective if successful 79 | """ 80 | python_code_blocks = re.findall(r'```python\s*([\s\S]*?)```', text_content) 81 | 82 | if not python_code_blocks: 83 | print("No Python code blocks found.") 84 | return False, "No Python code blocks found" 85 | 86 | for code_block in python_code_blocks: 87 | code_block = code_block.strip() 88 | if not code_block: 89 | print("Found an empty Python code block, skipped.") 90 | continue 91 | 92 | print("Found Python code block, starting execution...") 93 | try: 94 | with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as tmp_file: 95 | tmp_file.write(code_block) 96 | temp_file_path = tmp_file.name 97 | 98 | result = subprocess.run([sys.executable, temp_file_path], capture_output=True, text=True, check=False) 99 | 100 | if result.returncode == 0: 101 | print("Python code executed successfully, output:\n") 102 | print(result.stdout) 103 | 104 | best_obj = extract_best_objective(result.stdout) 105 | if best_obj is not None: 106 | print(f"\nOptimal solution value (Best objective): {best_obj}") 107 | else: 108 | print("\nOptimal solution value not found") 109 | return True, str(best_obj) 110 | else: 111 | print(f"Python code execution error, error message:\n") 112 | print(result.stderr) 113 | return False, result.stderr 114 | 115 | except Exception as e: 116 | print(f"Error occurred while executing Python code block: {e}") 117 | return False, str(e) 118 | finally: 119 | if 'temp_file_path' in locals() and os.path.exists(temp_file_path): 120 | os.remove(temp_file_path) 121 | print("-" * 30) 122 | 123 | return False, "No valid code blocks executed" 124 | 125 | def eval_model_result(success, result, ground_truth, err_range=0.1): 126 | pass_flag = False 127 | correct_flag = False 128 | if success: 129 | pass_flag = True 130 | if is_number_string(str(result)) and ground_truth is not None: 131 | result_num = convert_to_number(str(result)) 132 | ground_truth_num = convert_to_number(str(ground_truth)) 133 | if abs(result_num - ground_truth_num) < err_range: 134 | correct_flag = True 135 | elif result == 'None': # no available solution 136 | if ground_truth is None or ground_truth == 'None': 137 | correct_flag = True 138 | return pass_flag, correct_flag --------------------------------------------------------------------------------