问题描述
给定Ñ个工厂和米个顾客,开工厂需要一定的费用,一个工厂有一定的容量限制,每个顾客也有一定的需求,而每个顾客要选取某个工厂也需要一定的分配费用,现在要求找出一个分配方案,把顾客分配给不同的工厂,然后在可以满足所有顾客需求的前提下让所有的花费(开工厂的花费和分配的花费)最小。
问题分析:
解决思路
设集合I = {1,...,m}是所有设施
集合J = {1,...,n}是所有客户
对于每个客户都有一个需求,只能被一个设施提供
对于每个设施都有一个容量,是该设施最多能提供的容量
对于每个设施都有一个固定成本,当该设施开启的时候固定的开销
定义是设施j满足顾客我的要求的开销
对于每个设施i∈I,定义变量
对于每个设施i∈I,每个客户j∈J,定义变量
对于单源容量设施位置问题可以描述为如下
因为顾客一般都比设施多,所以只关注客户的成本,可以制定出如下策略:
1.遍历所有客户,对于每一个客户,将该客户安排到所有设施的成本进行从小到大排序
2.对排序好的成本进行遍历,假如该设施剩余的容量满足客户的要求,则将该客户安排到该设施
3.代码实现
import random
import math
import matplotlib.pyplot as plt
CAPACITY = []
OPENCOST = []
ASSIGNCOST = []
OPENSTATUS = []
DEMAND = []
FACNUM = 0
CUSNUM = 0
Num = 0
#读取文件,获取各项变量
def init(filepath):
with open(filepath, 'r') as f:
global FACNUM
global CUSNUM
global CAPACITY
global OPENCOST
global ASSIGNCOST
global OPENSTATUS
FACNUM, CUSNUM = f.readline().strip("\n").split()
FACNUM = int(FACNUM)
CUSNUM = int(CUSNUM)
OPENSTATUS = [0] * FACNUM
for i in range(FACNUM):
line = f.readline().strip("\n").split()
CAPACITY.append(int(line[0]))
OPENCOST.append(int(line[1]))
for i in range(int(CUSNUM / 10)):
line = f.readline().strip("\n").replace(' ', '').split(".")
for j in range(10):
DEMAND.append(int(line[j]))
for i in range(CUSNUM):
linetoread = int(FACNUM / 10)
temp = []
for j in range(linetoread):
line = f.readline().strip("\n").replace(' ', '').split(".")
for k in range(10):
temp.append(int(line[k]))
ASSIGNCOST.append(temp)
print(ASSIGNCOST)
def greedy():
global CAPACITY
capacity = CAPACITY.copy()
openstatus = [0] * FACNUM
totalcost = 0
assign = [-1] * CUSNUM
assigncost = 0
opencost = 0
for cus in range(CUSNUM):
facIndex = [] # the facilities may be chosen
for i in range(FACNUM):
if capacity[i] >= DEMAND[cus]:
facIndex.append(i)
# ASSIGNCOST for customer i
asforeach = ASSIGNCOST[cus]
# ASSIGNCOST + OPENCOST for customer i
temp = [sum(x) for x in zip(asforeach, OPENCOST)]
# select the min cost index
sindex = facIndex[0]
for i in facIndex:
if temp[i] < temp[sindex]:
sindex = i
openstatus[sindex] = 1
capacity[sindex] = capacity[sindex] - DEMAND[cus]
assign[cus] = s