微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将枚举算法应用于问题?

如何解决如何将枚举算法应用于问题?

我是stackoverflow的新手,我想知道是否有合适的方法/算法来解决我的示例问题,以便生成一个尊重问题某些条件的理想解决方案。您可以在这里找到我的json文件 example1.json ):https://gitlab.com/Schrodinger168/practice/-/blob/master/example1.json

我将解释csv文件以及要生成内容,如下所示:

对于 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 举报,一经查实,本站将立刻删除。