如何解决如何将枚举算法应用于问题?
我是stackoverflow的新手,我想知道是否有合适的方法/算法来解决我的示例问题,以便生成一个尊重问题某些条件的理想解决方案。您可以在这里找到我的json文件( example1.json ):https://gitlab.com/Schrodinger168/practice/-/blob/master/example1.json
对于 Ressources ,例如, Ressources_X ,其中 X 的值可以是1到9。所有 Ressource_X 的 min 和 max 值必须作为最终解决方案(将在下面说)予以尊重,且不能小于 min 并且大于所有 Ressources_X 中每天的 max 。
对于季节,有冬天,夏天,是 ...,每个数字对应于这些季节指的是一天,例如冬季定义从第1天到第13天,其他季节表示相同。
对于干预:是否必须计划任务。有 Intervention_X 及其相应的工作负载包含必须使用的 Ressources_X 。 Delta 是 Intervention_X 的持续时间,例如我们可以在 Intervention_625 中将其作为 Delta 列表为 1.0 ,这意味着如果 Intervention_625 从第1天开始,则它需要在同一天(第1天)结束,因为其第1天的Delta值是 1.0 ,依此类推...每个 Intervention_X 都有自己的 tmax ,例如 Intervention_625 的 tmax 等于 17 ,这意味着它可以在我们希望生成的第一天到第17天之间开始,也可以在其他 Intervention_X 的另一个 tmax 中开始 strong>表示相同。
对于排除,有一些例外情况,例如:
“ E141 [” Intervention_315“,” Intervention_456“,”夏季“] 表示 Intervention_315 和 Intervention_456 不能同时开始夏季的一天(可以在夏季的不同日期开始),其他的意思相同。
T 是这里的总工时 T = 17 ,这意味着整个工作时间为17天
我要生成的解决方案是干预的名称和每个干预的开始日期( tx,ty .. ),例如:
Intervention_X tx
干预次数
以此类推...直到所有干预措施都用完,因为它们将只使用一次。
并且该解决方案将确保它遵守每天使用资源(最小,最大),排除的条件,并且完成日期可以为 T + 1 (最大)。
如果需要,这是我的代码,可访问我的json文件的每个节点和值:
class access_json:
def __init__(self):
self._resources = dict()
self._seasons = dict()
self._interventions = dict()
self._exclusions = dict()
self._NRESOURCES = 0
self._NINTERVENTIONS = 0
self._list_resources = list()
self._list_interventions = list()
self._T = 0
def loadjson(self,fpath: str):
js = dict()
with open(fpath,'r') as f:
js = json.load(f)
self._resources = js["Resources"]
self._NRESOURCES = len(self._resources)
self._list_resources = list(self._resources.keys())
self._seasons = js["Seasons"]
self._interventions = js["Interventions"]
self._NINTERVENTIONS = len(self._interventions)
self._list_interventions = list(self._interventions.keys())
self._exclusions = js["Exclusions"]
self._T = js["T"]
为解决问题,我尝试每天使用置换交换和替换这些干预,但是这样做似乎很久了,并且没有产生解决方案。任何有关代码的帮助,有关如何应用算法解决此问题的建议,将不胜感激。先谢谢你!
解决方法
可以使用backtracking algorithm快速解决此问题。特别地,有了陈述的数据,它可以在毫秒内解决。
代码
def overlap(x,y):
'''
Checks if two time segments overlap
'''
a,b = x
c,d = y
return a <= d and b >= c
def allocate(data,ans = None):
'''
Intervention schedule allocation based upon backtracking
'''
if ans is None:
ans = {}
if len(ans) == len(data["Interventions"]):
# handled all the interventions
yield ans
# Check next intervention
for intervention_name,intervention in data["Interventions"].items():
if intervention_name not in ans:
# will add items not in ans
# last day intervention can be run
last_day = min(data["T"],int(intervention["tmax"]))
for day in range(1,last_day+1):
str_day = str(day)
# different days intervention could be run
delta = intervention["Delta"][day-1] # number of days it takes to run
if day + delta <= last_day + 1:
# must finish within last day
# Check that there are sufficient resources
resource_usage = {}
missing_resources = False
for resource_name,v in intervention["workload"].items():
if not str_day in v:
missing_resources = True
break
#raise Exception(f'{intervention_name} resources {k} missing day {str_day}')
usage_key = (resource_name,day) # pair: (resource name,day) as key
resource_usage[usage_key] = v[str_day][str_day]
if missing_resources:
continue # one resource has no resources for a day
# Resources needed by items in list for this day
for ans_name,ans_response in ans.items():
ans_day = ans_response["Day"]
ans_delta = ans_response["Delta"]
if overlap([day,day+delta-1],[ans_day,ans_day+ans_delta-1]):
# An intervention in answer overlaps with current intervention
for resource_name,v_resource in ans_response["Resources"].items():
for overlap_day in range(day,day+int(delta)):
# Get resource usage for each day of overlap
usage_key = (resource_name,overlap_day)
if not usage_key in resource_usage:
resource_usage[usage_key] = 0
resource_usage[usage_key] += v_resource
# Check resource less than max
resources = data["Resources"]
for usage_key,value in resource_usage.items():
resource_name,overlap_day = usage_key # values from tuple
if value > resources[resource_name]["max"][day-1]: # max value for resoure for this day
break
else:
# Resource didn't exceed max
# Check on Exclusion
winter = data["Seasons"]['winter']
summer = data["Seasons"]['summer']
isa = data["Seasons"]['is']
if str_day in winter:
season = "winter"
elif str_day in summer:
season = "summer"
elif str_day in isa:
season = "is"
else:
season = ""
exclusions = data["Exclusions"]
bExclude = False
for k,v_lst in exclusions.items():
if season in v_lst and intervention_name in v_lst:
for intervention_k,ans_response in ans.items():
if intervention_k in v_lst:
ans_day = ans_response["Day"]
ans_delta = ans_response["Delta"]
if overlap([day,ans_day+ans_delta-1]):
bExclude = True
break
if bExclude:
break
if not bExclude:
# Resources used
response = {"Day": day,"Delta": intervention["Delta"][day-1]}
resources = {k:v[str_day][str_day] for k,v in intervention["workload"].items()}
response['Resources'] = resources
ans[intervention_name] = response
yield from allocate(data,ans)
# Remove last entry so we can try next iteration
del ans[intervention_name]
用法
使用发布的数据集
# Loading data from local file
with open('resource_allocation/example1.json','r') as f:
data = json.load(f)
# Get first solution using from allocate generator
answer = next(allocate(data),None)
if answer:
for name,intervention in answer.items():
print(f'Intervention {name}')
print(f'\tStart {intervention["Day"]},Duration: {intervention["Delta"]}')
resources = intervention["Resources"]
for k,v in resources.items():
print(f'\tResource: {k} Usage: {v}')
print()
输出
Intervention Intervention_625
Start 1,Duration: 1.0
Resource: Ressources_2 Usage: 0.14
Resource: Ressources_4 Usage: 0.14
Resource: Ressources_7 Usage: 0.14
Resource: Ressources_8 Usage: 0.056
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_31
Start 1,Duration: 2.0
Resource: Ressources_3 Usage: 0.86
Resource: Ressources_4 Usage: 0.86
Resource: Ressources_9 Usage: 0.086
Intervention Intervention_40
Start 1,Duration: 1.0
Resource: Ressources_2 Usage: 0.29
Resource: Ressources_7 Usage: 0.29
Resource: Ressources_9 Usage: 0.029
Intervention Intervention_224
Start 1,Duration: 1.0
Resource: Ressources_1 Usage: 0.71
Resource: Ressources_9 Usage: 0.071
Intervention Intervention_702
Start 1,Duration: 1.0
Resource: Ressources_2 Usage: 0.43
Resource: Ressources_9 Usage: 0.043
Intervention Intervention_19
Start 1,Duration: 2.0
Resource: Ressources_4 Usage: 0.86
Resource: Ressources_8 Usage: 0.344
Resource: Ressources_9 Usage: 0.086
Intervention Intervention_672
Start 1,Duration: 1.0
Resource: Ressources_3 Usage: 0.43
Resource: Ressources_9 Usage: 0.043
Intervention Intervention_579
Start 1,Duration: 1.0
Resource: Ressources_8 Usage: 0.028
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_627
Start 1,Duration: 2.0
Resource: Ressources_2 Usage: 0.86
Resource: Ressources_7 Usage: 0.86
Resource: Ressources_8 Usage: 0.344
Resource: Ressources_9 Usage: 0.086
Intervention Intervention_456
Start 1,Duration: 1.0
Resource: Ressources_4 Usage: 0.14
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_90
Start 1,Duration: 1.0
Resource: Ressources_2 Usage: 0.14
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_315
Start 2,Duration: 1.0
Resource: Ressources_4 Usage: 0.14
Resource: Ressources_6 Usage: 0.14
Resource: Ressources_7 Usage: 0.14
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_356
Start 1,Duration: 1.0
Resource: Ressources_7 Usage: 0.57
Resource: Ressources_9 Usage: 0.057
Intervention Intervention_535
Start 1,Duration: 1.0
Resource: Ressources_3 Usage: 0.29
Resource: Ressources_7 Usage: 0.29
Resource: Ressources_9 Usage: 0.029
Intervention Intervention_595
Start 1,Duration: 1.0
Resource: Ressources_2 Usage: 0.14
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_592
Start 1,Duration: 1.0
Resource: Ressources_2 Usage: 0.14
Resource: Ressources_8 Usage: 0.056
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_536
Start 1,Duration: 1.0
Resource: Ressources_3 Usage: 0.14
Resource: Ressources_7 Usage: 0.14
Resource: Ressources_9 Usage: 0.014
Intervention Intervention_150
Start 1,Duration: 1.0
Resource: Ressources_2 Usage: 0.14
Resource: Ressources_6 Usage: 0.14
Resource: Ressources_9 Usage: 0.014
说明
伪代码
def allocate(data,ans = None):
# initize answer if not initialized
if ans is None:
ans = {} # dictionary of interventions with name,day and resources used
# Base case (check if solution found)
if len(ans) == len(data["Interventions"]):
yield ans # let me know if you're not familiar with generators
# Try remaining interventions (i.e. ones not in answer ans)
# Loop over all interventions
for intervention_name,intervention in data["Interventions"].items():
if intervention_name not in ans:
# This intervention not in answer ans
# Found out what day to run the intervention
# last day to run
last_day = min(data["T"],last_day+1):
# Range of days to try running the intervention
# make sure intervention finishes before last day
delta = intervention["Delta"][day-1] # number of days it takes to run
if day + delta <= last_day + 1:
# Check if intervention satisfies constraints if we add it on this day
# 1--check sufficient resources
# logic for checking if suffient resources
# set sufficient_resources to True if sufficient,False otherwise
if sufficient_resources:
# 2--check if intervention compatible with others in list
# i.e. can run on same day as others in ans
# set compatible to True if not excluded by others in list,False otherwise
if compatible:
# add intervention to ans for this day with the resources it uses on this day
# we call this response
# Add intervention for this day
ans[intervention_name] = response
# now recursive try other interventions
# This recursives tries other interventions
# by now successively trying the next intervention which is not in ans on a compatibl day
yield from allocate(data,and)
del ans[intervention_name] # remove last entry
伪代码-非生成器功能(但仅找到第一个解决方案)
def allocate(data,day and resources used
# Base case (check if solution found)
if len(ans) == len(data["Interventions"]):
return True # let me know if you're not familiar with generators
# Try remaining interventions (i.e. ones not in answer ans)
# Loop over all interventions
for intervention_name,False otherwise
if compatible:
# add intervention to ans for this day with the resources it uses on this day
# we call this response
# Add intervention for this day
ans[intervention_name] = response
# now recursive try other interventions
# This recursives tries other interventions
# by now successively trying the next intervention which is not in ans on a compatibl day
if allocate(data,ans):
# Path forward found a solution
return True
else:
# Backtrack--this day won't work
# remove intervention since won't work for this day
del ans[intervention_name]
非生成器版本
def overlap(x,d = y
return a <= d and b >= c
def allocate2(data,ans = None):
'''
Intervention schedule allocation based upon backtracking
'''
if ans is None:
ans = {}
if len(ans) == len(data["Interventions"]):
# handled all the interventions
return ans
# Check next intervention
for intervention_name,v in intervention["workload"].items()}
response['Resources'] = resources
ans[intervention_name] = response
result = allocate2(data,ans)
if result:
# was able to find an answer going forward using intervention
# on this day,so return the result
return result
# Remove last entry so we can try next iteration
del ans[intervention_name]
用法
answer = allocate2(data)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。