Capacitated Facility Location Problem
2026/6/2 19:02:42 网站建设 项目流程

文章目录

  • Capacitated Facility Location Problem
    • [更多技术博客 http://vilins.top/](http://vilins.top/)
    • 题目
    • 分析
    • 实验工具
    • 解决算法
      • 模拟退火法
      • 禁忌搜索
    • 算法局部设计细节
      • 模拟退火法
      • 禁忌搜索
    • 结果整理
    • 两种做法的对比
    • 原始输出结果
    • 程序运行说明
    • 源码
    • github
    • [更多技术博客 http://vilins.top/](http://vilins.top/)

Capacitated Facility Location Problem

更多技术博客 http://vilins.top/

题目

分析

选址问题在生产生活,物流,甚至军事中都有这非常广泛的应用,以成为运筹学中经典的问题之一,其目的是确定一个或者多个设施的地址,使得判断标准获得优化的同时,及时向顾客提供其所需的产品和服务。工厂选址问题不仅影响到工厂的利润和市场竞争力,甚至决定了工厂的生死存亡。所以,工厂选址的研究具有重要意义。
这类问题在论文中出现得比较多,而网上现成的以实现的办法几乎没有,很多都是从理论层面上分析解决这类问题的可行性,而没有实操去证明其可行性。由于这类问题属于优化类问题,在线性时间很难求得其最优解,所以我们选择算法的时候一般选择优化类算法,动态规划之类的算法是行不通的,一般用于解决这类问题的办法有蚁群算法,遗传算法,贪婪算法,模拟退火法,禁忌搜索算法,近似算法等。
具体到这个题目,我们首先分析其限制的条件,这是一类有容量限制的工厂问题,具体限制如下:

总花费(total cost) = 工厂开放花费(opening cost) + 顾客分配到某个工厂以后的路程花费(assginment cost)

实验工具

语言:python
工具:Pycharm

解决算法

模拟退火法

禁忌搜索

算法局部设计细节

模拟退火法

初始解的产生,采用完全随机化选择部分工厂开放,但不让所有的工厂开放,符合一般最优化表现形式,表现最好。

def init_solution(self): for i in range(self.customer_num): self.current_state_of_customer.append(-1) for i in self.demand: self.total_demand += i self.current_capacity = self.capacity.copy() total_cost = 0 temp = [] while total_cost < self.total_demand: r = random.randint(0, self.facility_num - 1) if r not in temp: temp.append(r) total_cost += self.capacity[r] index = 0 for i in range(self.customer_num): if self.current_capacity[temp[index]] - self.demand[i] >= 0: self.current_capacity[temp[index]] -= self.demand[i] self.current_state_of_customer[i] = temp[index] else: index += 1 i -= 1 # self.current_state_of_customer[i] = index # self.current_capacity[index] -= self.demand[i] self.current_cost = self.calculate_cost(self.current_state_of_customer) self.new_capacity = self.current_capacity.copy() self.new_state_of_customer = self.current_state_of_customer.copy()

初始化解,利用局部贪婪,可以调节贪婪的比例,但效果不太好

def init_solution(self): for i in range(self.customer_num): self.current_state_of_customer.append(-1) for i in self.demand: self.total_demand += i self.current_capacity = self.capacity.copy() for i in range(self.customer_num): ran_select = random.random() if ran_select > 0.2: min = 100000 index = 0 for j in range(self.facility_num): if min > self.assignment[j][i]: min = self.assignment[j][i] index = j if self.current_capacity[index] >= self.demand[i]: self.current_capacity[index] -= self.demand[i] self.current_state_of_customer[i] = index else: tag = True while tag: ran = random.randint(0, self.facility_num - 1) if self.current_capacity[ran] >= self.demand[i]: self.current_capacity[ran] -= self.demand[i] self.current_state_of_customer[i] = ran tag = False else: tag_out = True while tag_out: ran = random.randint(0, self.facility_num - 1) if self.current_capacity[ran] >= self.demand[i]: self.current_capacity[ran] -= self.demand[i] self.current_state_of_customer[i] = ran tag_out = False self.current_cost = self.calculate_cost(self.current_state_of_customer) self.new_capacity = self.current_capacity.copy() self.new_state_of_customer = self.current_state_of_customer.copy() print('cost ', self.current_cost) print('current cap ', self.current_capacity) print('current cu ', self.current_state_of_customer)

产生新解的方式

def gen_new_solution(self): tag = True self.new_capacity = self.current_capacity.copy() self.new_state_of_customer = self.current_state_of_customer.copy() while tag: ran_customer = random.randint(0, self.customer_num - 1) ran_facility = random.randint(0, self.facility_num - 1) # print("ran ", ran_facility, ran_customer) if self.new_capacity[ran_facility] >= self.demand[ran_customer]: tag = False self.new_capacity[ran_facility] -= self.demand[ran_customer] origin = self.new_state_of_customer[ran_customer] self.new_state_of_customer[ran_customer] = ran_facility if origin == -1: break self.new_capacity[origin] += self.demand[ran_customer] else: continue

退火过程

def simulated_annealing(self): global fp_anneal time_start = time.time() while self.T > 0.01: i = 0 while i < self.repeat: i += 1 self.gen_new_solution() self.current_cost = self.calculate_cost(self.current_state_of_customer) new_cost = self.calculate_cost(self.new_state_of_customer) if new_cost < self.current_cost: self.current_capacity = self.new_capacity.copy() self.current_state_of_customer = self.new_state_of_customer.copy() # print("current cost ", new_cost) else: num = math.exp((self.current_cost - new_cost) / self.T) ran = random.random() # print("num ", num) # print("ran ", ran) if num >= ran: self.current_capacity = self.new_capacity.copy() self.current_state_of_customer = self.new_state_of_customer.copy() # print("current cost ", new_cost) self.T *= self.cooling_rate time_end = time.time() used_time = time_end - time_start fp_anneal.write('time ' + str(used_time) + '\n') fp_anneal.write('cost ' + str(self.current_cost) + '\n') temp = [] result_state = [] for i in range(self.customer_num): if self.current_state_of_customer[i] not in temp: temp.append(self.new_state_of_customer[i]) temp.sort() for i in range(self.facility_num): result_state.append(0) for i in temp: result_state[i] = 1 # print('cost ' + str(self.current_cost)) # print(result_state) # print(self.current_state_of_customer) # print(self.current_capacity) fp_anneal.write('facility state ' + str(result_state) + '\n') fp_anneal.write('current state of customer ' + str(self.current_state_of_customer) + '\n\n')

禁忌搜索

新解产生与模拟退火类似
邻居的产生

def gen_nei_solution(self): tag = True self.nei_capacity = self.current_capacity.copy() self.nei_state_of_customer = self.current_state_of_customer.copy() ran_customer = 0 origin = 0 while tag: ran_customer = random.randint(0, self.customer_num - 1) ran_facility = random.randint(0, self.facility_num - 1) # print("ran ", ran_facility, ran_customer) if self.nei_capacity[ran_facility] >= self.demand[ran_customer]: tag = False self.nei_capacity[ran_facility] -= self.demand[ran_customer] origin = self.nei_state_of_customer[ran_customer] self.nei_state_of_customer[ran_customer] = ran_facility if origin == -1: break self.nei_capacity[origin] += self.demand[ran_customer] else: continue return ran_customer, origin

禁忌搜索过程

def tabu_search(self): global fp_tabu self.nei_state_of_customer = self.current_state_of_customer.copy() self.nei_capacity = self.current_capacity.copy() # print(self.current_state_of_customer) # print(self.nei_capacity) self.tabu_list = [[0 for i in range(self.customer_num)]for i in range(self.facility_num)] # print(tabu_list) repeat = 30000 count = 0 nei_count = int(self.customer_num/4) best_solution_customer = self.current_state_of_customer.copy() best_solution_capacity = self.current_capacity.copy() best_cost = self.calculate_cost(best_solution_customer) time_start = time.time() while count < repeat: count += 1 i = nei_count self.gen_new_solution() new_cost = self.calculate_cost(self.new_state_of_customer) ran_customer = 0 origin = 0 while i > 1: i -= 1 ran_customer, origin = self.gen_nei_solution() nei_cost = self.calculate_cost(self.nei_state_of_customer) # print("nei ", nei_cost) # print("new ", new_cost) if nei_cost < new_cost: self.new_state_of_customer = self.nei_state_of_customer.copy() self.new_capacity = self.nei_capacity.copy() new_cost = nei_cost if new_cost < best_cost: # print("new ", new_cost) best_solution_customer = self.new_state_of_customer.copy() best_solution_capacity = self.new_capacity.copy() best_cost = new_cost if self.tabu_list[origin][ran_customer] < count: self.tabu_list[origin][ran_customer] = count + 20 self.current_state_of_customer = self.new_state_of_customer.copy() self.current_capacity = self.new_capacity.copy() time_end = time.time() used_time = time_end - time_start temp = [] result_state = [] for i in range(self.customer_num): if best_solution_customer[i] not in temp: temp.append(best_solution_customer[i]) temp.sort() for i in range(self.facility_num): result_state.append(0) for i in temp: result_state[i] = 1 fp_tabu.write('time ' + str(used_time) + '\n') fp_tabu.write('cost ' + str(best_cost) + '\n') fp_tabu.write('facility state ' + str(result_state) + '\n') fp_tabu.write('customer state ' + str(best_solution_customer) + '\n\n') print(best_cost) print(result_state) print(best_solution_customer) print(best_solution_capacity)

结果整理

fileresulttimeresulttime
模拟退火法模拟退火法禁忌搜索禁忌搜索
p190335.12332606315612889859.848682165145874
p280055.52882313728332579409.718816757202148
p393145.13923668861389296789.466161012649536
p4116285.307790279388428109549.69756555557251
p591315.344730377197266913710.06436276435852
p677815.39656233787536679079.97243070602417
p795775.525223731994629962510.066269397735596
p8114395.5332002639770511143310.113304615020752
p985934.83005332946777390318.910385608673096
p1076484.93875694274902377249.172668695449829
p1192265.14822697639465390628.851669073104858
p12110334.917876720428467102778.693775177001953
p1393125.169209718704224960410.038275718688965
p1471645.242977142333984820410.189182996749878
p1589645.441417932510376103359.89920711517334
p16119255.371662139892578124969.891655445098877
p1792785.45040369033813597959.87352442741394
p1877815.39055061340332826510.18008804321289
p1992675.236989974975586104089.878618240356445
p20117585.060497522354126125939.863529920578003
p2192954.85899639129638791039.683191061019897
p2277385.12528634071350180889.918416261672974
p2396545.08836030960083100709.597949266433716
p24112634.70444393157959118009.354219436645508
p251228112.8904881477355961358967.44565677642822
p261162313.5537416934967041125470.20729756355286
p271357413.0281190872192381337766.27394366264343
p281572913.245565891265871757267.49193954467773
p291351013.50685191154481368372.6292462348938
p301189413.906796693801881179772.82930493354797
p311482313.6664142608642581441272.44930481910706
p321773312.950354576110841670872.29048991203308
p331253612.9812731742858891234367.8763542175293
p341158213.5367550849914551114269.67934989929199
p351448713.4699332714080811309968.77509903907776
p361568813.1477956771850591732067.9144344329834
p371220012.650130748748781224867.00625324249268
p381128313.4859235286712651117067.53133893013
p391348013.1727778911590581286265.43386697769165
p401568213.0899877548217771556964.73360013961792
p4170088.108281373977661790624.470109462738037
p4269327.624598264694214631221.45367980003357
p4365296.635222673416138673317.159975051879883
p4472068.201093912124634819727.290011882781982
p4573847.414166450500488748921.240010738372803
p4661666.826710224151611720817.667112588882446
p4764348.080354928970337724925.64135766029358
p4862997.8948752880096436643822.5309157371521
p4963296.82571268081665676417.12479257583618
p5093138.6319098472595211088029.890727758407593
p5179138.980969190597534893931.077434062957764
p5293478.536164283752441972633.53241181373596
p5399469.4257862567901611114132.7076473236084
p5491788.4992961883544921056033.5239634513855
p5584659.157528400421143831832.04251146316528
p562271321.77771425247192423903144.6936798095703
p573358119.87682652473449730914142.13889384269714
p585650118.7248744964599646049138.9957413673401
p593273820.6597051620483438781140.89498019218445
p602320123.38042521476745624435128.45606589317322
p613144618.32096123695373529426122.40536570549011
p626351816.8770191669464138882126.1437463760376
p633202718.30001544952392634958120.8425030708313
p642334721.73286342620849624081118.14805221557617
p652848317.2887492179870632030115.24073910713196
p664080915.93437194824218838021116.89702320098877
p672990717.8990929126739529351125.08517384529114
p6

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询