first
This commit is contained in:
commit
e4c411bbe2
|
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
output/
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# UV
|
||||
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
#uv.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||
.pdm.toml
|
||||
.pdm-python
|
||||
.pdm-build/
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# Ruff stuff:
|
||||
.ruff_cache/
|
||||
|
||||
# PyPI configuration file
|
||||
.pypirc
|
||||
|
||||
# Cursor
|
||||
# Cursor is an AI-powered code editor.`.cursorignore` specifies files/directories to
|
||||
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
||||
# refer to https://docs.cursor.com/context/ignore-files
|
||||
.cursorignore
|
||||
.cursorindexingignore
|
||||
*.xlsx
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
import json
|
||||
import os
|
||||
|
||||
import matplotlib
|
||||
import pandas as pd
|
||||
import solara
|
||||
from mesa.visualization import SolaraViz, make_plot_component
|
||||
|
||||
from simulation_model import SimulationModel
|
||||
|
||||
# Configure matplotlib to support Chinese labels.
|
||||
matplotlib.rcParams["font.family"] = ["Microsoft YaHei", "SimHei", "sans-serif"]
|
||||
matplotlib.rcParams["axes.unicode_minus"] = False
|
||||
|
||||
# Load default parameters from data/model_params.json
|
||||
with open("data/model_params.json", "r", encoding="utf-8") as f:
|
||||
_cfg = json.load(f)
|
||||
|
||||
def _load_factory_name_map():
|
||||
try:
|
||||
with open("data/factory_mapping.json", "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
except FileNotFoundError:
|
||||
return {}
|
||||
# data is Chinese name -> code; invert it
|
||||
return {v: k for k, v in data.items()}
|
||||
|
||||
|
||||
FACTORY_NAME_MAP = _load_factory_name_map()
|
||||
|
||||
def _load_product_catalog():
|
||||
try:
|
||||
try:
|
||||
df = pd.read_csv("data/product.csv", encoding="utf-8")
|
||||
except UnicodeDecodeError:
|
||||
df = pd.read_csv("data/product.csv", encoding="gbk")
|
||||
except FileNotFoundError:
|
||||
return pd.DataFrame()
|
||||
df.columns = [c.strip() for c in df.columns]
|
||||
rename_map = {
|
||||
df.columns[0]: "平台",
|
||||
df.columns[1]: "标准机型",
|
||||
df.columns[2]: "叶片型号",
|
||||
}
|
||||
df = df.rename(columns=rename_map)
|
||||
df["平台"] = df["平台"].astype(str).str.strip()
|
||||
df["标准机型"] = df["标准机型"].astype(str).str.strip()
|
||||
df["叶片型号"] = df["叶片型号"].astype(str).str.strip()
|
||||
return df
|
||||
|
||||
|
||||
PRODUCT_DF = _load_product_catalog()
|
||||
ALL_PLATFORMS = sorted(PRODUCT_DF["平台"].dropna().unique()) if not PRODUCT_DF.empty else []
|
||||
ALL_STANDARDS = sorted(PRODUCT_DF["标准机型"].dropna().unique()) if not PRODUCT_DF.empty else []
|
||||
|
||||
def _platform_options():
|
||||
return ["全部"] + ALL_PLATFORMS
|
||||
|
||||
|
||||
def _standard_options(platform):
|
||||
if PRODUCT_DF.empty:
|
||||
return ["全部"]
|
||||
if platform and platform != "全部":
|
||||
stds = sorted(PRODUCT_DF.loc[PRODUCT_DF["平台"] == platform, "标准机型"].dropna().unique())
|
||||
else:
|
||||
stds = ALL_STANDARDS
|
||||
return ["全部"] + [s for s in stds if s]
|
||||
|
||||
|
||||
def _product_set_for_selection(platform, standard):
|
||||
if PRODUCT_DF.empty:
|
||||
return []
|
||||
df = PRODUCT_DF
|
||||
if platform and platform != "全部":
|
||||
df = df[df["平台"] == platform]
|
||||
if standard and standard != "全部":
|
||||
df = df[df["标准机型"] == standard]
|
||||
return sorted(df["叶片型号"].dropna().unique())
|
||||
|
||||
def _legend_postprocess(label_map, ylabel=None):
|
||||
def _post(ax):
|
||||
handles, labels = ax.get_legend_handles_labels()
|
||||
if labels:
|
||||
mapped = [label_map.get(label, label) for label in labels]
|
||||
ax.legend(handles, mapped, loc="best")
|
||||
if ylabel:
|
||||
ax.set_ylabel(ylabel)
|
||||
return _post
|
||||
|
||||
|
||||
def _split_product_set(text: str):
|
||||
return [p.strip() for p in text.split(",") if p.strip()]
|
||||
|
||||
|
||||
@solara.component
|
||||
def Page():
|
||||
platform_selected = solara.use_reactive("全部")
|
||||
standard_selected = solara.use_reactive("全部")
|
||||
initial_product_set_text = ",".join(_cfg.get("product_set", []))
|
||||
product_set_value = solara.use_reactive(initial_product_set_text)
|
||||
|
||||
def sync_product_set(platform_val, standard_val):
|
||||
blades = _product_set_for_selection(platform_val, standard_val)
|
||||
if blades:
|
||||
product_set_value.set(",".join(blades))
|
||||
elif PRODUCT_DF.empty:
|
||||
product_set_value.set(initial_product_set_text)
|
||||
else:
|
||||
product_set_value.set("")
|
||||
|
||||
def on_platform_change(val):
|
||||
platform_selected.set(val)
|
||||
std_opts = _standard_options(val)
|
||||
if standard_selected.value not in std_opts:
|
||||
standard_selected.set("全部")
|
||||
active_std = "全部"
|
||||
else:
|
||||
active_std = standard_selected.value
|
||||
sync_product_set(val, active_std)
|
||||
|
||||
def on_standard_change(val):
|
||||
standard_selected.set(val)
|
||||
sync_product_set(platform_selected.value, val)
|
||||
|
||||
# Build model params fresh each render so product_set value stays in sync
|
||||
model_params = {
|
||||
"product_set": {"type": "InputText", "value": product_set_value, "label": "产品集合(逗号分隔)"},
|
||||
"is_within_region_allocation_only": {
|
||||
"type": "Select",
|
||||
"value": bool(_cfg.get("is_within_region_allocation_only", False)),
|
||||
"values": [False, True],
|
||||
"label": "仅区域内调拨?(布尔)",
|
||||
},
|
||||
"month1": {"type": "InputText", "value": _cfg.get("month1", 220), "label": "第1个月效率(小时/支)"},
|
||||
"month2": {"type": "InputText", "value": _cfg.get("month2", 100), "label": "第2个月效率(小时/支)"},
|
||||
"month3": {"type": "InputText", "value": _cfg.get("month3", 45), "label": "第3个月效率(小时/支)"},
|
||||
"month4": {"type": "InputText", "value": _cfg.get("month4", 36), "label": "第4个月及以后效率(小时/支)"},
|
||||
"holiday_days_1": {"type": "InputText", "value": _cfg.get("holiday_days_1", 2), "label": "1月假日天数(天)"},
|
||||
"holiday_days_2": {"type": "InputText", "value": _cfg.get("holiday_days_2", 2), "label": "2月假日天数(天)"},
|
||||
"holiday_days_3": {"type": "InputText", "value": _cfg.get("holiday_days_3", 2), "label": "3月假日天数(天)"},
|
||||
"holiday_days_4": {"type": "InputText", "value": _cfg.get("holiday_days_4", 2), "label": "4月假日天数(天)"},
|
||||
"holiday_days_5": {"type": "InputText", "value": _cfg.get("holiday_days_5", 2), "label": "5月假日天数(天)"},
|
||||
"holiday_days_6": {"type": "InputText", "value": _cfg.get("holiday_days_6", 2), "label": "6月假日天数(天)"},
|
||||
"holiday_days_7": {"type": "InputText", "value": _cfg.get("holiday_days_7", 2), "label": "7月假日天数(天)"},
|
||||
"holiday_days_8": {"type": "InputText", "value": _cfg.get("holiday_days_8", 2), "label": "8月假日天数(天)"},
|
||||
"holiday_days_9": {"type": "InputText", "value": _cfg.get("holiday_days_9", 2), "label": "9月假日天数(天)"},
|
||||
"holiday_days_10": {"type": "InputText", "value": _cfg.get("holiday_days_10", 2), "label": "10月假日天数(天)"},
|
||||
"holiday_days_11": {"type": "InputText", "value": _cfg.get("holiday_days_11", 2), "label": "11月假日天数(天)"},
|
||||
"holiday_days_12": {"type": "InputText", "value": _cfg.get("holiday_days_12", 2), "label": "12月假日天数(天)"},
|
||||
}
|
||||
for key, val in _cfg.items():
|
||||
if key.startswith("factor_"):
|
||||
suffix = key.replace("factor_", "")
|
||||
label_name = FACTORY_NAME_MAP.get(suffix, suffix)
|
||||
model_params[key] = {"type": "InputText", "value": val, "label": f"{label_name} 磨合系数(倍率)"}
|
||||
|
||||
active_model = solara.use_memo(
|
||||
lambda: SimulationModel(product_set=_split_product_set(product_set_value.value)),
|
||||
dependencies=[product_set_value.value],
|
||||
)
|
||||
|
||||
production_label_map = {region: f"{region}-产出[套]" for region in active_model.region_names}
|
||||
demand_label_map = {f"demand_{region}": f"{region}-需求[套]" for region in active_model.demand_regions}
|
||||
inventory_label_map = {f"inventory_{region}": f"{region}-库存[套]" for region in active_model.region_names}
|
||||
fulfill_pct_label_map = {f"fulfill_pct_{region}": f"{region}-满足率[%]" for region in active_model.demand_regions}
|
||||
unmet_label_map = {f"unmet_{region}": f"{region}-未满足需求[套]" for region in active_model.demand_regions}
|
||||
overall_fulfill_label_map = {"fulfill_pct_overall": "总体满足率[%]"}
|
||||
transport_cost_label_map = {"transport_cost": "运输成本[万元]"}
|
||||
fulfill_month_label_map = {f"fulfill_month_{region}": f"{region}-当月满足率[%]" for region in active_model.demand_regions}
|
||||
fulfill_cum_label_map = {f"fulfill_cum_{region}": f"{region}-累计满足率[%]" for region in active_model.demand_regions}
|
||||
transport_units_label_map = {f"transport_units_{region}": f"{region}-运输量[套]" for region in active_model.demand_regions}
|
||||
|
||||
RegionPlot = make_plot_component(
|
||||
{region: f"C{idx}" for idx, region in enumerate(active_model.region_names)},
|
||||
post_process=_legend_postprocess(production_label_map, ylabel="产出[套]"),
|
||||
)
|
||||
DemandPlot = make_plot_component(
|
||||
{f"demand_{region}": f"C{idx}" for idx, region in enumerate(active_model.demand_regions)},
|
||||
post_process=_legend_postprocess(demand_label_map, ylabel="需求量[套]"),
|
||||
)
|
||||
InventoryPlot = make_plot_component(
|
||||
{f"inventory_{region}": f"C{idx}" for idx, region in enumerate(active_model.region_names)},
|
||||
post_process=_legend_postprocess(inventory_label_map, ylabel="库存量[套]"),
|
||||
)
|
||||
FulfillPlot = make_plot_component(
|
||||
{f"fulfill_pct_{region}": f"C{idx}" for idx, region in enumerate(active_model.demand_regions)},
|
||||
post_process=_legend_postprocess(fulfill_pct_label_map, ylabel="满足率[%]"),
|
||||
)
|
||||
UnmetPlot = make_plot_component(
|
||||
{f"unmet_{region}": f"C{idx}" for idx, region in enumerate(active_model.demand_regions)},
|
||||
post_process=_legend_postprocess(unmet_label_map, ylabel="未满足需求[套]"),
|
||||
)
|
||||
OverallFulfillPlot = make_plot_component(
|
||||
{"fulfill_pct_overall": "tab:purple"},
|
||||
post_process=_legend_postprocess(overall_fulfill_label_map, ylabel="总体满足率[%]"),
|
||||
)
|
||||
TransportCostPlot = make_plot_component(
|
||||
{"transport_cost": "tab:brown"},
|
||||
post_process=_legend_postprocess(transport_cost_label_map, ylabel="运输成本[万元]"),
|
||||
)
|
||||
FulfillMonthPlot = make_plot_component(
|
||||
{f"fulfill_month_{region}": f"C{idx}" for idx, region in enumerate(active_model.demand_regions)},
|
||||
post_process=_legend_postprocess(fulfill_month_label_map, ylabel="当月满足率[%]"),
|
||||
)
|
||||
FulfillCumPlot = make_plot_component(
|
||||
{f"fulfill_cum_{region}": f"C{idx}" for idx, region in enumerate(active_model.demand_regions)},
|
||||
post_process=_legend_postprocess(fulfill_cum_label_map, ylabel="累计满足率[%]"),
|
||||
)
|
||||
TransportUnitsPlot = make_plot_component(
|
||||
{f"transport_units_{region}": f"C{idx}" for idx, region in enumerate(active_model.demand_regions)},
|
||||
post_process=_legend_postprocess(transport_units_label_map, ylabel="运输量[套]"),
|
||||
)
|
||||
|
||||
def get_total_production(model):
|
||||
return solara.Markdown(f"**累计产量(机组):{model.cumulative_production:.2f}**")
|
||||
|
||||
def get_mean_abs_error(model):
|
||||
return solara.Markdown(f"**工厂年产量均值绝对误差:{model.mean_abs_error:.2f}**")
|
||||
|
||||
with solara.Column() as main:
|
||||
with solara.Card("产品筛选"):
|
||||
solara.Select(
|
||||
label="平台",
|
||||
value=platform_selected,
|
||||
values=_platform_options(),
|
||||
on_value=on_platform_change,
|
||||
)
|
||||
solara.Select(
|
||||
label="标准机型",
|
||||
value=standard_selected,
|
||||
values=_standard_options(platform_selected.value),
|
||||
on_value=on_standard_change,
|
||||
)
|
||||
solara.Text(f"叶片型号数:{len(_split_product_set(product_set_value.value))}")
|
||||
SolaraViz(
|
||||
active_model,
|
||||
renderer=None,
|
||||
components=[
|
||||
RegionPlot,
|
||||
DemandPlot,
|
||||
InventoryPlot,
|
||||
FulfillPlot,
|
||||
UnmetPlot,
|
||||
OverallFulfillPlot,
|
||||
TransportCostPlot,
|
||||
FulfillMonthPlot,
|
||||
FulfillCumPlot,
|
||||
TransportUnitsPlot,
|
||||
get_total_production,
|
||||
get_mean_abs_error,
|
||||
],
|
||||
model_params=model_params,
|
||||
name="产线生产与需求可视化",
|
||||
show_parameter_values=True,
|
||||
)
|
||||
return main
|
||||
|
||||
|
||||
page = Page()
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import math
|
||||
from pathlib import Path
|
||||
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def haversine(lat1, lon1, lat2, lon2):
|
||||
R = 6371.0 # Earth radius in km
|
||||
phi1, phi2 = math.radians(lat1), math.radians(lat2)
|
||||
dphi = math.radians(lat2 - lat1)
|
||||
dlambda = math.radians(lon2 - lon1)
|
||||
a = math.sin(dphi / 2) ** 2 + math.cos(phi1) * math.cos(phi2) * math.sin(dlambda / 2) ** 2
|
||||
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
|
||||
return R * c
|
||||
|
||||
|
||||
def _read_csv_flexible(path: str, header: int = 0):
|
||||
for enc in ["utf-8", "utf-8-sig", "gbk", "latin1"]:
|
||||
try:
|
||||
return pd.read_csv(path, encoding=enc, engine="python")
|
||||
except UnicodeDecodeError:
|
||||
continue
|
||||
# fallback with ignoring errors
|
||||
return pd.read_csv(path, encoding="utf-8", engine="python", encoding_errors="ignore")
|
||||
|
||||
|
||||
def _infer_coords(df, name_col, lat_col, lon_col):
|
||||
# Cast numeric columns
|
||||
df[lat_col] = pd.to_numeric(df[lat_col], errors="coerce")
|
||||
df[lon_col] = pd.to_numeric(df[lon_col], errors="coerce")
|
||||
|
||||
lat_range = df[lat_col].between(-90, 90).mean()
|
||||
lon_range = df[lon_col].between(-180, 180).mean()
|
||||
|
||||
# If swapped, switch
|
||||
if lat_range < lon_range:
|
||||
df[lat_col], df[lon_col] = df[lon_col], df[lat_col]
|
||||
|
||||
df = df.rename(columns={name_col: "name", lat_col: "lat", lon_col: "lon"})
|
||||
return df[["name", "lat", "lon"]].dropna()
|
||||
|
||||
|
||||
def main():
|
||||
demand = _read_csv_flexible("data/DemandLocation.csv")
|
||||
factory = _read_csv_flexible("data/FactoryLocation.csv")
|
||||
|
||||
# Demand: assume first column name, last two numeric
|
||||
demand_coords = _infer_coords(demand, demand.columns[0], demand.columns[-2], demand.columns[-1])
|
||||
# Factory: assume first column name, last two numeric
|
||||
factory_coords = _infer_coords(factory, factory.columns[0], factory.columns[-2], factory.columns[-1])
|
||||
|
||||
rows = []
|
||||
for _, drow in demand_coords.iterrows():
|
||||
for _, frow in factory_coords.iterrows():
|
||||
dist = haversine(drow["lat"], drow["lon"], frow["lat"], frow["lon"])
|
||||
rows.append({"demand_city": drow["name"], "factory": frow["name"], "distance_km": dist})
|
||||
|
||||
df = pd.DataFrame(rows)
|
||||
out_path = Path("data") / "distance_matrix.csv"
|
||||
df.to_csv(out_path, index=False, encoding="utf-8-sig")
|
||||
print(f"Saved {len(df)} rows to {out_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
需求方,经度,纬度
|
||||
三门峡市,111.581892,34.592412
|
||||
中卫市,104.326348,37.42582674
|
||||
乌兰察布市,112.583248,41.859146
|
||||
乌鲁木齐市,88.3526,43.4871
|
||||
佳木斯市,132.578341,46.90926
|
||||
兴安盟,122.089308,45.921339
|
||||
南阳市,112.97302,32.488644
|
||||
吐鲁番地区,88.26158,42.931764
|
||||
吴忠市,105.999463,37.823582
|
||||
哈密市,93.2830057,43.96107218
|
||||
哈尔滨市,128.1882308,45.77706491
|
||||
商丘市,115.17386,34.39346
|
||||
国际,101.091124,38.787478
|
||||
塔城地区,85.047175,46.867906
|
||||
大同市,114.3823027,39.46432744
|
||||
天津市,117.408432,40.046544
|
||||
定西市,104.24555,34.360151
|
||||
巴音郭楞蒙古自治州,87.795193,39.202885
|
||||
庆阳市,106.578249,36.363741
|
||||
延安市,107.7202223,36.9307021
|
||||
张家口市,114.366182,41.115161
|
||||
德州市,116.7061394,37.21128042
|
||||
忻州市,111.320864,38.89993
|
||||
恩施土家族苗族自治州,108.789522,30.452828
|
||||
承德市,117.306009,41.817294
|
||||
新疆生产建设兵团第十师,87.659628,47.373723
|
||||
昆明市,103.3556505,25.74601202
|
||||
昌吉回族自治州,90.524934,44.753213
|
||||
晋中市,113.9980185,37.59244878
|
||||
曲靖市,104.066905,25.501188
|
||||
朔州市,111.95946,39.612056
|
||||
朝阳市,120.960563,42.159688
|
||||
来宾市,108.8706184,23.53272696
|
||||
松原市,123.5325177,44.3099525
|
||||
梧州市,110.8023439,23.92578726
|
||||
榆林市,109.424847,38.670326
|
||||
永州市,111.470832,25.975085
|
||||
沈阳市,123.350854,42.471099
|
||||
沧州市,117.354557,38.27852
|
||||
河池市,106.764545,25.04219
|
||||
济源市,112.1719039,35.04617738
|
||||
海南藏族自治州,99.66212099,36.11799294
|
||||
海西蒙古族藏族自治州,96.085432,37.13638947
|
||||
渭南市,109.5518929,35.41186149
|
||||
烟台市,121.0760873,36.62456081
|
||||
玉林市,110.140777,22.17541
|
||||
白城市,123.906296,45.50445
|
||||
百色市,105.9323029,24.4875734
|
||||
秦皇岛市,119.2400992,39.53770068
|
||||
绥化市,127.581712,46.566521
|
||||
聊城市,115.4099,36.5642
|
||||
荆州市,112.2145266,29.71230666
|
||||
荆门市,112.590853,31.324363
|
||||
葫芦岛市,120.69668,40.701877
|
||||
衡水市,115.432929,38.006891
|
||||
赣州市,114.879181,25.768879
|
||||
辽阳市,123.438258,41.423986
|
||||
运城市,111.8791446,35.53009921
|
||||
通辽市,121.079033,43.025639
|
||||
邢台市,114.9568513,37.40531178
|
||||
鄂尔多斯市,110.669035,40.003893
|
||||
酒泉市,97.142116,40.792238
|
||||
重庆市,108.012898,29.179982
|
||||
钦州市,109.3893375,22.15819114
|
||||
铜仁市,108.504004,28.563993
|
||||
锡林郭勒盟,114.8256,44.5873
|
||||
锦州市,121.510124,40.97325273
|
||||
阜阳市,114.967423,33.016503
|
||||
阳江市,112.0157107,20.9886087
|
||||
阳泉市,113.148888,38.211682
|
||||
阿勒泰地区,85.62480544,47.14043099
|
||||
鞍山市,122.3749923,41.31678205
|
||||
黄冈市,115.937974,29.922599
|
||||
黔西南布依族苗族自治州,105.87635,24.965761
|
||||
济南市,117.02,36.40
|
||||
安阳市,114,35.72
|
||||
白银市,104.09,36.41
|
||||
毕节市,106,26.86
|
||||
邯郸市,114.47,36.60
|
||||
七台河市,131.01,45.78
|
||||
通化市,125.95,41.73
|
||||
盐城市,120.17,33.36
|
||||
本溪市,123.69,41.49
|
||||
鹤岗市,130.30,47.36
|
||||
开封市,114.32,34.80
|
||||
洛阳市,112.45,34.72
|
||||
莆田市,119.01,25.46
|
||||
新乡市,113.81,35.20
|
||||
伊犁哈萨克自治州,43.916823,81.324136
|
||||
镇江市,119.43,32.19
|
||||
上海市,121.29,31.14
|
||||
桂林市,110.296647,25.27981
|
||||
呼和浩特市,111.41,40.48
|
||||
济宁市,116.35,35.41
|
||||
天门市,113.162071,30.647308
|
||||
黔南布依族苗族自治州,106.45,25.45
|
||||
黔东南苗族侗族自治州,107.1720,25.1920
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
工厂,经度,纬度
|
||||
艾郎玉门,97.142116,40.792238
|
||||
艾郎张北,114.366182,41.115161
|
||||
时代巴里坤,93.2830057,43.96107218
|
||||
时代百色,105.9323029,24.4875734
|
||||
时代射阳,119.5548,33.3112
|
||||
时代松原,123.5325177,44.3099525
|
||||
时代株洲,113.151737,27.835806
|
||||
双瑞大丰,120.43,33.11
|
||||
双瑞东营,118.07,36.55
|
||||
天顺濮阳,115.0742,35.7773
|
||||
天顺沙洋,112.590853,31.324363
|
||||
中材白城,123.906296,45.50445
|
||||
中材阜宁,119.8,33.8
|
||||
中材哈密,93.2830057,43.96107218
|
||||
中材邯郸,113.27,36.02
|
||||
中材酒泉,97.142116,40.792238
|
||||
中材连云港,119.13,34.36
|
||||
中材萍乡,113.89,27.66
|
||||
中材锡林,114.8256,44.5873
|
||||
中材兴安盟,122.089308,45.921339
|
||||
中材阳江,112.0157107,20.9886087
|
||||
中材伊吾,93.2830057,43.96107218
|
||||
中材玉溪,101.16,23.19
|
||||
重通昌吉,90.524934,44.753213
|
||||
重通大安,123.906296,45.50445
|
||||
重通如东,120.42,32.12
|
||||
重通武威,103.9680036,39.09623555
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
区域名,工厂名,是否新工厂,产线ID,生产型号,开始月份,结束月份
|
||||
西北东部,艾郎玉门,是,艾郎玉门1,GWBD-A2,1,12
|
||||
西北东部,艾郎玉门,是,艾郎玉门2,GWBD-A2,1,12
|
||||
华北,艾郎张北,是,艾郎张北1,GWBD-A2,1,12
|
||||
华北,艾郎张北,是,艾郎张北2,GWBD-A2,1,12
|
||||
西北西部,时代巴里坤,是,时代巴里坤1,GWBD-A2,5,12
|
||||
西北西部,时代巴里坤,是,时代巴里坤2,GWBD-A2,5,12
|
||||
西北西部,时代巴里坤,是,时代巴里坤3,GW99A,3,4
|
||||
西北西部,时代巴里坤,是,时代巴里坤4,GW99A,6,9
|
||||
华南,时代百色,是,时代百色1,GWBD-A3,5,12
|
||||
华南,时代百色,是,时代百色2,GWBD-A3,5,12
|
||||
华东南北部,时代射阳,是,时代射阳1,GW130,9,12
|
||||
华东南北部,时代射阳,是,时代射阳2,GW130,9,12
|
||||
东北,时代松原,是,时代松原1,GWBD-A3,6,12
|
||||
东北,时代松原,是,时代松原2,GWBD-A3,6,12
|
||||
华东南南部,时代株洲,是,时代株洲1,GW99A,4,12
|
||||
华东南南部,时代株洲,是,时代株洲2,GW99A,4,12
|
||||
华东南北部,双瑞大丰,是,双瑞大丰1,GW110.5,2,11
|
||||
华东南北部,双瑞大丰,是,双瑞大丰2,GW110.5,2,11
|
||||
华东南北部,双瑞大丰,是,双瑞大丰3,GW93,1,1
|
||||
华东南北部,双瑞东营,否,双瑞东营1,GWBD-A2,10,12
|
||||
华东南北部,双瑞东营,否,双瑞东营2,GWBD-A2,10,12
|
||||
华东南北部,双瑞东营,否,双瑞东营3,GWBD-A2,10,12
|
||||
华东南北部,双瑞东营,否,双瑞东营4,GWBD-A2,10,12
|
||||
华东南北部,天顺濮阳,否,天顺濮阳1,GW99A,8,12
|
||||
华东南北部,天顺濮阳,否,天顺濮阳2,GW99A,8,12
|
||||
华东南北部,天顺沙洋,否,天顺沙洋1,GW93,2,2
|
||||
华东南北部,天顺沙洋,是,天顺沙洋2,GW93,5,5
|
||||
华东南北部,天顺沙洋,否,天顺沙洋3,GW93,11,11
|
||||
华东南北部,天顺沙洋,否,天顺沙洋4,GW99,10,11
|
||||
华东南北部,天顺沙洋,否,天顺沙洋5,GW99A,5,12
|
||||
华东南北部,天顺沙洋,否,天顺沙洋6,GW99A,5,12
|
||||
东北,中材白城,否,中材白城1,GWBD-A3,8,8
|
||||
华东南北部,中材阜宁,是,中材阜宁1,GW110.5,4,11
|
||||
华东南北部,中材阜宁,是,中材阜宁2,GW110.5,4,11
|
||||
华东南北部,中材阜宁,是,中材阜宁3,GW110.5,4,11
|
||||
华东南北部,中材阜宁,是,中材阜宁4,GW83.4,1,11
|
||||
华东南北部,中材阜宁,否,中材阜宁5,GW93,6,8
|
||||
华东南北部,中材阜宁,否,中材阜宁6,GW99A,1,7
|
||||
华东南北部,中材阜宁,否,中材阜宁7,GW99A,1,7
|
||||
华东南北部,中材阜宁,否,中材阜宁8,SI90.2,1,12
|
||||
华东南北部,中材阜宁,否,中材阜宁9,SI90.2,1,12
|
||||
华东南北部,中材阜宁,是,中材阜宁10,SI90.2,3,12
|
||||
华东南北部,中材阜宁,是,中材阜宁11,SI90.2,3,12
|
||||
华东南北部,中材阜宁,是,中材阜宁12,SI90.2,3,12
|
||||
华东南北部,中材阜宁,是,中材阜宁13,SI90.2,3,12
|
||||
西北西部,中材哈密,否,中材哈密1,GWBD-A3,7,11
|
||||
西北西部,中材哈密,否,中材哈密2,GWBD-A3,7,11
|
||||
华北,中材邯郸,否,中材邯郸1,GW99A,1,12
|
||||
华北,中材邯郸,否,中材邯郸2,GW99A,1,12
|
||||
华北,中材邯郸,是,中材邯郸3,GWBD-A2,4,12
|
||||
华北,中材邯郸,是,中材邯郸4,GWBD-A2,4,12
|
||||
西北东部,中材酒泉,否,中材酒泉1,GW99,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉2,GW99,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉3,GWBD-A2,2,12
|
||||
西北东部,中材酒泉,否,中材酒泉4,GWBD-A2,2,12
|
||||
西北东部,中材酒泉,否,中材酒泉5,GWBD-A2,2,12
|
||||
西北东部,中材酒泉,是,中材酒泉6,GWBD-A2,2,12
|
||||
西北东部,中材酒泉,否,中材酒泉7,SI90.2,1,1
|
||||
西北东部,中材酒泉,否,中材酒泉8,SI90.2,3,4
|
||||
西北东部,中材酒泉,否,中材酒泉9,SI90.2,3,4
|
||||
西北东部,中材酒泉,否,中材酒泉10,SI90.2,9,9
|
||||
西北东部,中材酒泉,是,中材酒泉11,SI90.2,4,12
|
||||
西北东部,中材酒泉,是,中材酒泉12,SI90.2,4,12
|
||||
华东南北部,中材连云港,是,中材连云港1,GW93,4,4
|
||||
华东南北部,中材连云港,否,中材连云港2,GW93,1,12
|
||||
华东南北部,中材连云港,否,中材连云港3,GW93,1,12
|
||||
华东南南部,中材萍乡,否,中材萍乡1,GW83.4,2,3
|
||||
华东南南部,中材萍乡,是,中材萍乡2,GW93,1,10
|
||||
华东南南部,中材萍乡,是,中材萍乡3,GW93,1,10
|
||||
华东南南部,中材萍乡,是,中材萍乡4,GWBD-A3,2,12
|
||||
华东南南部,中材萍乡,是,中材萍乡5,GWBD-A3,2,12
|
||||
东北,中材锡林,否,中材锡林1,GW99,1,12
|
||||
东北,中材锡林,否,中材锡林2,GW99,1,12
|
||||
东北,中材锡林,是,中材锡林3,GWBD-A2,2,12
|
||||
东北,中材锡林,是,中材锡林4,GWBD-A2,2,12
|
||||
东北,中材锡林,是,中材锡林5,GWBD-A2,2,12
|
||||
东北,中材锡林,否,中材锡林6,SI90.2,1,1
|
||||
东北,中材锡林,否,中材锡林7,SI90.2,1,1
|
||||
东北,中材兴安盟,是,中材兴安盟1,GW93,1,9
|
||||
东北,中材兴安盟,是,中材兴安盟2,GW93,1,9
|
||||
华南,中材阳江,是,中材阳江1,GW130,11,12
|
||||
华南,中材阳江,是,中材阳江2,GW130,11,12
|
||||
华南,中材阳江,否,中材阳江3,SI122,1,12
|
||||
华南,中材阳江,否,中材阳江4,SI122,1,12
|
||||
西北西部,中材伊吾,否,中材伊吾1,GWBD-A2,3,12
|
||||
西北西部,中材伊吾,否,中材伊吾2,GWBD-A2,3,12
|
||||
西北西部,中材伊吾,是,中材伊吾3,GWBD-A3,7,9
|
||||
华南,中材玉溪,否,中材玉溪1,GW93,3,3
|
||||
西北西部,重通昌吉,否,重通昌吉1,GW99,11,11
|
||||
西北西部,重通昌吉,是,重通昌吉2,GW99A,2,10
|
||||
西北西部,重通昌吉,否,重通昌吉3,GWBD-A2,1,12
|
||||
西北西部,重通昌吉,否,重通昌吉4,GWBD-A2,1,12
|
||||
西北西部,重通昌吉,否,重通昌吉5,GWBD-A2,1,12
|
||||
东北,重通大安,是,重通大安1,GWBD-A2,3,12
|
||||
东北,重通大安,是,重通大安2,GWBD-A2,4,12
|
||||
华东南北部,重通如东,是,重通如东1,GW110.5,6,10
|
||||
华东南北部,重通如东,是,重通如东2,GW110.5,6,10
|
||||
华东南北部,重通如东,否,重通如东3,GW76,1,6
|
||||
华东南北部,重通如东,否,重通如东4,GW76,1,6
|
||||
华东南北部,重通如东,否,重通如东5,GW76,11,12
|
||||
华东南北部,重通如东,否,重通如东6,GW76,11,12
|
||||
华东南北部,重通如东,否,重通如东7,GW81,1,12
|
||||
华东南北部,重通如东,否,重通如东8,GW81,1,12
|
||||
华东南北部,重通如东,否,重通如东9,GW86,10,12
|
||||
华东南北部,重通如东,否,重通如东10,GWBD-D,10,10
|
||||
华东南北部,重通如东,是,重通如东11,GW83.3,7,9
|
||||
西北东部,重通武威,否,重通武威1,GW83.4,1,1
|
||||
西北东部,重通武威,否,重通武威2,GW99A,1,1
|
||||
西北东部,重通武威,否,重通武威3,GWBD-A2,1,12
|
||||
西北东部,重通武威,否,重通武威4,GWBD-A2,1,12
|
||||
西北东部,重通武威,否,重通武威5,GWBD-A3,4,12
|
||||
西北东部,重通武威,否,重通武威6,GWBD-A3,4,12
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
区域名,工厂名,是否新工厂,产线ID,生产型号,开始月份,结束月份
|
||||
西北东部,艾郎玉门,否,艾郎玉门1,GWBD-A2,1,12
|
||||
西北东部,艾郎玉门,否,艾郎玉门2,GWBD-A2,1,12
|
||||
华北,艾郎张北,否,艾郎张北1,GWBD-A2,1,12
|
||||
华北,艾郎张北,否,艾郎张北2,GWBD-A2,1,12
|
||||
西北西部,时代巴里坤,是,时代巴里坤1,GWBD-A2,5,12
|
||||
西北西部,时代巴里坤,是,时代巴里坤2,GWBD-A2,5,12
|
||||
西北西部,时代巴里坤,是,时代巴里坤3,GW99A,3,9
|
||||
华南,时代百色,是,时代百色1,GWBD-A3,5,12
|
||||
华南,时代百色,是,时代百色2,GWBD-A3,5,12
|
||||
华东南北部,时代射阳,是,时代射阳1,GW130,9,12
|
||||
华东南北部,时代射阳,是,时代射阳2,GW130,9,12
|
||||
东北,时代松原,是,时代松原1,GWBD-A3,5,12
|
||||
东北,时代松原,是,时代松原2,GWBD-A3,5,12
|
||||
华东南南部,时代株洲,否,时代株洲1,GW99A,4,12
|
||||
华东南南部,时代株洲,否,时代株洲2,GW99A,4,12
|
||||
华东南北部,双瑞大丰,否,双瑞大丰1,GW110.5,2,11
|
||||
华东南北部,双瑞大丰,否,双瑞大丰2,GW110.5,2,11
|
||||
华东南北部,双瑞大丰,否,双瑞大丰3,GW93,1,1
|
||||
华东南北部,双瑞东营,是,双瑞东营1,GWBD-A2,9,12
|
||||
华东南北部,双瑞东营,是,双瑞东营2,GWBD-A2,9,12
|
||||
华东南北部,双瑞东营,是,双瑞东营3,GWBD-A2,9,12
|
||||
华东南北部,双瑞东营,是,双瑞东营4,GWBD-A2,9,12
|
||||
华东南北部,天顺濮阳,是,天顺濮阳1,GW99A,8,12
|
||||
华东南北部,天顺濮阳,是,天顺濮阳2,GW99A,8,12
|
||||
华东南北部,天顺沙洋,否,天顺沙洋1,GW93,2,11
|
||||
华东南北部,天顺沙洋,否,天顺沙洋2,GW99,10,11
|
||||
华东南北部,天顺沙洋,是,天顺沙洋3,GW99A,5,12
|
||||
华东南北部,天顺沙洋,是,天顺沙洋4,GW99A,5,12
|
||||
东北,中材白城,是,中材白城1,GWBD-A3,8,8
|
||||
华东南北部,中材阜宁,否,中材阜宁1,GW110.5,4,12
|
||||
华东南北部,中材阜宁,是,中材阜宁2,GW110.5,4,12
|
||||
华东南北部,中材阜宁,是,中材阜宁3,GW110.5,4,12
|
||||
华东南北部,中材阜宁,否,中材阜宁4,GW83.4,1,11
|
||||
华东南北部,中材阜宁,否,中材阜宁5,GW93,1,8
|
||||
华东南北部,中材阜宁,否,中材阜宁6,GW99A,1,7
|
||||
华东南北部,中材阜宁,否,中材阜宁7,GW99A,1,7
|
||||
华东南北部,中材阜宁,否,中材阜宁8,SI90.2,1,12
|
||||
华东南北部,中材阜宁,否,中材阜宁9,SI90.2,1,12
|
||||
华东南北部,中材阜宁,否,中材阜宁10,SI90.2,1,12
|
||||
华东南北部,中材阜宁,否,中材阜宁11,SI90.2,1,12
|
||||
华东南北部,中材阜宁,是,中材阜宁12,SI90.2,3,12
|
||||
华东南北部,中材阜宁,是,中材阜宁13,SI90.2,3,12
|
||||
西北西部,中材哈密,是,中材哈密1,GWBD-A3,7,12
|
||||
西北西部,中材哈密,是,中材哈密2,GWBD-A3,7,12
|
||||
华北,中材邯郸,否,中材邯郸1,GW99A,1,12
|
||||
华北,中材邯郸,否,中材邯郸2,GW99A,1,12
|
||||
华北,中材邯郸,是,中材邯郸3,GWBD-A2,4,12
|
||||
华北,中材邯郸,是,中材邯郸4,GWBD-A2,4,12
|
||||
西北东部,中材酒泉,否,中材酒泉1,GW99,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉2,GW99,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉3,GWBD-A2,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉4,GWBD-A2,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉5,GWBD-A2,1,12
|
||||
西北东部,中材酒泉,是,中材酒泉6,GWBD-A2,2,12
|
||||
西北东部,中材酒泉,否,中材酒泉7,SI90.2,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉8,SI90.2,1,12
|
||||
西北东部,中材酒泉,否,中材酒泉9,SI90.2,4,12
|
||||
西北东部,中材酒泉,否,中材酒泉10,SI90.2,4,12
|
||||
华东南北部,中材连云港,否,中材连云港1,GW93,4,4
|
||||
华东南北部,中材连云港,否,中材连云港2,GW93,1,12
|
||||
华东南北部,中材连云港,否,中材连云港3,GW93,1,12
|
||||
华东南南部,中材萍乡,否,中材萍乡1,GW83.4,2,6
|
||||
华东南南部,中材萍乡,否,中材萍乡2,GW93,1,10
|
||||
华东南南部,中材萍乡,否,中材萍乡3,GW93,1,10
|
||||
华东南南部,中材萍乡,否,中材萍乡4,GWBD-A3,2,12
|
||||
华东南南部,中材萍乡,否,中材萍乡5,GWBD-A3,2,12
|
||||
东北,中材锡林,否,中材锡林1,GW99,1,12
|
||||
东北,中材锡林,否,中材锡林2,GW99,1,12
|
||||
东北,中材锡林,否,中材锡林3,GWBD-A2,1,12
|
||||
东北,中材锡林,否,中材锡林4,GWBD-A2,1,12
|
||||
东北,中材锡林,是,中材锡林5,GWBD-A2,4,12
|
||||
东北,中材锡林,否,中材锡林6,SI90.2,1,1
|
||||
东北,中材锡林,否,中材锡林7,SI90.2,1,1
|
||||
东北,中材兴安盟,否,中材兴安盟1,GW93,1,9
|
||||
东北,中材兴安盟,否,中材兴安盟2,GW93,1,9
|
||||
华南,中材阳江,是,中材阳江1,GW130,11,12
|
||||
华南,中材阳江,是,中材阳江2,GW130,11,12
|
||||
华南,中材阳江,否,中材阳江3,SI122,1,12
|
||||
华南,中材阳江,否,中材阳江4,SI122,1,12
|
||||
西北西部,中材伊吾,否,中材伊吾1,GWBD-A2,3,12
|
||||
西北西部,中材伊吾,否,中材伊吾2,GWBD-A2,3,12
|
||||
西北西部,中材伊吾,是,中材伊吾3,GWBD-A3,7,9
|
||||
华南,中材玉溪,否,中复玉溪1,GW93,3,3
|
||||
西北西部,重通昌吉,否,重通昌吉1,GW99,11,11
|
||||
西北西部,重通昌吉,否,重通昌吉2,GW99A,2,10
|
||||
西北西部,重通昌吉,否,重通昌吉3,GWBD-A2,1,12
|
||||
西北西部,重通昌吉,否,重通昌吉4,GWBD-A2,1,12
|
||||
西北西部,重通昌吉,是,重通昌吉5,GWBD-A2,11,12
|
||||
东北,重通大安,是,重通大安1,GWBD-A2,3,12
|
||||
东北,重通大安,是,重通大安2,GWBD-A2,4,12
|
||||
华东南北部,重通如东,是,重通如东1,GW110.5,6,10
|
||||
华东南北部,重通如东,是,重通如东2,GW110.5,6,10
|
||||
华东南北部,重通如东,否,重通如东3,GW76,1,12
|
||||
华东南北部,重通如东,否,重通如东4,GW76,1,12
|
||||
华东南北部,重通如东,否,重通如东5,GW81,1,12
|
||||
华东南北部,重通如东,否,重通如东6,GW81,1,12
|
||||
华东南北部,重通如东,否,重通如东7,GW86,3,12
|
||||
华东南北部,重通如东,是,重通如东8,GWBD-D,6,11
|
||||
华东南北部,重通如东,否,重通如东9,GW83.3,7,9
|
||||
西北东部,重通武威,否,重通武威1,GW83.4,1,1
|
||||
西北东部,重通武威,否,重通武威2,GW99A,1,1
|
||||
西北东部,重通武威,否,重通武威3,GWBD-A2,1,12
|
||||
西北东部,重通武威,否,重通武威4,GWBD-A2,1,12
|
||||
西北东部,重通武威,否,重通武威5,GWBD-A3,4,12
|
||||
西北东部,重通武威,否,重通武威6,GWBD-A3,4,12
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
工厂,1月,2月,3月,4月,5月,6月,7月,8月,9月,10月,11月,12月,全年
|
||||
艾郎玉门,2,6,12,13,12,12,9,14,12,12,12,12,128
|
||||
艾郎张北,3,6,12,14,12,12,12,12,12,12,12,12,131
|
||||
时代巴里坤,0,0,2,4,5,9,6,16,14,13,12,12,93
|
||||
时代百色,0,0,0,0,5,9,12,12,12,12,12,12,86
|
||||
时代射阳,0,0,0,0,0,0,0,0,1,2,4,6,13
|
||||
时代松原,0,0,0,0,0,5,6,10,15,16,12,12,76
|
||||
时代株洲,0,0,0,7,9,14,14,14,14,14,14,14,114
|
||||
双瑞大丰,1,2,3,6,7,10,8,10,10,10,7,7,81
|
||||
双瑞东营,0,0,0,0,0,0,0,0,0,15,15,16,46
|
||||
天顺濮阳,2,0,0,0,0,0,0,12,11,9,10,11,55
|
||||
天顺沙洋,1,4,0,0,9,13,13,13,13,17,19,11,113
|
||||
中材白城,0,0,0,0,0,0,0,3,0,0,0,0,3
|
||||
中材阜宁,34,18,31,50,42,45,52,48,46,43,49,31,489
|
||||
中材哈密,0,0,0,0,0,0,8,9,9,6,7,0,39
|
||||
中材邯郸,12,6,3,17,18,27,18,21,23,19,20,14,198
|
||||
中材酒泉,11,20,52,56,43,45,50,53,59,52,52,40,533
|
||||
中材连云港,6,9,13,16,13,12,5,5,5,0,0,7,91
|
||||
中材萍乡,2,17,21,19,24,27,29,28,17,13,14,5,216
|
||||
中材锡林,28,6,17,25,36,32,27,36,27,30,32,21,317
|
||||
中材兴安盟,2,8,10,18,14,18,12,11,14,0,0,0,107
|
||||
中材阳江,4,1,5,5,5,5,5,5,5,5,7,7,59
|
||||
中材伊吾,0,0,10,14,5,4,8,16,16,8,15,10,106
|
||||
中材玉溪,0,0,3,0,0,0,0,0,0,0,0,0,3
|
||||
重通昌吉,13,9,19,21,22,23,23,28,27,18,23,19,245
|
||||
重通大安,0,0,2,9,6,12,11,10,11,11,13,12,97
|
||||
重通如东,24,7,24,19,23,26,27,24,30,33,34,35,306
|
||||
重通武威,22,7,14,27,31,29,29,28,30,28,29,29,303
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
工厂,1月,2月,3月,4月,5月,6月,7月,8月,9月,10月,11月,12月,全年
|
||||
艾郎玉门,2,6,12,13,12,12,9,14,12,12,12,12,128
|
||||
艾郎张北,3,6,12,14,12,12,12,12,12,12,12,12,131
|
||||
时代巴里坤,0,0,7,2,2,9,6,16,14,13,12,12,93
|
||||
时代百色,0,0,0,0,5,9,12,8,15,13,12,12,86
|
||||
时代射阳,0,0,0,0,0,0,0,0,1,0,6,6,13
|
||||
时代松原,0,0,0,0,0,6,5,10,15,16,12,12,76
|
||||
时代株洲,0,0,0,7,9,14,14,14,14,14,14,14,114
|
||||
双瑞大丰,1,2,11,6,7,10,8,10,10,10,6,0,81
|
||||
双瑞东营,0,0,0,0,0,0,0,0,3,15,14,14,46
|
||||
天顺濮阳,2,0,0,0,0,0,0,12,11,9,10,11,55
|
||||
天顺沙洋,1,4,0,0,9,13,13,13,13,17,19,11,113
|
||||
中材白城,0,0,0,0,0,0,0,3,0,0,0,0,3
|
||||
中材阜宁,34,18,31,50,42,45,52,48,46,43,49,31,489
|
||||
中材哈密,0,0,0,0,0,0,8,9,9,6,7,0,39
|
||||
中材邯郸,12,6,3,17,18,27,18,21,23,19,20,14,198
|
||||
中材酒泉,11,20,52,56,43,45,50,53,59,52,52,40,533
|
||||
中材连云港,6,9,13,16,13,12,5,5,5,0,0,7,91
|
||||
中材萍乡,2,17,21,19,24,27,29,28,17,13,14,5,216
|
||||
中材锡林,28,6,17,25,36,32,27,36,27,30,32,21,317
|
||||
中材兴安盟,2,8,10,18,14,18,12,11,14,0,0,0,107
|
||||
中材阳江,4,1,5,5,5,5,5,5,5,5,7,7,59
|
||||
中材伊吾,0,0,10,14,5,4,8,16,16,8,15,10,106
|
||||
中材玉溪,0,0,3,0,0,0,0,0,0,0,0,0,3
|
||||
重通昌吉,13,9,19,21,22,23,23,28,27,18,23,19,245
|
||||
重通大安,0,0,2,9,6,12,11,10,11,11,13,12,97
|
||||
重通如东,24,7,24,19,23,26,27,24,30,33,34,35,306
|
||||
重通武威,22,7,14,27,31,29,29,28,30,28,29,29,303
|
||||
|
|
|
@ -0,0 +1,350 @@
|
|||
生产型号,省份,市,需求区域,1月,2月,3月,4月,5月,6月,7月,8月,9月,10月,11月,12月,总量
|
||||
GW83.4,辽宁,葫芦岛市,东北,,,,,,,,,,1,,,1
|
||||
GW83.4,广西,桂林市,华南,3,,3,,,2,,,,,,,8
|
||||
GW93,广西,桂林市,华南,,2,2,,,,,,,,,,4
|
||||
GW93,广西,桂林市,华南,,,3,,,,,,,,,,3
|
||||
GW93,广西,桂林市,华南,1,3,3,,,,,,,,,,7
|
||||
GW99A,广西,玉林市,华南,1,,,,,,,,,,,,1
|
||||
GW130,江苏,盐城市,华东南北部,,,1,,,,,,,,,,1
|
||||
GW110.5,江苏,盐城市,华东南北部,,,1,2,13,12,9,20,20,17,6,,100
|
||||
GW93,江苏,盐城市,华东南北部,,,,,4,4,5,,,,,,13
|
||||
GW93,辽宁,沈阳市,东北,1,3,7,8,,,,,,,,,19
|
||||
GW93,新疆,昌吉回族自治州,西北西部,,1,12,8,10,,,,,,,,31
|
||||
SI122,广东,阳江市,华南,,,,,1,5,15,,,,,,21
|
||||
SI122,广东,阳江市,华南,,,,,,,1,,,,,,1
|
||||
SI122,广东,阳江市,华南,,,,,,5,13,4,,,,,22
|
||||
GW110.5,上海,上海市,华东,,,,4,16,8,8,,,,,,36
|
||||
GW110.5,江苏,盐城市,华东南北部,,,,,,,,,10,8,6,,24
|
||||
GW110.5,江苏,盐城市,华东南北部,,,,,8,10,2,4,,,,,24
|
||||
GW110.5,江苏,盐城市,华东南北部,,,,,,1,1,4,8,9,,,23
|
||||
GW93,广西,钦州市,华南,2,,1,,,,,,,,,,3
|
||||
GW93,广西,钦州市,华南,,1,1,1,,,,,,,,,3
|
||||
GW93,广西,钦州市,华南,2,,3,1,,,,,,,,,6
|
||||
GW93,广西,钦州市,华南,2,2,7,2,,,,,,,,,13
|
||||
GW99A,陕西,渭南市,华北,,,3,3,3,,,,,,,,9
|
||||
GW93,山西,太原市,华北,1,3,5,,,,,,,,,,9
|
||||
GW93,河南,新乡市,华东南北部,1,,,,,,,,,,,,1
|
||||
GW93,湖北,天门市,华东南北部,,,1,,,,,,,,,,1
|
||||
GW81,国际,国际,国际,1,,,,,,,,,,,,1
|
||||
GW76,国际,国际,国际,,,,,,,,,,,7,8,15
|
||||
SI90.2,国际,国际,国际,,,,,,,,4,5,4,4,,17
|
||||
SI90.2,新疆,乌鲁木齐市,西北西部,,,,,1,2,,,,,,,3
|
||||
GW93,新疆,乌鲁木齐市,西北西部,,,,3,3,2,2,3,,,,,13
|
||||
GW93,新疆,乌鲁木齐市,西北西部,,,,1,3,2,2,,,,,,8
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,,,,,,,5,2,9,,16
|
||||
GW99A,内蒙古,鄂尔多斯市,华北,,,,,,,,,,,5,6,11
|
||||
GW93,河北,承德市,华北,6,5,1,,,,,,,,,,12
|
||||
GWBD-A2,河北,承德市,华北,1,,,2,,,1,1,,,5,3,13
|
||||
GWBD-A2,河北,张家口市,华北,1,,,2,2,1,5,2,,,,1,14
|
||||
GWBD-A2,河北,张家口市,华北,,,,,,,,,,,,3,3
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,,,,,,1,,1
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,2,6,2,4,5,2,4,9,21,55
|
||||
GW93,广西,钦州市,华南,,,1,1,1,1,1,,,,,,5
|
||||
GW93,广西,钦州市,华南,2,1,4,2,2,4,1,,,,,,16
|
||||
GW93,辽宁,朝阳市,东北,,,3,3,2,4,2,5,5,5,8,5,42
|
||||
GW93,辽宁,朝阳市,东北,,,,2,1,1,,,1,2,4,3,14
|
||||
GW93,贵州,黔东南苗族侗族自治州,华南,1,,3,3,4,3,2,,,,,,16
|
||||
GW99A,湖北,荆门市,华东南北部,,,,,,,,,,2,6,8,16
|
||||
GW99A,湖北,荆门市,华东南北部,,,,,,2,4,4,6,3,8,,27
|
||||
GWBD-A3,辽宁,朝阳市,东北,,,,,1,,,,,,,,1
|
||||
GW93,辽宁,朝阳市,东北,,,2,5,2,9,2,3,2,,,,25
|
||||
SI90.2,国际,国际,国际,,7,,9,,,,,,,,,16
|
||||
GW93,内蒙古,通辽市,华北,,,,,,,,,,,,3,3
|
||||
GW93,黑龙江,哈尔滨市,东北,1,,,,,,,,,,,,1
|
||||
GW99A,辽宁,鞍山市,东北,1,,3,,2,1,1,1,1,,,,10
|
||||
GW93,重庆,重庆市,华南,,,,2,,,,,,,,,2
|
||||
GW93,重庆,重庆市,华南,,,1,4,,,,,,,,,5
|
||||
GW99A,天津,天津市,华北,1,2,,,,,,,,,,,3
|
||||
GW93,天津,天津市,华北,,2,1,,,,,,,,,,3
|
||||
GW99A,河北,秦皇岛市,华北,,,1,1,1,5,,,,,,,8
|
||||
GW93,河北,秦皇岛市,华北,,,,1,1,,,,,,,,2
|
||||
GW93,贵州,黔西南布依族苗族自治州,华南,,,4,3,,,1,,,,1,1,10
|
||||
GW93,贵州,黔南布依族苗族自治州,华南,1,,,,,,,,,,,,1
|
||||
GW99A,河南,济源市,华东南北部,,,,2,1,,,,3,,,1,7
|
||||
GW83.4,国际,国际,国际,4,,6,4,,,,,,,,,14
|
||||
GW99A,甘肃,定西市,西北东部,,,2,2,1,,,,,1,4,3,13
|
||||
GW99,黑龙江,七台河市,东北,4,4,1,,,,,,,,,,9
|
||||
GWBD-A3,湖北,黄冈市,华东南北部,,,,,,,,,,,,2,2
|
||||
GW99A,黑龙江,绥化市,东北,,,,2,2,5,2,,,,,,11
|
||||
GW99,天津,天津市,华北,,,,,,,,,,,,1,1
|
||||
GWBD-A3,天津,天津市,华北,,,,,,,,,,,,1,1
|
||||
GWBD-A3,天津,天津市,华北,,,,,,,,,,,,1,1
|
||||
GW81,国际,国际,国际,,,,,,,8,8,4,,4,8,32
|
||||
GW99A,河南,南阳市,华东南北部,,,2,1,,,,,,,,,3
|
||||
GW99,河南,南阳市,华东南北部,2,,1,2,1,,,,,,,,6
|
||||
GW99A,安徽,阜阳市,华东南北部,,,,,,,,,2,2,2,2,8
|
||||
GW93,贵州,毕节市,华南,,,,,2,,,,,,,,2
|
||||
GW99,贵州,毕节市,华南,,,2,3,1,2,,,,,,,8
|
||||
GW83.4,黑龙江,哈尔滨市,东北,2,,2,5,1,,,,,,,,10
|
||||
GW99A,河南,开封市,华东南北部,2,,,,,,,,,,,,2
|
||||
GW99A,广西,玉林市,华南,,,,,,,,,1,,,,1
|
||||
GW99,广西,玉林市,华南,,,,,,,,,,1,2,1,4
|
||||
GW99A,甘肃,定西市,西北东部,,,1,1,6,3,1,5,1,,,,18
|
||||
GW99,河南,商丘市,华东南北部,,,,,,,,2,3,4,5,1,15
|
||||
GW99A,河南,三门峡市,华东南北部,6,,,,,,,,,,,,6
|
||||
GWBD-A2,新疆,哈密市,西北西部,,3,7,6,,6,6,5,3,3,9,,48
|
||||
GWBD-A2,新疆,塔城地区,西北西部,,,,,,,4,12,10,19,,,45
|
||||
GW93,新疆,塔城地区,西北西部,,,,,,4,14,2,1,,,,21
|
||||
GWBD-A2,新疆,塔城地区,西北西部,,,,,,4,8,8,4,,,,24
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,,,,,,,1,1
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,,,,,,,1,1
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,,,,,,,5,5
|
||||
GW83.4,辽宁,鞍山市,东北,,,,1,,,,,,,,,1
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,5,8,3,,,,,,,,16
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,,2,3,,,,,,,,5
|
||||
GW93,内蒙古,呼和浩特市,华北,,,,,,4,,,1,,,,5
|
||||
GW99A,广西,钦州市,华南,7,6,1,2,2,,,,,,,,18
|
||||
GW99A,黑龙江,七台河市,东北,,,,,1,4,8,10,9,,,,32
|
||||
GWBD-A2,河北,张家口市,华北,,,,,,,,,,1,4,,5
|
||||
GWBD-A2,河北,张家口市,华北,,,,,,,,,,,4,3,7
|
||||
GW99,河南,安阳市,华东南北部,1,1,3,3,2,3,3,1,,,,,17
|
||||
GW99A,河南,安阳市,华东南北部,,1,,2,3,3,1,1,1,,,,12
|
||||
GWBD-A2,甘肃,酒泉市,西北东部,,,5,4,4,6,5,6,,,,,30
|
||||
GWBD-A2,甘肃,酒泉市,西北东部,,,,,,,3,3,,,,,6
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,5,13,37,11,24,,,,,90
|
||||
GW99A,贵州,黔西南布依族苗族自治州,华南,,,,1,1,,,1,,,,3,6
|
||||
GWBD-A2,吉林,松原市,东北,,1,2,1,1,1,2,,,,,,8
|
||||
GWBD-A2,吉林,松原市,东北,3,6,7,10,20,5,5,,,,,,56
|
||||
GWBD-A2,河北,承德市,华北,2,,,,,,,,,,,,2
|
||||
GW83.4,辽宁,鞍山市,东北,,,,,1,,,,,,,,1
|
||||
GW99A,江西,赣州市,华东南南部,1,,3,3,9,,,,,,,,16
|
||||
GWBD-A3,广西,钦州市,华南,,,,,,,,,,,,4,4
|
||||
GW99A,湖北,恩施土家族苗族自治州,华东南北部,,1,3,3,1,,,,,,,,8
|
||||
GW99A,湖南,永州市,华东南南部,,,,1,,1,1,,1,1,2,2,9
|
||||
GW99A,河北,邢台市,华北,,,,,1,4,7,5,5,7,11,9,49
|
||||
GWBD-A2,河北,邢台市,华北,,,,,,,,,,,2,,2
|
||||
GW99A,重庆,重庆市,华南,,,,,,,,2,,2,1,,5
|
||||
GW99A,河南,新乡市,华东南北部,,,,2,5,2,2,2,2,,1,,16
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,,3,9,1,5,2,,,,,20
|
||||
GW99,新疆,昌吉回族自治州,西北西部,,,,3,2,4,9,2,6,1,,,27
|
||||
GWBD-A2,河北,张家口市,华北,,,,4,1,,,,,,,,5
|
||||
GWBD-A2,河北,张家口市,华北,,,,,1,,,,,,,,1
|
||||
GW99,广西,来宾市,华南,,,4,8,9,15,2,,,,,,38
|
||||
GWBD-A3,黑龙江,鹤岗市,东北,,,,,3,9,7,8,3,,,,30
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,8,,15,15,10,5,32,15,,,100
|
||||
SI90.2,国际,国际,国际,,,9,,11,,5,6,8,8,11,,58
|
||||
GW81,国际,国际,国际,3,,10,10,9,,,,,,,,32
|
||||
GW81,国际,国际,国际,,8,,,,9,,,,,,,17
|
||||
SI90.2,国际,国际,国际,,,5,,,,,,,,,,5
|
||||
GW83.4,国际,国际,国际,,,,,,5,8,8,,8,4,,33
|
||||
GWBD-A2,吉林,通化市,东北,,,,,3,1,,,,,,,4
|
||||
GW99,吉林,通化市,东北,,,,,1,,,,,,,,1
|
||||
GWBD-A2,河北,秦皇岛市,华北,,,,,,,1,,,,3,4,8
|
||||
GW99A,甘肃,白银市,西北东部,4,,2,7,,,,,,,,,13
|
||||
GW99A,甘肃,白银市,西北东部,,,,12,4,,,,,,,,16
|
||||
GW81,国际,国际,国际,,,4,,,,,,,,,,4
|
||||
GWBD-A3,天津,天津市,华北,,,,,,,,,5,1,,,6
|
||||
GW93,天津,天津市,华北,,,,,,,1,1,,,,,2
|
||||
GW99,河北,承德市,华北,1,1,,,1,,,,,,,,3
|
||||
GW99,河北,承德市,华北,2,,2,2,7,,,,,,,,13
|
||||
SI122,福建,莆田市,华东南南部,,,,,,3,7,2,,,,,12
|
||||
GW130,广东,阳江市,华南,,,,,,,,,,3,3,1,7
|
||||
GW93,河北,承德市,华北,,,,,,2,1,,,,,,3
|
||||
SI90.2,河北,承德市,华北,1,,4,2,,10,3,,1,,,,21
|
||||
GW93,河北,承德市,华北,,,2,1,3,,,,,,,,6
|
||||
SI90.2,河北,承德市,华北,3,,3,,8,,,,,,,,14
|
||||
GW81,国际,国际,国际,,,,,,,2,,,,,,2
|
||||
GWBD-A3,河南,洛阳市,华东南北部,,1,2,,,,,,,,,,3
|
||||
GW99A,山西,晋中市,华北,,,,,,,,,,,2,1,3
|
||||
GW99,山西,晋中市,华北,,,,,,,,,,,2,3,5
|
||||
GWBD-A2,黑龙江,佳木斯市,东北,6,3,3,,,6,5,5,,1,3,4,36
|
||||
GWBD-A2,宁夏,吴忠市,西北东部,1,,,,,,,,,,,,1
|
||||
SI90.2,国际,国际,国际,,,,,,,,,8,10,8,,26
|
||||
SI90.2,国际,国际,国际,10,,,,,,,,,,,,10
|
||||
GW81,国际,国际,国际,,,,,,,7,,,,,,7
|
||||
GW83.3,国际,国际,国际,,,,,,,,,5,,,,5
|
||||
GW93,山西,运城市,华北,,,,,,,,,,,,4,4
|
||||
GWBD-A2,山西,朔州市,华北,,,,,,,,,,2,8,3,13
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,1,4,8,3,8,,,24
|
||||
GW99,新疆,伊犁哈萨克自治州,西北西部,,,12,5,8,6,6,,11,7,10,,65
|
||||
GWBD-A2,云南,昆明市,华南,,,,,,,,,,,2,2,4
|
||||
GW93,陕西,渭南市,华北,1,2,2,,,,,,,,,,5
|
||||
GWBD-A2,山西,忻州市,华北,,,,,,,,,1,3,6,3,13
|
||||
GWBD-A2,山西,大同市,华北,,,,1,,2,,2,1,3,3,,12
|
||||
GW76,国际,国际,国际,2,,,,,,,,,,,,2
|
||||
GW99,内蒙古,鄂尔多斯市,华北,,,,,,3,5,2,1,4,10,5,30
|
||||
GW76,国际,国际,国际,1,,,,,,,,,,,,1
|
||||
GWBD-A2,新疆,乌鲁木齐市,西北西部,,,,6,7,,,,,,,,13
|
||||
GW99,青海,海南藏族自治州,西北东部,,,,,,,,2,3,,,,5
|
||||
GW76,国际,国际,国际,7,,,,,,,,,,,,7
|
||||
GWBD-A3,贵州,毕节市,华南,,,,2,1,2,,1,,,,,6
|
||||
GWBD-A2,甘肃,庆阳市,西北东部,,,,,2,,,,,,,,2
|
||||
SI90.2,新疆,吐鲁番地区,西北西部,5,,,,,,,,,,,,5
|
||||
GW93,辽宁,沈阳市,东北,,,1,,,,,,,,,,1
|
||||
GWBD-A2,内蒙古,兴安盟,东北,,,,,1,3,2,2,3,4,5,,20
|
||||
GWBD-A2,内蒙古,兴安盟,东北,,,,,,,,,3,,1,,4
|
||||
GWBD-A2,内蒙古,兴安盟,东北,,,,1,8,6,1,3,,,,,19
|
||||
GWBD-A2,内蒙古,兴安盟,东北,,,,,,4,,,,,,,4
|
||||
GWBD-A2,辽宁,锦州市,东北,,,,,,1,,,,,,,1
|
||||
GW76,国际,国际,国际,,,,4,,,,,,,,,4
|
||||
GW86,国际,国际,国际,,8,,,,,,,,,,,8
|
||||
GW76,国际,国际,国际,3,,,,,,,,,,,,3
|
||||
GW81,国际,国际,国际,,,,5,,,,,,,,,5
|
||||
GW76,国际,国际,国际,7,,,,,,,,,,,,7
|
||||
GW76,国际,国际,国际,,,,7,,,,,,,,,7
|
||||
SI90.2,国际,国际,国际,,,,7,10,,10,5,,,,,32
|
||||
SI90.2,国际,国际,国际,,7,16,10,,,,15,12,,,,60
|
||||
GW83.4,国际,国际,国际,14,7,,,,7,6,,,,,,34
|
||||
GW76,国际,国际,国际,,,,,,4,,,,,,,4
|
||||
GW81,国际,国际,国际,,,,,,,1,,,,,,1
|
||||
GW130,广东,阳江市,华南,,,,,,,,,,5,10,10,25
|
||||
GW81,国际,国际,国际,,,,,,10,,5,,10,,,25
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,,8,7,2,6,5,15,43
|
||||
SI90.2,新疆,吐鲁番地区,西北西部,,,,,1,4,7,12,3,15,14,,56
|
||||
GW99A,甘肃,酒泉市,西北东部,,,,,,,,,,3,9,3,15
|
||||
GWBD-A2,内蒙古,通辽市,华北,2,2,5,4,4,,,,,,,,17
|
||||
GW99A,河北,邢台市,华北,,,,1,3,2,3,5,1,1,,,16
|
||||
GW99,重庆,重庆市,华南,,,,,,,,,,3,,2,5
|
||||
GWBD-A2,重庆,重庆市,华南,,,,,,,,,1,4,2,,7
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,,,,,2,5,2,5,4,,18
|
||||
GWBD-A2,内蒙古,锡林郭勒盟,华北,,,4,4,,,,,,,,,8
|
||||
GWBD-A3,山东,聊城市,华东南北部,,,,,,,1,2,4,5,8,,20
|
||||
GWBD-A2,新疆,巴音郭楞蒙古自治州,西北西部,1,,,,,,,,,,,,1
|
||||
GWBD-A2,新疆,塔城地区,西北西部,,,,,,3,8,12,7,7,13,,50
|
||||
GW93,天津,天津市,华北,,,1,7,2,,,,,,,,10
|
||||
GWBD-A3,广西,梧州市,华南,,,,1,3,6,2,8,8,,,,28
|
||||
SI90.2,国际,国际,国际,,,,,9,,,,9,,,7,25
|
||||
GWBD-A2,新疆,乌鲁木齐市,西北西部,,,,,,,2,3,6,6,3,4,24
|
||||
SI90.2,国际,国际,国际,,,,,,,,,,,2,,2
|
||||
GW93,吉林,白城市,东北,,,,,,,,,,,,2,2
|
||||
GW110.5,江苏,盐城市,华东南北部,,,,,1,,6,6,,,,,13
|
||||
SI122,江苏,盐城市,华东南北部,,,,,,,1,,,,,,1
|
||||
GWBD-A2,内蒙古,乌兰察布市,华北,,2,3,5,6,2,8,,,,,,26
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,2,16,11,6,12,8,30,25,,,110
|
||||
GW99,广西,河池市,华南,,,,,,,,,2,1,,,3
|
||||
GW99A,广西,河池市,华南,,,,,,,,,2,3,,1,6
|
||||
GWBD-A3,宁夏,吴忠市,西北东部,,,,,,,,1,3,,2,,6
|
||||
GWBD-A3,新疆,昌吉回族自治州,西北西部,,,5,7,11,10,10,2,7,7,1,,60
|
||||
GW99,内蒙古,锡林郭勒盟,华北,,,,,,,,7,,,,,7
|
||||
GW99,内蒙古,锡林郭勒盟,华北,,,,,,,3,,,,,,3
|
||||
GW99,内蒙古,锡林郭勒盟,华北,,,,,,,,5,12,,,,17
|
||||
GW99,内蒙古,锡林郭勒盟,华北,,,,,,,,,3,10,3,1,17
|
||||
GWBD-A2,山东,济南市,华东南北部,,,,,,,1,,,,,,1
|
||||
GWBD-A3,山东,济南市,华东南北部,,,2,5,3,2,2,6,7,1,4,,32
|
||||
GWBD-A2,山东,济南市,华东南北部,,,,,,,5,3,,,,,8
|
||||
GWBD-A2,山东,济南市,华东南北部,,,,1,2,,,,,,,,3
|
||||
GWBD-A3,山东,济南市,华东南北部,,,2,3,1,,,,,,,,6
|
||||
GWBD-A2,内蒙古,锡林郭勒盟,华北,,,,1,2,1,1,,,,,,5
|
||||
GW99,云南,昆明市,华南,,,,,,,,,,,1,2,3
|
||||
GWBD-A2,新疆,新疆生产建设兵团第十师,西北西部,,,,,1,7,1,1,,,,,10
|
||||
GWBD-A2,新疆,阿勒泰地区,西北西部,,,5,16,21,,,1,2,,,,45
|
||||
GWBD-A3,广西,百色市,华南,,,,,,,,,,,6,6,12
|
||||
GW99,新疆,昌吉回族自治州,西北西部,,,10,12,,,,,,,,,22
|
||||
GWBD-A3,新疆,昌吉回族自治州,西北西部,,,,2,,,,,,,,,2
|
||||
GWBD-A2,内蒙古,兴安盟,东北,,,,,,,,,,,3,4,7
|
||||
GWBD-A2,内蒙古,兴安盟,东北,,,,,,,,,,,3,3,6
|
||||
GWBD-A3,新疆,昌吉回族自治州,西北西部,,,,,2,8,9,13,14,20,9,,75
|
||||
GW99,河北,张家口市,华北,,,,,,,,,,,5,3,8
|
||||
GWBD-A3,湖北,荆州市,华东南北部,,,,,,,,,,,,2,2
|
||||
GW99A,河北,衡水市,华北,,,,,,,,,2,3,3,2,10
|
||||
GWBD-A3,河北,邢台市,华北,,,,,,,,,1,4,4,3,12
|
||||
GW99A,陕西,延安市,华北,,,,2,2,,,,,,,,4
|
||||
GW81,国际,国际,国际,,,,,,9,11,9,11,,11,,51
|
||||
SI90.2,国际,国际,国际,,,,,,,,,9,,,9,18
|
||||
GWBD-A2,内蒙古,锡林郭勒盟,华北,,,,,,,,,1,3,8,,12
|
||||
SI90.2,新疆,塔城地区,西北西部,,,,,,,,,4,,,,4
|
||||
GW99A,湖北,荆门市,华东南北部,,,,,,2,4,4,4,3,1,,18
|
||||
GWBD-A2,内蒙古,锡林郭勒盟,华北,,,,,,,1,5,12,9,3,,30
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,3,1,1,,,1,,6
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,,7,1,,,,,8
|
||||
GWBD-A3,山西,朔州市,华北,,,3,,,,,,,,,,3
|
||||
GWBD-A2,宁夏,中卫市,西北东部,,,,,,1,5,7,5,,,,18
|
||||
GWBD-A3,宁夏,中卫市,西北东部,,,,,,,4,4,7,,,,15
|
||||
GWBD-A2,宁夏,中卫市,西北东部,,,,,,,,2,3,,,,5
|
||||
GWBD-A3,宁夏,中卫市,西北东部,,,,,,,,1,2,,,,3
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,,,,,,4,,4
|
||||
GW99A,河北,秦皇岛市,华北,,,,,,,,1,4,2,3,,10
|
||||
GW93,辽宁,沈阳市,东北,,,,,1,,,,,,,,1
|
||||
GW81,国际,国际,国际,,,,,,,3,,,,,,3
|
||||
SI90.2,国际,国际,国际,,,,,,,6,5,3,3,,,17
|
||||
SI90.2,国际,国际,国际,,,,1,,,,,,,,,1
|
||||
GWBD-A2,新疆,塔城地区,西北西部,,,,4,8,8,13,8,13,13,,,67
|
||||
GW93,陕西,榆林市,华北,,,2,,,,,,,,,,2
|
||||
SI90.2,国际,国际,国际,,,,,,,,,9,,,,9
|
||||
GWBD-A3,河北,邯郸市,华北,,,,1,1,2,,,,,,,4
|
||||
GWBD-A2,河北,邯郸市,华北,,,,1,1,,1,,,,,,3
|
||||
SI90.2,国际,国际,国际,,,,,,6,,6,6,4,,,22
|
||||
GWBD-A3,宁夏,吴忠市,西北东部,,,,,,,,,2,1,2,,5
|
||||
GWBD-A3,宁夏,吴忠市,西北东部,,,,,,,,,,2,,,2
|
||||
GW99A,河北,沧州市,华北,,,,,1,3,1,2,1,,,,8
|
||||
GW99A,天津,天津市,华北,,,,1,4,,,,,,,,5
|
||||
GWBD-A3,宁夏,中卫市,西北东部,,,,,,,,,,,6,4,10
|
||||
GW83.4,国际,国际,国际,,,,7,,,,,,,,,7
|
||||
GW76,国际,国际,国际,,,,,,,10,,,,,,10
|
||||
SI90.2,国际,国际,国际,,,,,,,,,,,1,,1
|
||||
GWBD-A3,河北,邢台市,华北,,,,,,,,,4,4,4,,12
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,,,,,1,6,10,4,21,,42
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,,,,,,3,11,11,20,,45
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,,,,,2,11,3,16
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,,,,,,2,2,4
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,,,,2,2,1,,5
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,,,,1,,,,1
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,,,,4,5,6,5,20
|
||||
GWBD-A2,内蒙古,通辽市,华北,,,,,,,,,,,2,2,4
|
||||
GW99,新疆,乌鲁木齐市,西北西部,,,,2,,,,,,,,,2
|
||||
GW99,新疆,乌鲁木齐市,西北西部,,,,3,,,,,,,,,3
|
||||
GWBD-A3,河北,衡水市,华北,,,,1,2,3,2,,,,,,8
|
||||
GWBD-A2,新疆,塔城地区,西北西部,,,,,,,10,8,16,11,5,,50
|
||||
GWBD-A2,黑龙江,绥化市,东北,,,,,,,,,,,3,2,5
|
||||
GW93,天津,天津市,华北,,,,,4,,,,,,,,4
|
||||
GWBD-A2,内蒙古,兴安盟,东北,,,,,,,,,,1,13,11,25
|
||||
GWBD-A2,新疆,乌鲁木齐市,西北西部,,,,,,,,,,,2,3,5
|
||||
GWBD-A3,山西,大同市,华北,,,,,,,,3,6,10,5,,24
|
||||
GWBD-D,辽宁,朝阳市,东北,,,,,,,,,,,1,,1
|
||||
GW99A,辽宁,辽阳市,东北,,,,,,,,,,,,2,2
|
||||
GWBD-A2,辽宁,锦州市,东北,,,,,,,,,,,1,,1
|
||||
GW99,河北,张家口市,华北,,,,,,,,,,,1,,1
|
||||
GWBD-A3,河北,张家口市,华北,,,,,,,,,,,1,,1
|
||||
GW83.4,国际,国际,国际,,,,,,3,,,,,,,3
|
||||
GW93,内蒙古,锡林郭勒盟,华北,,,,2,,,,,,,,,2
|
||||
GWBD-A3,山东,德州市,华东南北部,,,,,,,,,,,,4,4
|
||||
GWBD-A3,河北,邢台市,华北,,,,,,1,,,,5,5,5,16
|
||||
GWBD-A3,河北,邢台市,华北,,,,,,,,,,,4,4,8
|
||||
GWBD-A3,河北,邢台市,华北,,,,,,,,,,,2,3,5
|
||||
GWBD-A3,河北,邢台市,华北,,,,,,,,,,,,1,1
|
||||
GWBD-D,陕西,渭南市,华北,,,,,,,,1,2,,1,,4
|
||||
GW83.4,江苏,镇江市,华东南北部,,,,,,,,,1,,,,1
|
||||
GW99A,湖北,恩施土家族苗族自治州,华东南北部,,,,,,,,1,4,3,3,2,13
|
||||
GW99A,山东,聊城市,华东南北部,,,,,,,,,,,5,5,10
|
||||
GW81,国际,国际,国际,,,,,,,1,,,,,,1
|
||||
GWBD-A3,河北,衡水市,华北,,,,,,,,,2,3,6,8,19
|
||||
GWBD-A3,河北,衡水市,华北,,,,,,,4,3,4,3,2,,16
|
||||
GWBD-A2,新疆,乌鲁木齐市,西北西部,,,,,6,,,,,,,,6
|
||||
GW99A,天津,天津市,华北,,,,,,,,,4,2,,,6
|
||||
GW99,天津,天津市,华北,,,,,,,,,,1,,,1
|
||||
GW93,内蒙古,兴安盟,东北,,,,,,,4,3,3,,,,10
|
||||
GW99A,河北,沧州市,华北,,,,,,,,,,,,7,7
|
||||
GWBD-D,河北,张家口市,华北,,,,,,,,,,2,,,2
|
||||
SI90.2,国际,国际,国际,,,,,,,,,,,,10,10
|
||||
GWBD-A3,河北,沧州市,华北,,,,,1,2,5,,,,,,8
|
||||
GWBD-A3,河北,邢台市,华北,,,,,,,,,,,2,4,6
|
||||
GWBD-A2,新疆,哈密市,西北西部,,,,,,,,,,,2,4,6
|
||||
GW81,国际,国际,国际,,,,,,,,,1,,,,1
|
||||
GW83.4,国际,国际,国际,,,,,,,,,,,1,,1
|
||||
GW99,新疆,乌鲁木齐市,西北西部,,,,,,,,,4,4,3,,11
|
||||
GWBD-A2,新疆,阿勒泰地区,西北西部,,,,,,,,1,,6,18,,25
|
||||
GWBD-A2,新疆,阿勒泰地区,西北西部,,,,,,,,1,,7,24,8,40
|
||||
SI90.2,国际,国际,国际,,,,,,,,,,,1,,1
|
||||
GWBD-A2,内蒙古,鄂尔多斯市,华北,,,,,,,,,,,1,,1
|
||||
GW99A,河北,张家口市,华北,,,,,,,,,1,1,,,2
|
||||
GWBD-D,辽宁,本溪市,东北,,,,,,,,,,1,,,1
|
||||
GW99,云南,曲靖市,华南,,,,,,,,,,,6,10,16
|
||||
GW93,新疆,巴音郭楞蒙古自治州,西北西部,,,,,,,,,,,,1,1
|
||||
GW99,甘肃,酒泉市,西北东部,,,,,,,,,,,1,,1
|
||||
GW93,山东,济宁市,华东南北部,,,,,,,,,,,,2,2
|
||||
GW99,新疆,巴音郭楞蒙古自治州,西北西部,,,,,1,,,,,,,,1
|
||||
GWBD-A3,甘肃,庆阳市,西北东部,,,,,,,,,,,,2,2
|
||||
GW93,天津,天津市,华北,,,,,,,,,,,,1,1
|
||||
GWBD-A2,黑龙江,哈尔滨市,东北,,,,,,,,,,,,2,2
|
||||
GW83.4,国际,国际,国际,,,,,,,,,,,1,,1
|
||||
GW99A,贵州,铜仁市,华南,,,,,,,,,,,2,2,4
|
||||
GWBD-A2,河北,张家口市,华北,,,,,,,,,,,,2,2
|
||||
GWBD-A2,河北,张家口市,华北,,,,,,,,,,,,10,10
|
||||
GWBD-A2,辽宁,朝阳市,东北,,,,,,,,,,,1,,1
|
||||
SI90.2,新疆,昌吉回族自治州,西北西部,,,,,,,,,,,1,,1
|
||||
GWBD-A2,新疆,昌吉回族自治州,西北西部,,,,,,,,,1,,,,1
|
||||
GW83.3,新疆,昌吉回族自治州,西北西部,,,,,,,,,1,,,,1
|
||||
GWBD-A2,青海,海西蒙古族藏族自治州,西北东部,,,,,,,,,,,,4,4
|
||||
GWBD-A2,山东,烟台市,华东南北部,,,,,,,,,,,,1,1
|
||||
GW99,内蒙古,通辽市,华北,,,,,,,,,,,,1,1
|
||||
GW99,内蒙古,锡林郭勒盟,华北,,,,,,,,,,,,1,1
|
||||
|
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"艾郎玉门": "AilangYumen",
|
||||
"艾郎张北": "AilangZhangbei",
|
||||
"时代巴里坤": "ShidaiBalikun",
|
||||
"时代百色": "ShidaiBaise",
|
||||
"时代射阳": "ShidaiSheyang",
|
||||
"时代松原": "ShidaiSongyuan",
|
||||
"时代株洲": "ShidaiZhuzhou",
|
||||
"双瑞大丰": "ShuangruiDafeng",
|
||||
"双瑞东营": "ShuangruiDongying",
|
||||
"天顺濮阳": "TianshunPuyang",
|
||||
"天顺沙洋": "TianshunShayang",
|
||||
"中材白城": "ZhongcaiBaicheng",
|
||||
"中材阜宁": "ZhongcaiFuning",
|
||||
"中材哈密": "ZhongcaiHami",
|
||||
"中材邯郸": "ZhongcaiHandan",
|
||||
"中材酒泉": "ZhongcaiJiuquan",
|
||||
"中材连云港": "ZhongcaiLianyungang",
|
||||
"中材萍乡": "ZhongcaiPingxiang",
|
||||
"中材锡林": "ZhongcaiXilin",
|
||||
"中材兴安盟": "ZhongcaiXinganmeng",
|
||||
"中材阳江": "ZhongcaiYangjiang",
|
||||
"中材伊吾": "ZhongcaiYiwu",
|
||||
"中材玉溪": "ZhongcaiYuxi",
|
||||
"重通昌吉": "ChongtongChangji",
|
||||
"重通大安": "ChongtongDaan",
|
||||
"重通如东": "ChongtongRudong",
|
||||
"重通武威": "ChongtongWuwei"
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"best_score": 0.013780913115116374,
|
||||
"month1": 235.2024236560018,
|
||||
"month2": 80.13430957369465,
|
||||
"month3": 40.81815120444523,
|
||||
"month4": 35.573307322844045,
|
||||
"factor_AilangYumen": 1.1209670325377996,
|
||||
"factor_AilangZhangbei": 1.0869751796074336,
|
||||
"factor_ShidaiBalikun": 1.064344356385733,
|
||||
"factor_ShidaiBaise": 0.925644739081089,
|
||||
"factor_ShidaiSheyang": 2.2354053357800834,
|
||||
"factor_ShidaiSongyuan": 0.8850280359740502,
|
||||
"factor_ShidaiZhuzhou": 0.8,
|
||||
"factor_ShuangruiDafeng": 1.3485391587995974,
|
||||
"factor_ShuangruiDongying": 1.4720254802974653,
|
||||
"factor_TianshunPuyang": 1.1166692701637255,
|
||||
"factor_TianshunShayang": 1.060367420503057,
|
||||
"factor_ZhongcaiBaicheng": 1.8461095046937892,
|
||||
"factor_ZhongcaiFuning": 1.3124938381864457,
|
||||
"factor_ZhongcaiHami": 1.4843503931169255,
|
||||
"factor_ZhongcaiHandan": 1.210604184057787,
|
||||
"factor_ZhongcaiJiuquan": 0.9798174978126551,
|
||||
"factor_ZhongcaiLianyungang": 1.6036280376162886,
|
||||
"factor_ZhongcaiPingxiang": 1.132040522281658,
|
||||
"factor_ZhongcaiXilin": 1.0297971770720127,
|
||||
"factor_ZhongcaiXinganmeng": 0.9769716839603864,
|
||||
"factor_ZhongcaiYangjiang": 2.386768108574698,
|
||||
"factor_ZhongcaiYiwu": 1.2417395146436796,
|
||||
"factor_ZhongcaiYuxi": 1.7093165019081604,
|
||||
"factor_ChongtongChangji": 1.0895870479908367,
|
||||
"factor_ChongtongDaan": 1.0187316107483142,
|
||||
"factor_ChongtongRudong": 1.0270541553649646,
|
||||
"factor_ChongtongWuwei": 0.8811374580269447
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"best_score": 0.013780913115116374,
|
||||
"factor_ZhongcaiBaicheng": 1.8461095046937892,
|
||||
"factor_ZhongcaiHami": 1.4843503931169255
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"holiday_days_1": 5,
|
||||
"holiday_days_2": 12,
|
||||
"holiday_days_3": 2,
|
||||
"holiday_days_4": 2,
|
||||
"holiday_days_5": 2,
|
||||
"holiday_days_6": 2,
|
||||
"holiday_days_7": 2,
|
||||
"holiday_days_8": 2,
|
||||
"holiday_days_9": 2,
|
||||
"holiday_days_10": 7,
|
||||
"holiday_days_11": 2,
|
||||
"holiday_days_12": 2,
|
||||
"month1": 235.2024236560018,
|
||||
"month2": 80.13430957369465,
|
||||
"month3": 40.81815120444523,
|
||||
"month4": 35.573307322844045,
|
||||
"factor_AilangYumen": 1.1209670325377996,
|
||||
"factor_AilangZhangbei": 1.0869751796074336,
|
||||
"factor_ShidaiBalikun": 1.064344356385733,
|
||||
"factor_ShidaiBaise": 0.925644739081089,
|
||||
"factor_ShidaiSheyang": 2.2354053357800834,
|
||||
"factor_ShidaiSongyuan": 0.8850280359740502,
|
||||
"factor_ShidaiZhuzhou": 0.8,
|
||||
"factor_ShuangruiDafeng": 1.3485391587995974,
|
||||
"factor_ShuangruiDongying": 1.4720254802974653,
|
||||
"factor_TianshunPuyang": 1.1166692701637255,
|
||||
"factor_TianshunShayang": 1.060367420503057,
|
||||
"factor_ZhongcaiBaicheng": 1.8461095046937892,
|
||||
"factor_ZhongcaiFuning": 1.3124938381864457,
|
||||
"factor_ZhongcaiHami": 1.4843503931169255,
|
||||
"factor_ZhongcaiHandan": 1.210604184057787,
|
||||
"factor_ZhongcaiJiuquan": 0.9798174978126551,
|
||||
"factor_ZhongcaiLianyungang": 1.6036280376162886,
|
||||
"factor_ZhongcaiPingxiang": 1.132040522281658,
|
||||
"factor_ZhongcaiXilin": 1.0297971770720127,
|
||||
"factor_ZhongcaiXinganmeng": 0.9769716839603864,
|
||||
"factor_ZhongcaiYangjiang": 2.386768108574698,
|
||||
"factor_ZhongcaiYiwu": 1.2417395146436796,
|
||||
"factor_ZhongcaiYuxi": 1.7093165019081604,
|
||||
"factor_ChongtongChangji": 1.0895870479908367,
|
||||
"factor_ChongtongDaan": 1.0187316107483142,
|
||||
"factor_ChongtongRudong": 1.0270541553649646,
|
||||
"factor_ChongtongWuwei": 0.8811374580269447,
|
||||
"product_set": [
|
||||
"GWBD-A2",
|
||||
"GWBD-A3",
|
||||
"SI90.2",
|
||||
"GW99A",
|
||||
"GW110.5",
|
||||
"GW93",
|
||||
"GW130",
|
||||
"GW76",
|
||||
"GW99",
|
||||
"GW81",
|
||||
"GW86",
|
||||
"GWBD-D",
|
||||
"SI122",
|
||||
"GW83.3",
|
||||
"GW83.4"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"1": 31,
|
||||
"2": 28,
|
||||
"3": 31,
|
||||
"4": 30,
|
||||
"5": 31,
|
||||
"6": 30,
|
||||
"7": 31,
|
||||
"8": 31,
|
||||
"9": 30,
|
||||
"10": 31,
|
||||
"11": 30,
|
||||
"12": 31
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
平台,标准机型,叶片型号
|
||||
GWH V20,GWH266-16.2,GW130
|
||||
4S,155/4500,GW76
|
||||
5S,165/5200,GW81
|
||||
GWH V15,GWH170-7.2,GW83.3
|
||||
GWH V11,171/5300,GW83.4
|
||||
GWH V15,175/7800,GW86
|
||||
GWH V12,204/6250H,GW99
|
||||
GWH V12,204/6250H,GW99A
|
||||
GWH V12,204/5600H,GW99A
|
||||
GWH V17,GWH221-7,GWBD-A2
|
||||
GWH V17,GWH221-8,GWBD-A2
|
||||
GWH V17,GWH221-8.34,GWBD-A2
|
||||
GWH V17,GWH221-11.1,GWBD-A2
|
||||
GWH V17,GWH221-6,GWBD-A3
|
||||
GWH V17,GWH221-6.7,GWBD-A3
|
||||
GWH V19,GWH221-6,GWBD-A3
|
||||
GWH V12,GWH204-5.0,GWBD-D
|
||||
GWH V20,252/13600,SI122
|
||||
GWH V12,182/7200H,SI90.2
|
||||
GWH V12,191/4550H,GW93
|
||||
GWH V12,191/6700H,GW93
|
||||
GW110.5,GW110.5,GW110.5
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
产品型号,里程区间[公里], 平均单价[元/(公里*片)] , 平均整车价[元/片]
|
||||
others,0-99,," 12,859.46 "
|
||||
others,100-199,," 14,946.73 "
|
||||
others,200-299,," 18,662.46 "
|
||||
others,300-599, 52.83 ,
|
||||
others,600-899, 38.36 ,
|
||||
others,900-1199, 32.89 ,
|
||||
others,1200-1499, 30.69 ,
|
||||
others,1500-1999, 28.49 ,
|
||||
others,2000-2499, 27.76 ,
|
||||
others,2500-3499, 22.87 ,
|
||||
others,3500-10000000, 21.02 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",0-99,," 15,802.31 "
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",100-199,," 18,445.12 "
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",200-299,," 22,391.35 "
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",300-599, 62.29 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",600-899, 44.75 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",900-1199, 38.23 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",1200-1499, 36.08 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",1500-1999, 33.44 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",2000-2499, 32.76 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",2500-3499, 26.68 ,
|
||||
"GWBD-A2, GWBD-A3, GWBD-B",3500-10000000, 24.27 ,
|
||||
,,,
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
from mesa.agent import Agent
|
||||
|
||||
|
||||
class DemandAgent(Agent):
|
||||
"""Demand agent holding monthly demand per city and product."""
|
||||
|
||||
def __init__(self, model, city, region, product_monthly_demand):
|
||||
super().__init__(model)
|
||||
self.city = city
|
||||
self.region = region
|
||||
# product_monthly_demand: {product: {month: demand_units}}
|
||||
self.product_monthly_demand = product_monthly_demand
|
||||
self.fulfilled = 0.0
|
||||
self.total_demand = sum(sum(m.values()) for m in product_monthly_demand.values())
|
||||
|
||||
def step(self):
|
||||
month = self.model.current_month
|
||||
total = 0
|
||||
for product, monthly in self.product_monthly_demand.items():
|
||||
total += monthly.get(month, 0)
|
||||
if total > 0:
|
||||
self.model.record_demand(self.region, total)
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
name: gw
|
||||
channels:
|
||||
- defaults
|
||||
- conda-forge
|
||||
dependencies:
|
||||
- python=3.13.9
|
||||
- pip
|
||||
- pip:
|
||||
- altair==6.0.0
|
||||
- anyio==4.11.0
|
||||
- asttokens==3.0.1
|
||||
- attrs==25.4.0
|
||||
- cachetools==6.2.2
|
||||
- certifi==2025.11.12
|
||||
- chardet==5.2.0
|
||||
- charset-normalizer==3.4.4
|
||||
- click==8.3.1
|
||||
- colorama==0.4.6
|
||||
- comm==0.2.3
|
||||
- contourpy==1.3.3
|
||||
- cycler==0.12.1
|
||||
- debugpy==1.8.17
|
||||
- decorator==5.2.1
|
||||
- et_xmlfile==2.0.0
|
||||
- executing==2.2.1
|
||||
- fastjsonschema==2.21.2
|
||||
- filelock==3.20.0
|
||||
- fonttools==4.60.1
|
||||
- gurobipy==13.0.0
|
||||
- h11==0.16.0
|
||||
- humanize==4.14.0
|
||||
- idna==3.11
|
||||
- ipykernel==7.1.0
|
||||
- ipython==9.7.0
|
||||
- ipython_pygments_lexers==1.1.1
|
||||
- ipyvue==1.11.3
|
||||
- ipyvuetify==1.11.3
|
||||
- ipywidgets==8.1.8
|
||||
- jedi==0.19.2
|
||||
- Jinja2==3.1.6
|
||||
- jsonschema==4.25.1
|
||||
- jsonschema-specifications==2025.9.1
|
||||
- jupyter_client==8.6.3
|
||||
- jupyter_core==5.9.1
|
||||
- jupyterlab_widgets==3.0.16
|
||||
- kiwisolver==1.4.9
|
||||
- Markdown==3.10
|
||||
- markdown-it-py==4.0.0
|
||||
- MarkupSafe==3.0.3
|
||||
- matplotlib==3.10.7
|
||||
- matplotlib-inline==0.2.1
|
||||
- mdurl==0.1.2
|
||||
- Mesa==3.3.1
|
||||
- narwhals==2.12.0
|
||||
- nbformat==5.10.4
|
||||
- nest-asyncio==1.6.0
|
||||
- networkx==3.5
|
||||
- numpy==2.3.5
|
||||
- openpyxl==3.1.5
|
||||
- packaging==25.0
|
||||
- pandas==2.3.3
|
||||
- parso==0.8.5
|
||||
- pillow==12.0.0
|
||||
- platformdirs==4.5.0
|
||||
- prompt_toolkit==3.0.52
|
||||
- psutil==7.1.3
|
||||
- PuLP==3.3.0
|
||||
- pure_eval==0.2.3
|
||||
- Pygments==2.19.2
|
||||
- pymdown-extensions==10.17.1
|
||||
- pyparsing==3.2.5
|
||||
- python-dateutil==2.9.0.post0
|
||||
- pytz==2025.2
|
||||
- PyYAML==6.0.3
|
||||
- pyzmq==27.1.0
|
||||
- reacton==1.9.1
|
||||
- referencing==0.37.0
|
||||
- requests==2.32.5
|
||||
- rich==14.2.0
|
||||
- rich-click==1.9.4
|
||||
- rpds-py==0.29.0
|
||||
- scipy==1.16.3
|
||||
- setuptools==80.9.0
|
||||
- six==1.17.0
|
||||
- sniffio==1.3.1
|
||||
- solara==1.54.0
|
||||
- solara-server==1.54.0
|
||||
- solara-ui==1.54.0
|
||||
- stack-data==0.6.3
|
||||
- starlette==0.50.0
|
||||
- tornado==6.5.2
|
||||
- tqdm==4.67.1
|
||||
- traitlets==5.14.3
|
||||
- typing_extensions==4.15.0
|
||||
- tzdata==2025.2
|
||||
- urllib3==2.5.0
|
||||
- uvicorn==0.38.0
|
||||
- watchdog==6.0.0
|
||||
- watchfiles==1.1.1
|
||||
- wcwidth==0.2.14
|
||||
- websockets==15.0.1
|
||||
- wheel==0.45.1
|
||||
- widgetsnbextension==4.0.15
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
import json
|
||||
import random
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
from simulation_model import SimulationModel
|
||||
|
||||
# Decision variables: two factory factors only
|
||||
TARGET_FACTORIES = ["ZhongcaiBaicheng", "ZhongcaiHami"]
|
||||
|
||||
# Bounds
|
||||
FACTOR_BOUNDS = (0.8, 3.0)
|
||||
|
||||
POP_SIZE = 20
|
||||
GENERATIONS = 50
|
||||
MUTATION_RATE = 0.2
|
||||
MUTATION_STD = 0.05 # for factors
|
||||
|
||||
|
||||
def clip(val: float, bounds: Tuple[float, float]) -> float:
|
||||
lo, hi = bounds
|
||||
return max(lo, min(hi, val))
|
||||
|
||||
|
||||
def evaluate(genes: List[float]) -> float:
|
||||
factory_factors = {fid: val for fid, val in zip(TARGET_FACTORIES, genes)}
|
||||
model = SimulationModel(factory_factors=factory_factors, output_enabled=False)
|
||||
while model.running:
|
||||
model.step()
|
||||
return model.mean_abs_error
|
||||
|
||||
|
||||
def mutate(genes: List[float]) -> List[float]:
|
||||
new = genes.copy()
|
||||
for i in range(len(new)):
|
||||
if random.random() < MUTATION_RATE:
|
||||
jitter = random.gauss(0, MUTATION_STD)
|
||||
new[i] = clip(new[i] + jitter, FACTOR_BOUNDS)
|
||||
return new
|
||||
|
||||
|
||||
def crossover(p1: List[float], p2: List[float]) -> Tuple[List[float], List[float]]:
|
||||
point = random.randint(1, len(p1) - 1)
|
||||
c1 = p1[:point] + p2[point:]
|
||||
c2 = p2[:point] + p1[point:]
|
||||
return c1, c2
|
||||
|
||||
|
||||
def init_population() -> List[List[float]]:
|
||||
pop = []
|
||||
best_path = Path("data") / "ga_two_best_params.json"
|
||||
seed_indiv = None
|
||||
if best_path.exists():
|
||||
try:
|
||||
best = json.loads(best_path.read_text(encoding="utf-8"))
|
||||
seed_indiv = [float(best.get(f"factor_{fid}", random.uniform(*FACTOR_BOUNDS))) for fid in TARGET_FACTORIES]
|
||||
except Exception:
|
||||
seed_indiv = None
|
||||
|
||||
for idx in range(POP_SIZE):
|
||||
if seed_indiv is not None and idx == 0:
|
||||
pop.append(seed_indiv)
|
||||
continue
|
||||
indiv = [random.uniform(*FACTOR_BOUNDS) for _ in TARGET_FACTORIES]
|
||||
pop.append(indiv)
|
||||
return pop
|
||||
|
||||
|
||||
def main():
|
||||
best_genes = None
|
||||
best_score = float("inf")
|
||||
population = init_population()
|
||||
|
||||
for gen in range(GENERATIONS):
|
||||
scored = []
|
||||
for indiv in population:
|
||||
score = evaluate(indiv)
|
||||
scored.append((score, indiv))
|
||||
if score < best_score:
|
||||
best_score = score
|
||||
best_genes = indiv
|
||||
scored.sort(key=lambda x: x[0])
|
||||
next_pop = [scored[0][1], scored[1][1]]
|
||||
while len(next_pop) < POP_SIZE:
|
||||
parents = random.sample(scored[:max(3, len(scored))], 2)
|
||||
c1, c2 = crossover(parents[0][1], parents[1][1])
|
||||
next_pop.append(mutate(c1))
|
||||
if len(next_pop) < POP_SIZE:
|
||||
next_pop.append(mutate(c2))
|
||||
population = next_pop
|
||||
print(f"Generation {gen+1}: best={best_score:.4f}")
|
||||
|
||||
result = {}
|
||||
for fid, val in zip(TARGET_FACTORIES, best_genes):
|
||||
result[f"factor_{fid}"] = val
|
||||
|
||||
data_path = Path("data") / "ga_two_best_params.json"
|
||||
prev_score = float("inf")
|
||||
if data_path.exists():
|
||||
try:
|
||||
prev = json.loads(data_path.read_text(encoding="utf-8"))
|
||||
prev_score = float(prev.get("best_score", float("inf")))
|
||||
except Exception:
|
||||
prev_score = float("inf")
|
||||
|
||||
if best_score < prev_score:
|
||||
data_path.write_text(
|
||||
json.dumps({"best_score": best_score, **result}, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(f"New best mean abs error: {best_score:.4f}, saved to {data_path}")
|
||||
else:
|
||||
print(f"Best mean abs error: {best_score:.4f} (not better than {prev_score:.4f}, not saved)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
import json
|
||||
import random
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
from simulation_model import SimulationModel
|
||||
|
||||
|
||||
# Decision variables:
|
||||
# - month1, month2, month3, month4 efficiencies (hour/blade)
|
||||
# - factory-specific new-factory factors (from data/factory_mapping.json)
|
||||
FACTORY_MAPPING = json.loads(Path("data/factory_mapping.json").read_text(encoding="utf-8"))
|
||||
FACTORY_IDS = list(FACTORY_MAPPING.values())
|
||||
|
||||
# Bounds for genes: (min, max)
|
||||
MONTH_BOUNDS = (30.0, 250.0)
|
||||
FACTOR_BOUNDS = (0.8, 3.0)
|
||||
|
||||
POP_SIZE = 20
|
||||
GENERATIONS = 200
|
||||
MUTATION_RATE = 0.2
|
||||
MUTATION_STD = 5.0 # hours for months; factors mutate separately
|
||||
|
||||
|
||||
def clip(val: float, bounds: Tuple[float, float]) -> float:
|
||||
lo, hi = bounds
|
||||
return max(lo, min(hi, val))
|
||||
|
||||
|
||||
def evaluate(genes: List[float]) -> float:
|
||||
month1, month2, month3, month4 = genes[:4]
|
||||
factor_genes = genes[4:]
|
||||
factory_factors = {fid: val for fid, val in zip(FACTORY_IDS, factor_genes)}
|
||||
try:
|
||||
model = SimulationModel(
|
||||
month1=month1,
|
||||
month2=month2,
|
||||
month3=month3,
|
||||
month4=month4,
|
||||
factory_factors=factory_factors,
|
||||
output_enabled=False,
|
||||
)
|
||||
while model.running:
|
||||
model.step()
|
||||
return model.mean_abs_error
|
||||
except PermissionError as e:
|
||||
print(f"文件访问冲突: {e}. 正在重试...")
|
||||
return float('inf') # 返回高值以惩罚该个体
|
||||
except Exception as e:
|
||||
print(f"发生错误: {e}")
|
||||
return float('inf')
|
||||
|
||||
|
||||
def mutate(genes: List[float]) -> List[float]:
|
||||
new = genes.copy()
|
||||
for i in range(len(new)):
|
||||
if random.random() < MUTATION_RATE:
|
||||
if i < 4:
|
||||
new[i] = clip(new[i] + random.gauss(0, MUTATION_STD), MONTH_BOUNDS)
|
||||
else:
|
||||
jitter = random.gauss(0, 0.05)
|
||||
new[i] = clip(new[i] + jitter, FACTOR_BOUNDS)
|
||||
return new
|
||||
|
||||
|
||||
def crossover(p1: List[float], p2: List[float]) -> Tuple[List[float], List[float]]:
|
||||
point = random.randint(1, len(p1) - 1)
|
||||
c1 = p1[:point] + p2[point:]
|
||||
c2 = p2[:point] + p1[point:]
|
||||
return c1, c2
|
||||
|
||||
|
||||
def init_population() -> List[List[float]]:
|
||||
pop = []
|
||||
# Warm start from best params if available
|
||||
best_path = Path("data") / "ga_best_params.json"
|
||||
seed_indiv = None
|
||||
if best_path.exists():
|
||||
try:
|
||||
best = json.loads(best_path.read_text(encoding="utf-8"))
|
||||
seed_indiv = [
|
||||
float(best.get("month1", random.uniform(*MONTH_BOUNDS))),
|
||||
float(best.get("month2", random.uniform(*MONTH_BOUNDS))),
|
||||
float(best.get("month3", random.uniform(*MONTH_BOUNDS))),
|
||||
float(best.get("month4", random.uniform(*MONTH_BOUNDS))),
|
||||
]
|
||||
for fid in FACTORY_IDS:
|
||||
seed_indiv.append(float(best.get(f"factor_{fid}", random.uniform(*FACTOR_BOUNDS))))
|
||||
except Exception:
|
||||
seed_indiv = None
|
||||
|
||||
for _ in range(POP_SIZE):
|
||||
if seed_indiv is not None and _ == 0:
|
||||
indiv = seed_indiv
|
||||
else:
|
||||
indiv = [
|
||||
random.uniform(*MONTH_BOUNDS),
|
||||
random.uniform(*MONTH_BOUNDS),
|
||||
random.uniform(*MONTH_BOUNDS),
|
||||
random.uniform(*MONTH_BOUNDS),
|
||||
]
|
||||
indiv += [random.uniform(*FACTOR_BOUNDS) for _ in FACTORY_IDS]
|
||||
pop.append(indiv)
|
||||
return pop
|
||||
|
||||
|
||||
def main():
|
||||
best_genes = None
|
||||
best_score = float("inf")
|
||||
population = init_population()
|
||||
|
||||
for gen in range(GENERATIONS):
|
||||
scored = []
|
||||
for indiv in population:
|
||||
score = evaluate(indiv)
|
||||
scored.append((score, indiv))
|
||||
if score < best_score:
|
||||
best_score = score
|
||||
best_genes = indiv
|
||||
scored.sort(key=lambda x: x[0])
|
||||
# Elitism: keep top 2
|
||||
next_pop = [scored[0][1], scored[1][1]]
|
||||
# Fill rest via crossover + mutation
|
||||
while len(next_pop) < POP_SIZE:
|
||||
parents = random.sample(scored[:10], 2)
|
||||
c1, c2 = crossover(parents[0][1], parents[1][1])
|
||||
next_pop.append(mutate(c1))
|
||||
if len(next_pop) < POP_SIZE:
|
||||
next_pop.append(mutate(c2))
|
||||
population = next_pop
|
||||
print(f"Generation {gen+1}: best={best_score:.4f}")
|
||||
|
||||
# Save best parameters
|
||||
result = {
|
||||
"month1": best_genes[0],
|
||||
"month2": best_genes[1],
|
||||
"month3": best_genes[2],
|
||||
"month4": best_genes[3],
|
||||
}
|
||||
for fid, val in zip(FACTORY_IDS, best_genes[4:]):
|
||||
result[f"factor_{fid}"] = val
|
||||
|
||||
out_path = Path("output") / "ga_best_params.json"
|
||||
data_path = Path("data") / "ga_best_params.json"
|
||||
data_path.parent.mkdir(exist_ok=True)
|
||||
# Only overwrite if better
|
||||
if data_path.exists():
|
||||
try:
|
||||
prev = json.loads(data_path.read_text(encoding="utf-8"))
|
||||
prev_score = float(prev.get("best_score", float("inf")))
|
||||
except Exception:
|
||||
prev_score = float("inf")
|
||||
else:
|
||||
prev_score = float("inf")
|
||||
|
||||
if best_score < prev_score:
|
||||
data_path.write_text(
|
||||
json.dumps({"best_score": best_score, **result}, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(f"New best mean abs error: {best_score:.4f}, saved to {data_path}")
|
||||
else:
|
||||
print(f"Best mean abs error: {best_score:.4f} (not better than {prev_score:.4f}, not saved)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
from mesa.agent import Agent
|
||||
|
||||
|
||||
class ProductionLineAgent(Agent):
|
||||
"""A production line agent with basic production scheduling."""
|
||||
|
||||
def __init__(self, model, line_id, region, factory, is_new_factory, schedule, ramp_ranges):
|
||||
super().__init__(model)
|
||||
self.line_id = line_id
|
||||
self.region = region
|
||||
self.factory = factory
|
||||
self.is_new_factory = is_new_factory
|
||||
# List of dicts: {"product": str, "start_month": int, "end_month": int}
|
||||
self.schedule = schedule
|
||||
# ramp_ranges: {1: value, 2: value, 3: value, 4: value}
|
||||
self.ramp_ranges = ramp_ranges
|
||||
self.blade_stock = {} # 临时叶片库存 {product: blades not yet assembled}
|
||||
self.unit_stock = {} # 叶片机组库存 {product: assembled units}
|
||||
|
||||
def _sample_cycle_hours(self, product, month_index):
|
||||
idx = min(max(month_index, 1), 4)
|
||||
base = self.ramp_ranges[idx]
|
||||
factor = self.model.get_factory_factor(self.factory)
|
||||
return base * factor
|
||||
|
||||
def step(self):
|
||||
month = self.model.current_month
|
||||
available_hours = self.model.get_available_hours(month)
|
||||
active = [
|
||||
entry for entry in self.schedule if entry["start_month"] <= month <= entry["end_month"]
|
||||
]
|
||||
if not active:
|
||||
return
|
||||
# If multiple entries overlap, take the first one in the list.
|
||||
task = active[0]
|
||||
product = task["product"]
|
||||
|
||||
if not self.is_new_factory:
|
||||
cycle_hours = self._sample_cycle_hours(product, 4)
|
||||
else:
|
||||
if task["start_month"] == 1:
|
||||
month_index = 4
|
||||
else:
|
||||
month_index = month - task["start_month"] + 1
|
||||
cycle_hours = self._sample_cycle_hours(product, month_index)
|
||||
|
||||
produced_blades = available_hours / cycle_hours
|
||||
|
||||
# Update blade and unit inventories
|
||||
current_blades = self.blade_stock.get(product, 0) + produced_blades
|
||||
units_to_add = int(current_blades // 3)
|
||||
remaining_blades = current_blades - units_to_add * 3
|
||||
if units_to_add > 0:
|
||||
self.unit_stock[product] = self.unit_stock.get(product, 0) + units_to_add
|
||||
self.blade_stock[product] = remaining_blades
|
||||
|
||||
self.model.record_production(
|
||||
line_id=self.line_id,
|
||||
factory=self.factory,
|
||||
region=self.region,
|
||||
month=month,
|
||||
product=product,
|
||||
units=units_to_add,
|
||||
)
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pandas as pd
|
||||
import pulp
|
||||
from math import radians, sin, cos, sqrt, atan2
|
||||
|
||||
# 1. 读取数据
|
||||
inventory_df = pd.read_excel('可调拨库存表.xlsx')
|
||||
factory_loc_df = pd.read_excel('工厂位置.xlsx')
|
||||
demand_df = pd.read_excel('需求表.xlsx') # 型号、市、需求
|
||||
city_loc_df = pd.read_excel('地名经纬度.xlsx') # 市、经度、纬度
|
||||
|
||||
# 2. 数据合并
|
||||
inventory_df['可调拨库存'] = pd.to_numeric(inventory_df['可调拨库存'], errors='coerce').fillna(0)
|
||||
demand_df['需求'] = pd.to_numeric(demand_df['需求'], errors='coerce').fillna(0)
|
||||
|
||||
# 工厂库存合并
|
||||
factory_capacity = {}
|
||||
for _, row in inventory_df.groupby(['工厂', '型号'])['可调拨库存'].sum().reset_index().iterrows():
|
||||
f, p, cap = row['工厂'], row['型号'], int(row['可调拨库存'])
|
||||
if cap > 0:
|
||||
factory_capacity.setdefault(f, {})[p] = cap
|
||||
|
||||
# 城市需求合并
|
||||
city_demand = {}
|
||||
for _, row in demand_df.iterrows():
|
||||
city, p, dem = row['市'], row['型号'], int(row['需求'])
|
||||
if dem > 0:
|
||||
city_demand.setdefault(city, {})
|
||||
city_demand[city][p] = city_demand[city].get(p, 0) + dem
|
||||
|
||||
factory_lonlat = dict(zip(factory_loc_df['工厂'], zip(factory_loc_df['经度'], factory_loc_df['纬度'])))
|
||||
city_lonlat = dict(zip(city_loc_df['市'], zip(city_loc_df['经度'], city_loc_df['纬度'])))
|
||||
|
||||
# missing = set(city_demand) - set(city_lonlat)
|
||||
# if missing:
|
||||
# raise ValueError(f"缺少经纬度:{missing}")
|
||||
|
||||
# 3. 距离
|
||||
dist = {}
|
||||
for f in factory_capacity:
|
||||
for c in city_demand:
|
||||
lon1, lat1 = factory_lonlat[f]
|
||||
lon2, lat2 = city_lonlat[c]
|
||||
dlon = radians(lon2-lon1)
|
||||
dlat = radians(lat2-lat1)
|
||||
a = sin(dlat/2)**2 + cos(radians(lat1))*cos(radians(lat2))*sin(dlon/2)**2
|
||||
dist[(f,c)] = 6371 * 2 * atan2(sqrt(a), sqrt(1-a))
|
||||
|
||||
# 4. 单位运费函数
|
||||
def get_real_unit_cost(distance_km, product):
|
||||
d = distance_km
|
||||
p = str(product).strip()
|
||||
if p in ['GWBD-A2', 'GWBD-A3', 'GWBD-B']:
|
||||
if distance_km <= 100:
|
||||
return 15802.31
|
||||
elif distance_km <= 200:
|
||||
return 18445.12
|
||||
elif distance_km <= 300:
|
||||
return 22391.35
|
||||
elif distance_km <= 600:
|
||||
return 62.29 * d
|
||||
elif distance_km <= 900:
|
||||
return 44.75 * d
|
||||
elif distance_km <= 1200:
|
||||
return 38.23 * d
|
||||
elif distance_km <= 1500:
|
||||
return 36.08 * d
|
||||
elif distance_km <= 2000:
|
||||
return 33.44 * d
|
||||
elif distance_km <= 2500:
|
||||
return 32.76 * d
|
||||
elif distance_km <= 3500:
|
||||
return 26.68 * d
|
||||
else:
|
||||
return 24.27
|
||||
# 其他型号用第二套
|
||||
else:
|
||||
if distance_km <= 100:
|
||||
return 12859.46
|
||||
elif distance_km <= 200:
|
||||
return 14946.73
|
||||
elif distance_km <= 300:
|
||||
return 18662.46
|
||||
elif distance_km <= 600:
|
||||
return 52.83 * d
|
||||
elif distance_km <= 900:
|
||||
return 38.36 * d
|
||||
elif distance_km <= 1200:
|
||||
return 32.89 * d
|
||||
elif distance_km <= 1500:
|
||||
return 30.69 * d
|
||||
elif distance_km <= 2000:
|
||||
return 28.49 * d
|
||||
elif distance_km <= 2500:
|
||||
return 27.76 * d
|
||||
elif distance_km <= 3500:
|
||||
return 22.87 * d
|
||||
else:
|
||||
return 21.02 * d
|
||||
|
||||
# 5. 规划模型
|
||||
prob = pulp.LpProblem("最小化运费", pulp.LpMinimize)
|
||||
|
||||
x = {}
|
||||
for f in factory_capacity:
|
||||
for p in factory_capacity[f]:
|
||||
for city in city_demand:
|
||||
if city_demand[city].get(p, 0) > 0:
|
||||
x[(f,city,p)] = pulp.LpVariable(f"ship_{f}_{city}_{p}", lowBound=0, cat="Integer")
|
||||
|
||||
# 缺货惩罚
|
||||
shortage = {(city,p): pulp.LpVariable(f"short_{city}_{p}", lowBound=0, cat="Continuous")
|
||||
for city in city_demand for p in city_demand[city]}
|
||||
|
||||
BIG_M = 1e10
|
||||
prob += pulp.lpSum(
|
||||
x[k] * get_real_unit_cost(dist[(k[0],k[1])], k[2]) # 真实单位运费
|
||||
for k in x
|
||||
) + pulp.lpSum(BIG_M * s for s in shortage.values())
|
||||
|
||||
# 库存硬约束
|
||||
for f in factory_capacity:
|
||||
for p in factory_capacity[f]:
|
||||
prob += pulp.lpSum(x.get((f,c,p), 0) for c in city_demand) <= factory_capacity[f][p]
|
||||
|
||||
# 需求软约束
|
||||
for city in city_demand:
|
||||
for p, dem in city_demand[city].items():
|
||||
prob += pulp.lpSum(x.get((f,city,p), 0) for f in factory_capacity) + shortage[(city,p)] >= dem
|
||||
|
||||
# 6. 求解
|
||||
status = prob.solve(pulp.PULP_CBC_CMD(msg=True, timeLimit=600))
|
||||
|
||||
print(f"\n求解状态: {pulp.LpStatus[status]}")
|
||||
if status != 1:
|
||||
print("无解(请检查总库存)")
|
||||
else:
|
||||
print("有解")
|
||||
# real_cost = pulp.value(prob.objective)
|
||||
# print(f"实际运输总费用: {real_cost:,.2f} 元")
|
||||
|
||||
# ====================== 7. 输出 ======================
|
||||
result = []
|
||||
for (f,city,p), var in x.items():
|
||||
q = int(pulp.value(var) or 0)
|
||||
if q >= 1:
|
||||
d = dist[(f,city)]
|
||||
# unit = get_real_unit_cost(d, p)
|
||||
result.append({
|
||||
"工厂": f,
|
||||
"型号": p,
|
||||
"需求方": city,
|
||||
"调拨数量": q,
|
||||
# "距离_km": round(d, 1),
|
||||
# "真实单位运费": round(unit, 3),
|
||||
# "总运费": round(q * unit, 2)
|
||||
})
|
||||
|
||||
df = pd.DataFrame(result)
|
||||
if not df.empty:
|
||||
df = df.sort_values(["工厂", "型号"]) # 按单位运费排序
|
||||
df[["工厂","型号","需求方","调拨数量"]].to_excel("调拨方案.xlsx", index=False)
|
||||
# print("\n调拨方案已保存(真实单位运费最优,优先满足单价更低的城市)")
|
||||
# print(df[["工厂","型号","需求方","调拨数量"]].to_string(index=False))
|
||||
else:
|
||||
print("\n无调拨记录")
|
||||
|
||||
# 校验报告
|
||||
# print("\n各城市需求满足情况:")
|
||||
# for city in city_demand:
|
||||
# for p, dem in city_demand[city].items():
|
||||
# sup = sum(r["调拨数量"] for r in result if r["需求方"]==city and r["型号"]==p)
|
||||
# print(f" {city} | {p}: 需求 {dem} → 调拨 {sup} → {'完美' if sup==dem else '异常'}")
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue