Capacitated Facility Location Problem容量有限设施选址问题

Capacitated Facility Location Problem

问题如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
给出所有工厂的容量和开工厂的成本,所有客户的需求,以及客户分配给某个工厂的的分配成本,要求解的问题是:找出一个分配方案,使得总成本最低。
实例数据下载地址:Download: p1-p71

算法思路

思路一:贪心

容易想到的是,从每个用户的角度出发,要使得总成本最小的话,则可以每个用户选择设施的时候都贪心选择一个成本最低的设施。一开始我想的是所有设施都先不开,然后由每个用户去贪心选择,计算选择一个设施需要的成本,如果设施还没开的话,则要加上开设施的成本,最后选择成本最低的那个。但后来仔细一想,其实这样是不太符合贪心策略的,因为用户肯定会倾向于选择已经开过的设施,这样用户就不能真正选择到分配成本更低的设施,所以不能充分利用到贪心的特点。所以不应该让设施的开与不开对选择造成太大的影响,一个简单的做法就是事先决定要开哪些设施,然后在开的设施里面贪心选择。我把所有工厂都开了,然后跑出来的效果确实比一开始的想法要好。
下面是python代码实现:
首先先建立好需要用到的类。

  • 设施类:

    class Facility:
        def __init__(self):
            self.capacity = 0  # 总容量
            self.opening_cost = 0  # 开启成本
            self.rest = 0  # 剩余容量
    
  • 用户类

    class Customer:
      def __init__(self):
          self.demand = 0  # 需求量
          self.assign_cost = []  # 某设备分派给用户的成本
    
  • 系统类

    class System:
        def __init__(self, fnum, cnum):
            self.fnum = fnum  # 设备数量
            self.cnum = cnum  # 用户数量
            self.facilities = []
            self.status = [0] * self.fnum  # 工厂状态
            self.customers = []
            self.assignment = [0] * self.cnum  # 每个用户分配到哪个设备
            self.total_cost = 0  # 总成本
            self.best_assignment = []
    
        def show(self):
            print('result', self.total_cost)
            print('status', self.status)
            print('assignment:', self.assignment)
         ...
         
    

    在系统类里面添加贪心算法:

# 贪心算法
def greed(self, status):
    facilities = copy.deepcopy(self.facilities)
    customers = copy.deepcopy(self.customers)
    total_cost = 0
    self.assignment = [-1] * self.cnum
    for i in range(self.fnum):  # 先计算开工厂的费用
        if status[i] == 1:
            total_cost += facilities[i].opening_cost
    for i in range(self.cnum):  # 为每个用户分配一个工厂
        min_cost = 999999999
        for j in range(self.fnum):  # 从已开的工厂中选择有足够剩余量、且费用最小的
            if status[j] == 1 and facilities[j].rest >= customers[i].demand:
                cost = customers
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值