llm4ad 1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. llm4ad-1.0/LICENSE +21 -0
  2. llm4ad-1.0/PKG-INFO +18 -0
  3. llm4ad-1.0/README.md +306 -0
  4. llm4ad-1.0/llm4ad/__init__.py +6 -0
  5. llm4ad-1.0/llm4ad/base/__init__.py +9 -0
  6. llm4ad-1.0/llm4ad/base/code.py +270 -0
  7. llm4ad-1.0/llm4ad/base/evaluate.py +285 -0
  8. llm4ad-1.0/llm4ad/base/modify_code.py +402 -0
  9. llm4ad-1.0/llm4ad/base/sample.py +234 -0
  10. llm4ad-1.0/llm4ad/gui.py +141 -0
  11. llm4ad-1.0/llm4ad/method/__init__.py +57 -0
  12. llm4ad-1.0/llm4ad/method/eoh/__init__.py +2 -0
  13. llm4ad-1.0/llm4ad/method/eoh/eoh.py +305 -0
  14. llm4ad-1.0/llm4ad/method/eoh/population.py +83 -0
  15. llm4ad-1.0/llm4ad/method/eoh/profiler.py +161 -0
  16. llm4ad-1.0/llm4ad/method/eoh/prompt.py +120 -0
  17. llm4ad-1.0/llm4ad/method/eoh/resume.py +104 -0
  18. llm4ad-1.0/llm4ad/method/eoh/sampler.py +29 -0
  19. llm4ad-1.0/llm4ad/method/funsearch/__init__.py +3 -0
  20. llm4ad-1.0/llm4ad/method/funsearch/config.py +23 -0
  21. llm4ad-1.0/llm4ad/method/funsearch/funsearch.py +195 -0
  22. llm4ad-1.0/llm4ad/method/funsearch/profiler.py +135 -0
  23. llm4ad-1.0/llm4ad/method/funsearch/programs_database.py +305 -0
  24. llm4ad-1.0/llm4ad/method/funsearch/resume.py +111 -0
  25. llm4ad-1.0/llm4ad/method/hillclimb/__init__.py +2 -0
  26. llm4ad-1.0/llm4ad/method/hillclimb/hillclimb.py +189 -0
  27. llm4ad-1.0/llm4ad/method/hillclimb/profiler.py +8 -0
  28. llm4ad-1.0/llm4ad/method/hillclimb/resume.py +83 -0
  29. llm4ad-1.0/llm4ad/method/randsample/__init__.py +2 -0
  30. llm4ad-1.0/llm4ad/method/randsample/profiler.py +8 -0
  31. llm4ad-1.0/llm4ad/method/randsample/randsample.py +181 -0
  32. llm4ad-1.0/llm4ad/method/randsample/resume.py +73 -0
  33. llm4ad-1.0/llm4ad/task/__init__.py +29 -0
  34. llm4ad-1.0/llm4ad/task/machine_learning/__init__.py +0 -0
  35. llm4ad-1.0/llm4ad/task/machine_learning/acrobot/__init__.py +2 -0
  36. llm4ad-1.0/llm4ad/task/machine_learning/acrobot/evaluation.py +65 -0
  37. llm4ad-1.0/llm4ad/task/machine_learning/acrobot/template.py +35 -0
  38. llm4ad-1.0/llm4ad/task/machine_learning/acrobot/test.py +46 -0
  39. llm4ad-1.0/llm4ad/task/machine_learning/car_mountain/__init__.py +2 -0
  40. llm4ad-1.0/llm4ad/task/machine_learning/car_mountain/evaluation.py +57 -0
  41. llm4ad-1.0/llm4ad/task/machine_learning/car_mountain/q-learning.py +123 -0
  42. llm4ad-1.0/llm4ad/task/machine_learning/car_mountain/template.py +22 -0
  43. llm4ad-1.0/llm4ad/task/machine_learning/car_mountain/test.py +163 -0
  44. llm4ad-1.0/llm4ad/task/machine_learning/moon_lander/__init__.py +2 -0
  45. llm4ad-1.0/llm4ad/task/machine_learning/moon_lander/evaluation.py +84 -0
  46. llm4ad-1.0/llm4ad/task/machine_learning/moon_lander/template.py +32 -0
  47. llm4ad-1.0/llm4ad/task/machine_learning/moon_lander/test.py +51 -0
  48. llm4ad-1.0/llm4ad/task/optimization/__init__.py +30 -0
  49. llm4ad-1.0/llm4ad/task/optimization/admissible_set/__init__.py +2 -0
  50. llm4ad-1.0/llm4ad/task/optimization/admissible_set/evaluation.py +155 -0
  51. llm4ad-1.0/llm4ad/task/optimization/admissible_set/template.py +22 -0
  52. llm4ad-1.0/llm4ad/task/optimization/cvrp_construct/__init__.py +2 -0
  53. llm4ad-1.0/llm4ad/task/optimization/cvrp_construct/evaluation.py +152 -0
  54. llm4ad-1.0/llm4ad/task/optimization/cvrp_construct/get_instance.py +50 -0
  55. llm4ad-1.0/llm4ad/task/optimization/cvrp_construct/template.py +22 -0
  56. llm4ad-1.0/llm4ad/task/optimization/online_bin_packing/__init__.py +2 -0
  57. llm4ad-1.0/llm4ad/task/optimization/online_bin_packing/evaluation.py +91 -0
  58. llm4ad-1.0/llm4ad/task/optimization/online_bin_packing/generate_weibull_instances.py +36 -0
  59. llm4ad-1.0/llm4ad/task/optimization/online_bin_packing/template.py +15 -0
  60. llm4ad-1.0/llm4ad/task/optimization/ovrp_construct/__init__.py +2 -0
  61. llm4ad-1.0/llm4ad/task/optimization/ovrp_construct/evaluation.py +124 -0
  62. llm4ad-1.0/llm4ad/task/optimization/ovrp_construct/get_instance.py +50 -0
  63. llm4ad-1.0/llm4ad/task/optimization/ovrp_construct/template.py +22 -0
  64. llm4ad-1.0/llm4ad/task/optimization/tsp_construct/__init__.py +2 -0
  65. llm4ad-1.0/llm4ad/task/optimization/tsp_construct/evaluation.py +148 -0
  66. llm4ad-1.0/llm4ad/task/optimization/tsp_construct/get_instance.py +15 -0
  67. llm4ad-1.0/llm4ad/task/optimization/tsp_construct/template.py +24 -0
  68. llm4ad-1.0/llm4ad/task/optimization/vrptw_construct/__init__.py +2 -0
  69. llm4ad-1.0/llm4ad/task/optimization/vrptw_construct/evaluation.py +174 -0
  70. llm4ad-1.0/llm4ad/task/optimization/vrptw_construct/get_instance.py +65 -0
  71. llm4ad-1.0/llm4ad/task/optimization/vrptw_construct/template.py +23 -0
  72. llm4ad-1.0/llm4ad/task/science_discovery/__init__.py +0 -0
  73. llm4ad-1.0/llm4ad/task/science_discovery/bactgrow/__init__.py +2 -0
  74. llm4ad-1.0/llm4ad/task/science_discovery/bactgrow/evaluation.py +87 -0
  75. llm4ad-1.0/llm4ad/task/science_discovery/bactgrow/template.py +20 -0
  76. llm4ad-1.0/llm4ad/task/science_discovery/bactgrow/test_id.py +17502 -0
  77. llm4ad-1.0/llm4ad/task/science_discovery/bactgrow/test_odd.py +105002 -0
  78. llm4ad-1.0/llm4ad/task/science_discovery/bactgrow/train.py +52502 -0
  79. llm4ad-1.0/llm4ad/task/science_discovery/ode_1d/__init__.py +2 -0
  80. llm4ad-1.0/llm4ad/task/science_discovery/ode_1d/evaluation.py +152 -0
  81. llm4ad-1.0/llm4ad/task/science_discovery/ode_1d/strogatz_equations.py +224 -0
  82. llm4ad-1.0/llm4ad/task/science_discovery/ode_1d/strogatz_extended.py +34001 -0
  83. llm4ad-1.0/llm4ad/task/science_discovery/ode_1d/template.py +22 -0
  84. llm4ad-1.0/llm4ad/task/science_discovery/oscillator1/__init__.py +2 -0
  85. llm4ad-1.0/llm4ad/task/science_discovery/oscillator1/evaluation.py +85 -0
  86. llm4ad-1.0/llm4ad/task/science_discovery/oscillator1/template.py +19 -0
  87. llm4ad-1.0/llm4ad/task/science_discovery/oscillator1/test_id.py +50002 -0
  88. llm4ad-1.0/llm4ad/task/science_discovery/oscillator1/test_odd.py +50002 -0
  89. llm4ad-1.0/llm4ad/task/science_discovery/oscillator1/train.py +50002 -0
  90. llm4ad-1.0/llm4ad/task/science_discovery/oscillator2/__init__.py +2 -0
  91. llm4ad-1.0/llm4ad/task/science_discovery/oscillator2/evaluation.py +87 -0
  92. llm4ad-1.0/llm4ad/task/science_discovery/oscillator2/template.py +20 -0
  93. llm4ad-1.0/llm4ad/task/science_discovery/oscillator2/test_id.py +60002 -0
  94. llm4ad-1.0/llm4ad/task/science_discovery/oscillator2/test_odd.py +60002 -0
  95. llm4ad-1.0/llm4ad/task/science_discovery/oscillator2/train.py +60002 -0
  96. llm4ad-1.0/llm4ad/task/science_discovery/stresstrain/__init__.py +2 -0
  97. llm4ad-1.0/llm4ad/task/science_discovery/stresstrain/evaluation.py +85 -0
  98. llm4ad-1.0/llm4ad/task/science_discovery/stresstrain/template.py +19 -0
  99. llm4ad-1.0/llm4ad/task/science_discovery/stresstrain/test_id.py +7212 -0
  100. llm4ad-1.0/llm4ad/task/science_discovery/stresstrain/test_odd.py +3692 -0
  101. llm4ad-1.0/llm4ad/task/science_discovery/stresstrain/train.py +10807 -0
  102. llm4ad-1.0/llm4ad/tools/__init__.py +3 -0
  103. llm4ad-1.0/llm4ad/tools/llm/__init__.py +32 -0
  104. llm4ad-1.0/llm4ad/tools/llm/llm_api_https.py +73 -0
  105. llm4ad-1.0/llm4ad/tools/llm/llm_api_openai.py +21 -0
  106. llm4ad-1.0/llm4ad/tools/log_utils.py +730 -0
  107. llm4ad-1.0/llm4ad/tools/profiler/__init__.py +40 -0
  108. llm4ad-1.0/llm4ad/tools/profiler/profile.py +208 -0
  109. llm4ad-1.0/llm4ad/tools/profiler/tensorboard_profiler.py +85 -0
  110. llm4ad-1.0/llm4ad/tools/profiler/wandb_profiler.py +100 -0
  111. llm4ad-1.0/llm4ad.egg-info/PKG-INFO +18 -0
  112. llm4ad-1.0/llm4ad.egg-info/SOURCES.txt +115 -0
  113. llm4ad-1.0/llm4ad.egg-info/dependency_links.txt +1 -0
  114. llm4ad-1.0/llm4ad.egg-info/requires.txt +11 -0
  115. llm4ad-1.0/llm4ad.egg-info/top_level.txt +1 -0
  116. llm4ad-1.0/setup.cfg +4 -0
  117. llm4ad-1.0/setup.py +24 -0
llm4ad-1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
llm4ad-1.0/PKG-INFO ADDED
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.1
2
+ Name: llm4ad
3
+ Version: 1.0
4
+ Summary: Large Language Model for Algorithm Design Platform
5
+ Author: Optima
6
+ Requires-Python: >=3.9,<=3.11
7
+ License-File: LICENSE
8
+ Requires-Dist: numpy<2
9
+ Requires-Dist: tensorboard
10
+ Requires-Dist: scipy
11
+ Requires-Dist: tqdm
12
+ Requires-Dist: requests
13
+ Requires-Dist: openai
14
+ Requires-Dist: pytz
15
+ Requires-Dist: matplotlib
16
+ Requires-Dist: python-docx
17
+ Requires-Dist: gym
18
+ Requires-Dist: ttkbootstrap
llm4ad-1.0/README.md ADDED
@@ -0,0 +1,306 @@
1
+
2
+
3
+ <div align="center">
4
+ <h1 align="center">
5
+ <img src="./assets/figs/logo.png" alt="LLM4AD Logo" style="width: 90%; height: auto;">
6
+ </h1>
7
+ <h1 align="center">
8
+ LLM4AD: Large Language Model for Algorithm Design
9
+ </h1>
10
+
11
+ [![Releases](https://img.shields.io/badge/Release-v1.0-blue)](https://github.com/Optima-CityU/LLM4AD/releases)
12
+ ![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-brightgreen.svg)
13
+ [![PR's Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Optima-CityU/LLM4AD/pulls)
14
+ ![Python](https://img.shields.io/badge/Python-3.9+-blue)
15
+ [![License](https://img.shields.io/badge/License-MIT-important)](https://github.com/Optima-CityU/LLM4AD/blob/main/LICENSE)
16
+ [![Documentation Status](https://readthedocs.org/projects/llm4ad-doc/badge/?version=latest)](https://llm4ad-doc.readthedocs.io/en/latest/?badge=latest)
17
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Optima-CityU/llm4ad/blob/main/example/online_bin_packing/online_bin_packing_tutorial.ipynb)
18
+
19
+ [Website](http://www.llm4ad.com/)
20
+ | [Documentation](https://llm4ad-doc.readthedocs.io/en/latest/)
21
+ | [Examples](https://github.com/Optima-CityU/LLM4AD/tree/main/example)
22
+ | [GUI](https://github.com/Optima-CityU/LLM4AD/tree/main/GUI)
23
+
24
+ </div>
25
+ <br>
26
+
27
+ ## Introduction 📖
28
+
29
+ LLM4AD is an open-source Python-based Platform leveraging **Large Language Models (LLMs)** for **Automatic Algorithm Design (AD)**. Please refer to the [paper](https://arxiv.org/pdf/2412.17287) [LLM4AD] for detailed information, including the overview, methodology, and benchmark results.
30
+
31
+ LLM4AD is accomplished with [Documents](https://llm4ad-doc.readthedocs.io/en/latest/) and [Examples](https://github.com/Optima-CityU/LLM4AD/tree/main/example) materials to support users and developers to easily test, build and deploy their own LLM4AD applications and conduct research.
32
+
33
+ LLM4AD was originally developed for [optimisation tasks](https://llm4ad-doc.readthedocs.io/en/latest/task/optimization/index.html). The framework is versatile enough to be used in other areas, including [machine learning](https://llm4ad-doc.readthedocs.io/en/latest/task/machine_learning/index.html), [science discovery](https://llm4ad-doc.readthedocs.io/en/latest/task/science_discovery/index.html), game theory and engineering design.
34
+
35
+ For more information, see the [contact list](https://github.com/Optima-CityU/LLM4AD#Contact)
36
+
37
+ <img src="./assets/figs/overview.png" alt="llm4ad" style="zoom:50%;" />
38
+
39
+ ## 🔥 News
40
+
41
+ + 2024.12 🎉🎉 **LLM4AD paper Released** [“LLM4AD: A Platform for Algorithm Design with Large Language Model"](https://arxiv.org/pdf/2412.17287) !
42
+
43
+ + 2024.11 🎉🎉 **LLM4AD v1.0 Released** !
44
+
45
+ + 2024.10 🎉🎉 **Survey Paper** [“A Systematic Survey on Large Language Models for Algorithm Design”](https://arxiv.org/pdf/2410.14716) is online !
46
+
47
+
48
+
49
+ ## 💡 Features of our package
50
+
51
+ | Feature | Support / To be supported |
52
+ | ------------------------------------------------------------ | ------------------------- |
53
+ | **Unified Interfaces** for methods | 🔥Support |
54
+ | **Unified Interfaces** for tasks | 🔥Support |
55
+ | **Unified Interfaces** for LLMs | 🔥Support |
56
+ | **Evaluation acceleration:** multiprocessing evaluation, add Numba wrapper for heuristic | 🔥Support |
57
+ | **Secure Evaluation:** main process protection, timeout interruption | 🔥Support |
58
+ | **Logs:** local logs, Wandb and Tensorboard support | 🔥Support |
59
+ | **GUI:** methods selection, tasks selection, convergence, best algorithm, ... | 🔥Support |
60
+ | **Resume run** | 🚀Will be updated soon |
61
+ | Support other languages | 🚀Will be updated soon |
62
+ | More search methods | 🚀Will be updated soon |
63
+ | More task examples | 🚀Will be updated soon |
64
+
65
+
66
+
67
+ ## 🎁 Requirements & Installation
68
+
69
+ > [!Important]
70
+ > The Python version **must** be larger or equal to Python 3.9.
71
+
72
+
73
+ - refer to [requirements.txt](./requirements.txt)
74
+
75
+ - Numba (if you want to use Numba accelerate)
76
+
77
+ - Tensorboard (if you want to use a Tensorboard logger)
78
+
79
+ - wandb (if you want to use wandb logger)
80
+
81
+ - gym (if you want to try **Machine Learning** tasks)
82
+
83
+ - pandas (if you want to try **Science Discovery** tasks)
84
+
85
+ - all required packages in [requirements.txt](./requirements.txt) (if you want to use GUI)
86
+
87
+ #### Install LLM4AD locally
88
+
89
+ We suggest to install and run LLM4AD in [conda](https://conda.io/projects/conda/en/latest/index.html) env with python>=3.9, <=3.11
90
+
91
+ ```bash
92
+ cd LLM4AD
93
+
94
+ pip install .
95
+ ```
96
+
97
+ #### Install LLM4AD using PiPy
98
+
99
+ We suggest to install and run LLM4AD in [conda](https://conda.io/projects/conda/en/latest/index.html) env with python>=3.9, <=3.11
100
+
101
+ ```bash
102
+ pip install llm4ad
103
+ ```
104
+
105
+
106
+
107
+ ## 💻 Example Usage
108
+
109
+ ### Quick Start:
110
+
111
+ > [!Note]
112
+ > Configure your LLM api before running the script. For example:
113
+ >
114
+ > 1) Set `host`: 'api.deepseek.com'
115
+ > 2) Set `key`: 'your api key'
116
+ > 3) Set `model` `deepseek-chat'
117
+
118
+ ```python
119
+ from llm4ad.task.optimization.online_bin_packing import OBPEvaluation
120
+ from llm4ad.tools.llm.llm_api_https import HttpsApi
121
+ from llm4ad.method.eoh import EoH, EoHProfiler
122
+
123
+
124
+ def main():
125
+
126
+ llm = HttpsApi(host="xxx", # your host endpoint, e.g., api.openai.com, api.deepseek.com
127
+ key="sk-xxx", # your key, e.g., sk-xxxxxxxxxx
128
+ model="xxx", # your llm, e.g., gpt-3.5-turbo, deepseek-chat
129
+ timeout=20)
130
+
131
+ task = OBPEvaluation()
132
+
133
+ method = EoH(llm=llm,
134
+ profiler=EoHProfiler(log_dir='logs/eoh', log_style='simple'),
135
+ evaluation=task,
136
+ max_sample_nums=20,
137
+ max_generations=10,
138
+ pop_size=4,
139
+ num_samplers=1,
140
+ num_evaluators=1,
141
+ debug_mode=False)
142
+
143
+ method.run()
144
+
145
+
146
+ if __name__ == '__main__':
147
+ main()
148
+
149
+ ```
150
+
151
+
152
+ ### More Examples:
153
+ + [Constructive Heuristics for TSP](https://github.com/Optima-CityU/LLM4AD/blob/main/example/tsp_construct/run_eoh.py)
154
+ + [Constructive Heuristics for VRPTW](https://github.com/Optima-CityU/LLM4AD/blob/main/example/vrptw_construct/run_eoh.py)
155
+ + ...
156
+
157
+
158
+ Check [Documents](https://llm4ad-doc.readthedocs.io/en/latest/index.html) for more tasks and examples
159
+
160
+ ### GUI usage:
161
+
162
+ > [!Important]
163
+ > Install all required packages in [requirements.txt](./requirements.txt) for GUI usage
164
+
165
+ ```bash
166
+ $ cd GUI
167
+ $ python run_gui.py
168
+ ```
169
+
170
+ Check [GUI Introduction](https://llm4ad-doc.readthedocs.io/en/latest/getting_started/gui.html) for more information
171
+
172
+ <img src="./assets/figs/gui.gif" alt="llm4ad" style="zoom:80%;" />
173
+
174
+ ## 📦 LLM4AD Search Methods
175
+
176
+ | Methods | Paper title |
177
+ | ----------------------------------------------------- | ------------------------------------------------------------ |
178
+ | **AEL** (Preliminary Version of **EoH**) | [Algorithm Evolution using Large Language Model](https://arxiv.org/abs/2311.15249) (Arxiv 2023) |
179
+ | **EoH** | [Evolution of Heuristics: Towards Efficient Automatic Algorithm Design Using Large Language Model](https://openreview.net/pdf?id=BwAkaxqiLB) (ICML 2024) |
180
+ | **FunSearch** | [Mathematical Discoveries from Program Search with Large Language Models](https://www.nature.com/articles/s41586-023-06924-6) (Nature 2024) |
181
+ | **RandomSampling** | [Understanding the Importance of Evolutionary Search in Automated Heuristic Design with Large Language Models](https://arxiv.org/abs/2407.10873) (PPSN 2024) |
182
+ | **(1+1)-EPS** <br/>(HillClimbing) | [Understanding the Importance of Evolutionary Search in Automated Heuristic Design with Large Language Models](https://arxiv.org/abs/2407.10873) (PPSN 2024) |
183
+ | RegEvo | coming soon |
184
+ | Neighborhood search methods | coming soon |
185
+ | Multi-objective search methods | coming soon |
186
+ | Others | coming soon |
187
+
188
+
189
+ ## 📦LLM4AD Algorithm Design Tasks
190
+
191
+
192
+ | Area | Algorithm Task | Paper |
193
+ | ----------------- | ------------------------------------------------------------ | ------------------------------------------------- |
194
+ | Optimization | [Online Bin Packing, Constructive heuristic] | [paper](https://openreview.net/pdf?id=BwAkaxqiLB) |
195
+ | | [Traveling Salesman Problem (TSP), Construct heuristic](https://llm4ad-doc.readthedocs.io/en/latest/task/optimization/tsp_construct.html) | [paper](https://arxiv.org/pdf/2311.15249) |
196
+ | | Traveling Salesman Problem (TSP), Guided local search | [paper](https://openreview.net/pdf?id=BwAkaxqiLB) |
197
+ | | Flow Shop Scheduling Problem (FSSP), Guided local search | [paper](https://openreview.net/pdf?id=BwAkaxqiLB) |
198
+ | | Bayesian Optimization, Cost-aware Acquisition Function Design | [paper](https://arxiv.org/abs/2404.16906) |
199
+ | Machine Learning | Adversarial Attack, Attack strategy | [paper](https://arxiv.org/abs/2401.15335) |
200
+ | | [Acrobot, Heuristic (Agent)](https://llm4ad-doc.readthedocs.io/en/latest/task/machine_learning/acrobot.html) | |
201
+ | | [Cart Pole, Heuristic (Agent)](https://llm4ad-doc.readthedocs.io/en/latest/task/machine_learning/car_pole.html) | |
202
+ | | [Mountain Car, Heuristic (Agent)](https://llm4ad-doc.readthedocs.io/en/latest/task/machine_learning/mountain_car.html) | |
203
+ | Science Discovery | Computational fluid dynamics, Turbulence model design | [paper](https://arxiv.org/pdf/2410.10657) |
204
+ | | [Bacteria Growth, Function](https://llm4ad-doc.readthedocs.io/en/latest/task/science_discovery/bacteria_grow.html) | |
205
+ | | [Oscillator, Equation](https://llm4ad-doc.readthedocs.io/en/latest/task/science_discovery/oscillator1.html) | |
206
+ | | [Stress & Strain, Equation](https://llm4ad-doc.readthedocs.io/en/latest/task/science_discovery/stress_strain.html) | |
207
+ | Math | Admissible Sets | [paper](https://www.nature.com/articles/s41586-023-06924-6) |
208
+ | coming soon ... | | |
209
+
210
+
211
+
212
+ ## 🤖 LLM Interfaces
213
+ There are three approaches on LLM interface implementation, check [Tutorial on LLM interface implementation](https://llm4ad-doc.readthedocs.io/en/latest/dev/llm.html) for more information.
214
+ + **Remote LLM API** (e.g., GPT4o, GPT3.5, Gemini Pro, Deepseek ...) (**<Recommended !!!>**)
215
+ + **Local HuggingFace LLM Deployment** (e.g., Llamacode, Llama, Gemma, Deepseek, ...)
216
+ + **Your Implementation** If you want to use your own GPT API or local LLMs deployment, please create and add your interface in [LLM](https://github.com/Optima-CityU/LLM4AD/tree/main/llm4ad/tools/llm)
217
+
218
+
219
+
220
+ ## 🗎 Tutorial: How to Use LLM4AD to Solve Your Algorithm Design Task
221
+
222
+ A Step-by-step Tutorial on using LLM4AD to solve your algorithm design task is provided [here](https://llm4ad-doc.readthedocs.io/en/latest/dev/run_new_task.html#)
223
+
224
+
225
+
226
+
227
+ ## 🪪 Licence
228
+
229
+ This project is licensed under the **MIT License** - see the [LICENSE](./LICENSE) file for details. Parts of this project use code licensed under the Apache License 2.0.
230
+
231
+
232
+
233
+ ## ✨Reference
234
+
235
+ If you find LLM4AD helpful please cite:
236
+
237
+ ```bibtex
238
+ @article{liu2024llm4ad,
239
+ title={LLM4AD: A Platform for Algorithm Design with Large Language Model},
240
+ author={Fei Liu and Rui Zhang and Zhuoliang Xie and Rui Sun and Kai Li and Xi Lin and Zhenkun Wang and Zhichao Lu and Qingfu Zhang},
241
+ year={2024},
242
+ eprint={2412.17287},
243
+ archivePrefix={arXiv},
244
+ primaryClass={cs.AI},
245
+ url={https://arxiv.org/abs/2412.17287},
246
+ }
247
+ ```
248
+
249
+
250
+
251
+ ## About LLM4AD
252
+
253
+ This platform is developed and maintained by LLM4AD developer group from the City University of Hong Kong (CityUHK) and the Southern University of Science and Technology (SUSTech). We develop LLM4AD platform for research purposes and hope to contribute to the research area by delivering tools for LLM-based algorithm design methods.
254
+
255
+ + **Contribution:** We are more than welcome to contribute (see our 📖 [contribution guide](https://github.com/Optima-CityU/llm4ad/tree/main/assets/contribution.md)) including developing code and ideas to improve our platform.
256
+ + **Collaborations:** If you like our platform, and you would like to use it for profit-making purposes? We are always searching for industrial collaborations because they help direct research to meet the industry’s needs.
257
+ + **Issue:** If you find a bug or you have any kind of concern regarding the correctness, please report us an [issue](https://github.com/Optima-CityU/llm4ad/issues).
258
+ + **Profit Purpose:** If you intend to use LLM4AD for any profit-making purposes, please contact [us](http://www.llm4ad.com/contact.html).
259
+
260
+ ## :star: Star Trends
261
+ [![Star History Chart](https://api.star-history.com/svg?repos=Optima-CityU/llm4ad&type=Date)](https://star-history.com/#Optima-CityU/llm4ad&Date)
262
+
263
+ ## Contact
264
+
265
+ If you are interested in LLM4AD or if you encounter any difficulty using the platform, you can:
266
+
267
+ 1. Visit our website [LLM4AD Web](http://www.llm4ad.com)
268
+
269
+ 2. Visit our collection [a collection of resources and research papers on LLM4AD](https://github.com/FeiLiu36/LLM4Opt)
270
+
271
+ 3. Visit [Discussions](https://github.com/Optima-CityU/llm4ad/discussions) to connect with other members of our community
272
+
273
+ 4. Join our QQ Group
274
+
275
+ <img src="./assets/figs/qq.png" alt="LLM4AD Logo" style="width: 30%; height: auto;">
276
+
277
+ 5. Contact us through email fliu36-c@my.cityu.edu.hk
278
+
279
+ 6. Submit an [issue](https://github.com/Optima-CityU/LLM4AD)
280
+
281
+
282
+
283
+ ## Contributors
284
+
285
+ Any new ideas, features, and improvements are welcomed!
286
+
287
+ You can contribute to LLM4AD follow our 📖 [Contribution Guide](https://github.com/Optima-CityU/llm4ad/tree/main/assets/contribution.md).
288
+
289
+ Thank you for contributing to LLM4AD and welcome to being part of the LLM4AD community! :sparkles:
290
+
291
+ <table>
292
+ <tbody>
293
+ <tr>
294
+ <td align="center" valign="top" width="12.5%"><a href="https://github.com/FeiLiu36"><img src="https://avatars.githubusercontent.com/FeiLiu36" width="50px;" alt="Fei Liu"/><br /><sub><b>Fei Liu</b></sub></td>
295
+ <td align="center" valign="top" width="12.5%"><a href="https://ahalikai.github.io/"><img src="https://github.com/Ahalikai/Ahalikai.github.io/blob/main/Aha.jpg?raw=true" width="50px;" alt="Kai Li"/><br /><sub><b>Kai Li</b></sub>
296
+ </td>
297
+ <td align="center" valign="top" width="12.5%"><a href="https://github.com/SunnyR7"><img src="https://avatars.githubusercontent.com/SunnyR7" width="50px;" alt="Rui Sun"/><br /><sub><b>Rui Sun</b></sub></td>
298
+ <td align="center" valign="top" width="12.5%"><a href="https://github.com/Acquent0"><img src="https://avatars.githubusercontent.com/Acquent0" width="50px;" alt="Julian XIE"/><br /><sub><b>Julian XIE</b></sub>
299
+ </td>
300
+ <td align="center" valign="top" width="12.5%"><a href="https://github.com/ShunyuYao6"><img src="https://avatars.githubusercontent.com/ShunyuYao6" width="50px;" alt="Shunyu Yao"/><br /><sub><b>Shunyu Yao</b></sub>
301
+ </td>
302
+ <td align="center" valign="top" width="12.5%"><a href="https://github.com/RayZhhh"><img src="https://avatars.githubusercontent.com/RayZhhh" width="50px;" alt="Rui Zhang"/><br /><sub><b>Rui Zhang</b></sub>
303
+ </td>
304
+ </tr>
305
+
306
+
@@ -0,0 +1,6 @@
1
+ from . import base
2
+ from . import method
3
+ from . import task
4
+ from .tools import profiler
5
+ from .tools import llm
6
+
@@ -0,0 +1,9 @@
1
+ from . import code, evaluate, sample, modify_code
2
+ from .code import (
3
+ Function,
4
+ Program,
5
+ TextFunctionProgramConverter
6
+ )
7
+ from .evaluate import Evaluation, SecureEvaluator
8
+ from .modify_code import ModifyCode
9
+ from .sample import LLM, SampleTrimmer
@@ -0,0 +1,270 @@
1
+ """
2
+ This file implements 2 classes representing unities of code:
3
+
4
+ - Function, containing all the information we need about functions: name, args,
5
+ body and optionally a return type and a docstring.
6
+
7
+ - Program, which contains a code preface (which could be imports, global
8
+ variables and classes, ...) and a list of Functions.
9
+
10
+ - For example, a function is shown below,
11
+ which is an un-executable program because 'np' is not defined, and 'WEIGHT' is not defined.
12
+ --------------------------------------------------------------------------------------------
13
+ def func(a: np.ndarray, b: np.ndarray) -> np.ndarray:
14
+ b = b + WEIGHT
15
+ return a + b
16
+ --------------------------------------------------------------------------------------------
17
+
18
+ - A program is an executable object as shown below.
19
+ --------------------------------------------------------------------------------------------
20
+ import numpy as np
21
+ WEIGHT = 10
22
+
23
+ def func(a: np.ndarray, b: np.ndarray) -> np.ndarray:
24
+ b = b + WEIGHT
25
+ return a + b
26
+ --------------------------------------------------------------------------------------------
27
+ """
28
+ from __future__ import annotations
29
+
30
+ import ast
31
+ import copy
32
+ import dataclasses
33
+ from typing import Any
34
+
35
+
36
+ @dataclasses.dataclass
37
+ class Function:
38
+ """A parsed Python function."""
39
+
40
+ name: str
41
+ args: str
42
+ body: str
43
+ return_type: str | None = None
44
+ docstring: str | None = None
45
+ score: Any | None = None
46
+ evaluate_time: float | None = None
47
+ sample_time: float | None = None
48
+
49
+ def __str__(self) -> str:
50
+ return_type = f' -> {self.return_type}' if self.return_type else ''
51
+
52
+ function = f'def {self.name}({self.args}){return_type}:\n'
53
+ if self.docstring:
54
+ # self.docstring is already indented on every line except the first one.
55
+ # Here, we assume the indentation is always four spaces.
56
+ new_line = '\n' if self.body else ''
57
+ function += f' """{self.docstring}"""{new_line}'
58
+ # self.body is already indented.
59
+ function += self.body + '\n\n'
60
+ return function
61
+
62
+ def __setattr__(self, name: str, value: str) -> None:
63
+ # Ensure there aren't leading & trailing new lines in `body`.
64
+ if name == 'body':
65
+ value = value.strip('\n')
66
+ # Ensure there aren't leading & trailing quotes in `docstring``.
67
+ if name == 'docstring' and value is not None:
68
+ if '"""' in value:
69
+ value = value.strip()
70
+ value = value.replace('"""', '')
71
+ super().__setattr__(name, value)
72
+
73
+ def __eq__(self, other: Function):
74
+ assert isinstance(other, Function)
75
+ return (self.name == other.name and
76
+ self.args == other.args and
77
+ self.return_type == other.return_type and
78
+ self.body == other.body)
79
+
80
+
81
+ @dataclasses.dataclass(frozen=True)
82
+ class Program:
83
+ """A parsed Python program."""
84
+
85
+ # `preface` is everything from the beginning of the code till the first
86
+ # function is found.
87
+ preface: str
88
+ functions: list[Function]
89
+
90
+ def __str__(self) -> str:
91
+ program = f'{self.preface}\n' if self.preface else ''
92
+ program += '\n'.join([str(f) for f in self.functions])
93
+ return program
94
+
95
+ def find_function_index(self, function_name: str) -> int:
96
+ """Returns the index of input function name."""
97
+ function_names = [f.name for f in self.functions]
98
+ count = function_names.count(function_name)
99
+ if count == 0:
100
+ raise ValueError(
101
+ f'function {function_name} does not exist in program:\n{str(self)}'
102
+ )
103
+ if count > 1:
104
+ raise ValueError(
105
+ f'function {function_name} exists more than once in program:\n'
106
+ f'{str(self)}'
107
+ )
108
+ index = function_names.index(function_name)
109
+ return index
110
+
111
+ def get_function(self, function_name: str) -> Function:
112
+ index = self.find_function_index(function_name)
113
+ return self.functions[index]
114
+
115
+
116
+ class _ProgramVisitor(ast.NodeVisitor):
117
+ """Parses code to collect all required information to produce a `Program`.
118
+ Note that we do not store function decorators.
119
+ """
120
+
121
+ def __init__(self, sourcecode: str):
122
+ self._codelines: list[str] = sourcecode.splitlines()
123
+ self._preface: str = ''
124
+ self._functions: list[Function] = []
125
+ self._current_function: str | None = None
126
+
127
+ def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
128
+ """Collects all information about the function being parsed.
129
+ """
130
+ # We only care about first level functions.
131
+ if node.col_offset == 0:
132
+ self._current_function = node.name
133
+ # --------------------------------------------------------------------------------------------
134
+ # RZ: Here is an issue: some cases were not taken into consideration.
135
+ # For instance, if the first parsed function has decorators,
136
+ # these decorators will also be retained in the preceding code snippet.
137
+ # However, in the algorithm's flow, these decorators are invalid,
138
+ # leading to subsequent evaluations reporting errors.
139
+ # --------------------------------------------------------------------------------------------
140
+ # if not self._functions:
141
+ # self._preface = '\n'.join(self._codelines[:node.lineno - 1])
142
+ # --------------------------------------------------------------------------------------------
143
+ # Fix bugs: if the first function is decorated, find the smallest line_no of the decorator,
144
+ # FIX bugs: and retrain the code above it as 'preface'.
145
+ # --------------------------------------------------------------------------------------------
146
+ if not self._functions:
147
+ has_decorators = bool(node.decorator_list)
148
+ if has_decorators:
149
+ # find the minimum line number and retain the code above
150
+ decorator_start_line = min(decorator.lineno for decorator in node.decorator_list)
151
+ self._preface = '\n'.join(self._codelines[:decorator_start_line - 1])
152
+ else:
153
+ self._preface = '\n'.join(self._codelines[:node.lineno - 1])
154
+ # --------------------------------------------------------------------------------------------
155
+ function_end_line = node.end_lineno
156
+ body_start_line = node.body[0].lineno - 1
157
+ # Extract the docstring.
158
+ docstring = None
159
+ if isinstance(node.body[0], ast.Expr) and isinstance(node.body[0].value, ast.Str):
160
+ docstring = f' """{ast.literal_eval(ast.unparse(node.body[0]))}"""'
161
+ if len(node.body) > 1:
162
+ # ----------------------------------------------------------------------------
163
+ # RZ: If the next line of the docstring is also comment that starts with "#"
164
+ # We should preserve it.
165
+ # ----------------------------------------------------------------------------
166
+ # body_start_line = node.body[1].lineno - 1
167
+ # ----------------------------------------------------------------------------
168
+ # Fix bugs: If we find the docstring, the function body start with
169
+ # Fix bugs: body[0].end_lineno, where body[0] refers to the docstring node.
170
+ # ----------------------------------------------------------------------------
171
+ body_start_line = node.body[0].end_lineno
172
+ # ----------------------------------------------------------------------------
173
+ else:
174
+ body_start_line = function_end_line
175
+
176
+ self._functions.append(Function(
177
+ name=node.name,
178
+ args=ast.unparse(node.args),
179
+ return_type=ast.unparse(node.returns) if node.returns else None,
180
+ docstring=docstring,
181
+ body='\n'.join(self._codelines[body_start_line:function_end_line]),
182
+ ))
183
+ self.generic_visit(node)
184
+
185
+ def return_program(self) -> Program:
186
+ return Program(preface=self._preface, functions=self._functions)
187
+
188
+
189
+ class TextFunctionProgramConverter:
190
+ """Convert text to Program instance and Function instance,
191
+ Convert Program instance to Function instance, and Function instance to Program instance.
192
+ """
193
+
194
+ @classmethod
195
+ def text_to_program(cls, program_str: str) -> Program | None:
196
+ """Returns Program object by parsing input text using Python AST.
197
+ """
198
+ try:
199
+ # We assume that the program is composed of some preface (e.g. imports,
200
+ # classes, assignments, ...) followed by a sequence of functions.
201
+ tree = ast.parse(program_str)
202
+ visitor = _ProgramVisitor(program_str)
203
+ visitor.visit(tree)
204
+ return visitor.return_program()
205
+ except:
206
+ return None
207
+
208
+ @classmethod
209
+ def text_to_function(cls, program_str: str) -> Function | None:
210
+ """Returns Function object by parsing input text using Python AST.
211
+ """
212
+ try:
213
+ program = cls.text_to_program(program_str)
214
+ if len(program.functions) != 1:
215
+ raise ValueError(f'Only one function expected, got {len(program.functions)}'
216
+ f':\n{program.functions}')
217
+ return program.functions[0]
218
+ except ValueError as value_err:
219
+ raise value_err
220
+ except:
221
+ return None
222
+
223
+ @classmethod
224
+ def function_to_program(cls, function: str | Function, template_program: str | Program) -> Program | None:
225
+ try:
226
+ # convert function to Function instance
227
+ if isinstance(function, str):
228
+ function = cls.text_to_function(function)
229
+ else:
230
+ function = copy.deepcopy(function)
231
+
232
+ # convert template_program to Program instance
233
+ if isinstance(template_program, str):
234
+ template_program = cls.text_to_program(template_program)
235
+ else:
236
+ template_program = copy.deepcopy(template_program)
237
+
238
+ # assert that a program have one function
239
+ if len(template_program.functions) != 1:
240
+ raise ValueError(f'Only one function expected, got {len(template_program.functions)}'
241
+ f':\n{template_program.functions}')
242
+
243
+ # replace the function body with the new function body
244
+ template_program.functions[0].body = function.body
245
+ return template_program
246
+ except ValueError as value_err:
247
+ raise value_err
248
+ except:
249
+ return None
250
+
251
+ @classmethod
252
+ def program_to_function(cls, program: str | Program) -> Function | None:
253
+ try:
254
+ # convert program to Program instance
255
+ if isinstance(program, str):
256
+ program = cls.text_to_program(program)
257
+ else:
258
+ program = copy.deepcopy(program)
259
+
260
+ # assert that a program have one function
261
+ if len(program.functions) != 1:
262
+ raise ValueError(f'Only one function expected, got {len(program.functions)}'
263
+ f':\n{program.functions}')
264
+
265
+ # return the function
266
+ return program.functions[0]
267
+ except ValueError as value_err:
268
+ raise value_err
269
+ except:
270
+ return None