-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: LongxingTan <[email protected]>
- Loading branch information
1 parent
5a443c2
commit 0036690
Showing
13 changed files
with
189 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
""" | ||
backward + forward + push | ||
""" | ||
|
||
import pandas as pd | ||
|
||
from lekin.lekin_struct import Job, JobCollector, Resource, ResourceCollector, Route | ||
from lekin.solver.construction_heuristics.rule import BackwardScheduler | ||
|
||
mo = pd.read_excel("./MOInput.xlsx", sheet_name="2.1.工单") | ||
resource_date = pd.read_excel("./MOInput.xlsx", sheet_name="5.1.资源可用列表") | ||
|
||
# print(mo) | ||
print(resource_date) | ||
|
||
|
||
job_collector = JobCollector() | ||
for index, row in mo.iterrows(): | ||
job_id = row["产品ID"] | ||
priority = row["优先级"] | ||
earliest_start_date = row["任务开始控制"] | ||
demand_date = row["交付时间"] | ||
assigned_route = map() | ||
# route_id = row['route_id'] | ||
job_collector.add_job( | ||
Job( | ||
job_id=job_id, | ||
priority=priority, | ||
demand_time=demand_date, | ||
earliest_start_time=earliest_start_date, | ||
assigned_route=assigned_route, | ||
) | ||
) | ||
|
||
|
||
resource_collector = ResourceCollector() | ||
for group, row in resource_date.groupby("资源ID"): | ||
resource_id = group | ||
start_time = row["开始时间"] | ||
end_time = row["结束时间"] | ||
|
||
resource = Resource(resource_id=resource_id) | ||
for s, d in zip(start_time, end_time): | ||
resource.add_timeslot(start_time, end_time) | ||
resource_collector.add_resource(resource) | ||
|
||
|
||
# scheduler = BackwardScheduler(job_collector, resource_collector) | ||
# scheduler.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
""" | ||
物料检查 | ||
物料 | ||
- 物料可以锁定,可以占用,可以空闲 | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from datetime import datetime, timedelta | ||
from itertools import permutations | ||
|
||
from lekin.lekin_struct import TimeSlot | ||
|
||
|
||
class BranchAndBoundScheduler: | ||
def __init__(self, job_list, resource_list): | ||
self.job_list = job_list | ||
self.resource_list = resource_list | ||
self.best_schedule = None | ||
self.best_cost = float("inf") | ||
|
||
def find_available_time_slots(self, operation, resource, current_time): | ||
# Implement the logic to find available time slots for a given operation and resource | ||
available_time_slots = [] | ||
for slot in resource.available_time_slots: | ||
if slot.start_time >= current_time + operation.processing_time: | ||
available_time_slots.append(slot) | ||
return available_time_slots | ||
|
||
def assign_operation(self, job, operation, resource, start_time): | ||
# Implement the logic to assign an operation to a resource at a specific start time | ||
end_time = start_time + operation.processing_time | ||
resource.available_time_slots.append(TimeSlot(end_time, float("inf"))) | ||
return end_time | ||
|
||
def calculate_cost(self, schedule): | ||
# Implement the logic to calculate the cost of the current schedule | ||
# For example, you can calculate makespan or any other relevant metric | ||
makespan = max(slot.end_time for slot in schedule) | ||
return makespan | ||
|
||
def branch_and_bound(self, current_job_idx, current_time, schedule): | ||
# Implement the Branch and Bound algorithm for scheduling | ||
if current_job_idx == len(self.job_list): | ||
cost = self.calculate_cost(schedule) | ||
if cost < self.best_cost: | ||
self.best_cost = cost | ||
self.best_schedule = schedule.copy() | ||
return | ||
|
||
job = self.job_list[current_job_idx] | ||
route = self.resource_list[job.route_id] | ||
|
||
for resource_id in route.operations[0].resource_ids: | ||
resource = self.resource_list[resource_id] | ||
time_slots = self.find_available_time_slots(route.operations[0], resource, current_time) | ||
for slot in time_slots: | ||
new_schedule = schedule + [slot] | ||
new_time = self.assign_operation(job, route.operations[0], resource, slot.start_time) | ||
self.branch_and_bound(current_job_idx + 1, new_time, new_schedule) | ||
|
||
def get_schedule(self): | ||
# Implement the main function to get the final schedule using Branch and Bound | ||
self.branch_and_bound(0, datetime(2023, 1, 1), []) | ||
return self.best_schedule |
File renamed without changes.
27 changes: 27 additions & 0 deletions
27
tests/test_solver/test_meta_heuristics/test_branch_and_bound.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from datetime import datetime, timedelta | ||
import unittest | ||
|
||
from lekin.lekin_struct import Job, Operation, Resource, Route, TimeSlot | ||
from lekin.solver.meta_heuristics.branch_and_bound import BranchAndBoundScheduler | ||
|
||
|
||
class BranchAndBoundSchedulerTest(unittest.TestCase): | ||
def test_schedule(self): | ||
job1 = Job(1, datetime(2023, 1, 10), 2, 1) | ||
job2 = Job(2, datetime(2023, 1, 20), 1, 1) | ||
|
||
op1 = Operation(1, timedelta(hours=2), 2, None, [1]) | ||
op2 = Operation(2, timedelta(hours=3), None, 1, [1]) | ||
|
||
route1 = Route(1, [op1, op2]) | ||
print(route1) | ||
|
||
resource1 = Resource(1, [TimeSlot(datetime(2023, 1, 1), datetime(2023, 1, 3))]) | ||
|
||
job_list = [job1, job2] | ||
resource_list = [resource1] | ||
|
||
scheduler = BranchAndBoundScheduler(job_list, resource_list) | ||
schedule = scheduler.get_schedule() | ||
for idx, slot in enumerate(schedule): | ||
print(f"Job {idx + 1} will start at {slot.start_time} and end at {slot.end_time}") |