diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..2084c46
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ mysql.8
+ true
+ com.mysql.cj.jdbc.Driver
+ jdbc:mysql://gz-cynosdbmysql-grp-4ynd0gkb.sql.tencentcdb.com:23027/outsoursing_dataset
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 30078b5..0816e31 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/.idea/scheduling.iml b/.idea/scheduling.iml
index e1774a4..dde2ab6 100644
--- a/.idea/scheduling.iml
+++ b/.idea/scheduling.iml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
new file mode 100644
index 0000000..c9c7d12
--- /dev/null
+++ b/.idea/sqldialects.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dataset_importer.py b/dataset_importer.py
new file mode 100644
index 0000000..db35475
--- /dev/null
+++ b/dataset_importer.py
@@ -0,0 +1,138 @@
+from typing import List, Dict
+import mysql.connector
+import model
+
+
+def import_order(res) -> Dict[str, model.Order]:
+ """
+ 导入订单
+ :param res: 数据库返回的行对象
+ :return: 订单对象集合
+ """
+
+ orders: Dict[str, model.Order] = {}
+
+ for record in res:
+ order: model.Order = model.Order(record[0], record[1])
+ order.set_time(record[2], record[3])
+ orders[order.order_id] = order
+
+ return orders
+
+
+def import_product(res) -> Dict[str, model.Product]:
+ """
+ 导入产品
+ :param res: 数据库返回的行对象
+ :return: 产品对象集合
+ """
+
+ products: Dict[str, model.Product] = {}
+
+ for record in res:
+ product: model.Product = model.Product(record[0], record[1])
+ products[product.product_id] = product
+
+ return products
+
+
+def import_order_product(res, orders: Dict[str, model.Order], products: Dict[str, model.Product]) -> None:
+ for record in res:
+ orders[record[0]].add_product(products[record[1]], record[2])
+
+
+def import_product_component(res, products: Dict[str, model.Product]):
+ for record in res:
+ products[record[0]].add_semi_product(products[record[1]], record[2])
+
+
+def import_process(res, products: Dict[str, model.Product]) -> Dict[str, model.Process]:
+ processes: Dict[str, model.Process] = {}
+
+ for record in res:
+ process: model.Process = model.Process(record[0], record[1], products[record[2]], record[9])
+ process.set_mode_quantity(record[5], record[6], record[7])
+ process.set_product_time(record[8])
+ products[record[2]].set_process(process)
+ processes[process.pcs_id] = process
+
+ for record in res:
+
+ pre_process = None
+ if record[3] is not None:
+ pre_process = processes[record[3]]
+
+ last_process = None
+ if record[4] is not None:
+ last_process = processes[record[4]]
+
+ processes[record[0]].set_pre_last_pcs(pre_process, last_process)
+
+ return processes
+
+
+def import_resource(res) -> Dict[str, model.Resource]:
+ resources: Dict[str, model.Resource] = {}
+
+ for record in res:
+ resource = model.Resource(record[0], record[1], record[2], record[4])
+ resource.set_amount(record[3])
+ resources[resource.rsc_id] = resource
+
+ return resources
+
+
+def import_resource_attributes(res, resources: Dict[str, model.Resource]):
+ for record in res:
+ resources[record[0]].set_basic_attr(record[1])
+ resources[record[0]].add_attr(record[2])
+
+
+def import_dataset():
+ conn = mysql.connector.connect(
+ host="gz-cynosdbmysql-grp-4ynd0gkb.sql.tencentcdb.com",
+ port="23027",
+ user="outsoursing",
+ password="Npu1234!",
+ database="outsoursing_dataset")
+
+ cur = conn.cursor()
+
+ cur.execute("SELECT * FROM aps_order;")
+ res = cur.fetchall()
+
+ orders = import_order(res)
+
+ cur.execute("SELECT * FROM aps_product;")
+ res = cur.fetchall()
+
+ products = import_product(res)
+
+ cur.execute("SELECT * FROM aps_order_product;")
+ res = cur.fetchall()
+
+ import_order_product(res, orders, products)
+
+ cur.execute("SELECT * FROM aps_product_component;")
+ res = cur.fetchall()
+
+ import_product_component(res, products)
+
+ cur.execute("SELECT * FROM aps_process;")
+ res = cur.fetchall()
+
+ processes = import_process(res, products)
+
+ cur.execute("SELECT * FROM aps_resource;")
+ res = cur.fetchall()
+
+ resources = import_resource(res)
+
+ cur.execute("SELECT * FROM aps_resource_arrtibutes;")
+ res = cur.fetchall()
+
+ import_resource_attributes(res, resources)
+
+ conn.close()
+
+ return orders, products, processes, resources
diff --git a/model.py b/model.py
index 1a5311a..278d524 100644
--- a/model.py
+++ b/model.py
@@ -1,8 +1,11 @@
from __future__ import annotations
from datetime import datetime
-from typing import List, Dict, Set
+from typing import List, Dict, Set, Optional
+from utils import *
+@auto_str
+@auto_repr
class Order:
def __init__(self, order_id: str, description: str):
@@ -23,27 +26,43 @@ class Order:
})
+@auto_str
+@auto_repr
class Product:
def __init__(self, product_id: str, product_name: str):
self.product_id: str = product_id
self.product_name: str = product_name
+ self.semi_products: List[Dict[str, any]] = []
+ self.process: Optional[Process] = None
+
+ def add_semi_product(self, semi_product: Product, amount):
+ if semi_product.product_id != self.product_id:
+ self.semi_products.append({
+ "semi_product": semi_product,
+ "amount": amount
+ })
+
+ def set_process(self, process):
+ self.process = process
+@auto_str
+@auto_repr
class Workspace:
def __init__(self, name: str):
self.name: str = name
+@auto_str
+@auto_repr
class Process:
def __init__(self,
pcs_id: str,
pcs_name: str,
product: Product,
- prev_pcs: Process,
- last_pcs: Process,
workspace: Workspace):
self.pcs_id: str = pcs_id
@@ -56,11 +75,16 @@ class Process:
self.pdt_time: int = 0
- self.prev_pcs: Process = prev_pcs
- self.last_pcs: Process = last_pcs
+ self.prev_pcs: Optional[Process] = None
+ self.last_pcs: Optional[Process] = None
+
self.res_needs: List[Dict[str, any]] = []
self.workspace: Workspace = workspace
+ def set_pre_last_pcs(self, prev_pcs: Optional[Process], last_pcs: Optional[Process]):
+ self.prev_pcs: Process = prev_pcs
+ self.last_pcs: Process = last_pcs
+
def set_mode_quantity(self, production_mode: int, min_quantity: int, max_quantity: int):
self.production_mode: int = production_mode
self.min_quantity: int = max_quantity
@@ -76,20 +100,26 @@ class Process:
})
+@auto_str
+@auto_repr
class Resource:
def __init__(self, rsc_id: str, rsc_name: str, rsc_type: str, workspace: Workspace):
self.rsc_id: str = rsc_id
self.rsc_name: str = rsc_name
self.rsc_type: str = rsc_type
+ self.amount: int = 0
- self.attr: str = ""
- self.basic_attrs: Set = set()
+ self.basic_attr: Optional[str] = None
+ self.attrs: Set = set()
self.workspace: Workspace = workspace
- def set_attr(self, attr: str, basic_attrs: List[str]):
- if attr not in basic_attrs:
- raise Exception("Attr NOT IN Basic_Attrs")
+ def set_amount(self, amount: int):
+ self.amount: int = amount
- self.attr: str = attr
- self.basic_attrs: List[str] = basic_attrs
+ def set_basic_attr(self, basic_attr: Optional[str]):
+ self.basic_attr = basic_attr
+ self.attrs.add(basic_attr)
+
+ def add_attr(self, attr: str):
+ self.attrs.add(attr)
diff --git a/runtime.py b/runtime.py
index 214729b..e079455 100644
--- a/runtime.py
+++ b/runtime.py
@@ -1,6 +1,6 @@
import model
from datetime import datetime, timedelta
-from typing import List
+from typing import List, Dict
class RuntimeProduct:
@@ -25,6 +25,47 @@ class ProductLine:
self.runtime_products.append(runtime_product)
+class RuntimeProductLines:
+
+ def __init__(self):
+ self.product_lines: Dict[str, ProductLine] = {}
+ self.product_lines_list: List[ProductLine] = []
+
+ def add_runtime_product(self, runtime_product: RuntimeProduct):
+
+ if runtime_product.product.product_id not in self.product_lines.keys():
+ self.product_lines[runtime_product.product.product_id] = ProductLine(runtime_product.product)
+ self.product_lines_list = list(self.product_lines.values())
+
+ self.product_lines[runtime_product.product.product_id].add_runtime_product(runtime_product)
+
+ def pop_runtime_product(self):
+ if self.product_lines_list is None:
+ return None
+
+ earliest_end_time_runtime_product_line = self.product_lines_list[0]
+
+ earliest_end_time_runtime_product = None
+ if len(earliest_end_time_runtime_product_line.runtime_products) > 0:
+ earliest_end_time_runtime_product = earliest_end_time_runtime_product_line.runtime_products[0]
+
+ for product_line in self.product_lines_list:
+ if len(product_line.runtime_products) > 0:
+ runtime_product = product_line.runtime_products[0]
+ if earliest_end_time_runtime_product is None \
+ or runtime_product.ddl < earliest_end_time_runtime_product.ddl:
+ earliest_end_time_runtime_product = runtime_product
+ earliest_end_time_runtime_product_line = product_line
+
+ if len(earliest_end_time_runtime_product_line.runtime_products) > 0:
+ earliest_end_time_runtime_product_line.runtime_products.pop(0)
+
+ return earliest_end_time_runtime_product
+
+ def reset(self):
+ self.product_lines_list = list(self.product_lines)
+
+
class RuntimeProcess:
def __init__(self, runtime_product: RuntimeProduct, process: model.Process):
diff --git a/scheduling.py b/scheduling.py
index 53ddade..413fddb 100644
--- a/scheduling.py
+++ b/scheduling.py
@@ -1,14 +1,66 @@
import runtime
import model
import csv
-from typing import List
+from typing import List, Dict
from datetime import datetime
import time
+import dataset_importer
-def read_dataset():
- order_list: List[model.Order] = []
+def orders_processor(orders: Dict[str, model.Order]) -> List[runtime.RuntimeProduct]:
+ orders_list = list(orders.values())
+ sorted_orders_list = sorted(orders_list, key=lambda order: order.latest_end_time)
+ products_lines = runtime.RuntimeProductLines()
+
+ for sorted_order in sorted_orders_list:
+ for item in sorted_order.products:
+ runtime_product = runtime.RuntimeProduct(item["product"], item["amount"])
+ runtime_product.set_ddl(sorted_order.latest_end_time)
+ products_lines.add_runtime_product(runtime_product)
+
+ runtime_product = products_lines.pop_runtime_product()
+
+ produce_tree = []
+
+ produce_list = []
+
+ while runtime_product is not None:
+ search_semi_products(0, produce_tree, produce_list, runtime_product)
+ runtime_product = products_lines.pop_runtime_product()
+
+ return produce_list
+
+
+def search_semi_products(floor, produce_tree, produce_list, runtime_product):
+
+ runtime_semi_products = []
+ produce_tree.append({"runtime_product": runtime_product, "runtime_semi_products": runtime_semi_products})
+ # print("F", runtime_product.product.product_id, runtime_product.ddl)
+ if len(runtime_product.product.semi_products) > 0:
+
+ for item in runtime_product.product.semi_products:
+
+ runtime_semi_product = runtime.RuntimeProduct(item["semi_product"], item["amount"])
+ runtime_semi_product.set_ddl(runtime_product.ddl)
+
+ # print("C", runtime_semi_product.product.product_id, runtime_semi_product.ddl)
+
+ search_semi_products(floor+1, runtime_semi_products, produce_list, runtime_semi_product)
+
+ print("L", floor, runtime_product.product.product_id, runtime_product.ddl)
+ produce_list.append(runtime_product)
+
+
+def products_processor(runtime_products: List[runtime.RuntimeProduct]):
+ processes_list: List[runtime.RuntimeProcess] = []
+
+ for runtime_product in runtime_products:
+ runtime_process: runtime.RuntimeProcess = \
+ runtime.RuntimeProcess(runtime_product, runtime_product.product.process)
+
+ processes_list.append(runtime_process)
if __name__ == "__main__":
- read_dataset()
\ No newline at end of file
+ orders, products, processes, resources = dataset_importer.import_dataset()
+ orders_processor(orders)
\ No newline at end of file
diff --git a/utils.py b/utils.py
new file mode 100644
index 0000000..e119428
--- /dev/null
+++ b/utils.py
@@ -0,0 +1,17 @@
+def auto_str(cls):
+ def __str__(self):
+ return '%s(%s)' % (
+ type(self).__name__,
+ ', '.join('%s=%s' % item for item in vars(self).items())
+ )
+
+ cls.__str__ = __str__
+ return cls
+
+
+def auto_repr(cls):
+ def __repr__(self):
+ return str(self.__dict__)
+
+ cls.__repr__ = __repr__
+ return cls