12、前置分拣测算

# -*- coding: utf-8 -*-
"""
Created on Mon Jan 21 10:33:38 2019

@author: zhangchaoyu
"""

import re
import copy
import os
import math
import datetime
import sys
import wmi
import hashlib

def read_data_csv(f):
    
    #f=open(r'数据.csv')
    
    data = []
    f.readline()
    
    while(True):
        row = f.readline()
        if row == ',\n' or row == '':
            break
        row = re.split(',', row)
        row[1] = float(row[1])
        row[2] = float(row[2])
        row[4] = float(row[4])
        row[5] = float(row[5])
        if row[6] != "":   
            row[7] = float(row[7])
            row[8] = float(row[8])
        row[9] = int(math.ceil(float(row[9])))
        row[10] = int(math.ceil(float(row[10])))
        row[11] = float(row[11])
        row[12] = float(row[12])
        row[13] = float(row[13])
        row[14] = float(row[14])
        row[15] = float(row[15])
        row[16] = float(row[16])
        row[17] = float(row[17])
        row[18] = float(row[18])
        row[19] = float(row[19])
        row[20] = float(row[20])
        data.append(row)
    
    return data

def read_parameter_csv(f):
    
    #f=open(r'配置文件.csv')
    
    parameter = []
    
    #接货仓人员配置
    f.readline()
    for i in range(3):
        row = f.readline()
        row = re.split(',', row)
        parameter.append(float(row[1]))
    
    #前置分拣配置
    f.readline()
    f.readline()
    for i in range(3):
        row = f.readline()
        row = re.split(',', row)
        parameter.append(float(row[1]))
    
    #分拣中心配置
    f.readline()
    f.readline()
    row = f.readline()
    row = re.split(',', row)
    parameter.append(float(row[1]))
        
    #车辆配置
    vehicles = []
    f.readline()
    f.readline()
    f.readline()
    for i in range(2):
        row = f.readline()
        row = re.split(',', row)
        row[1] = float(row[1])
        row[2] = float(row[2])
        row[3] = float(row[3])
        row[4] = float(row[4])
        row[5] = float(row[5])
        row[6] = float(row[6])
        vehicles.append(row) 
    parameter.append(vehicles)
    
    #依据单量百分比确定个数
    f.readline()
    f.readline()
    row = f.readline()
    row = re.split(',', row)
    parameter.append(float(row[1]))
    
    #车辆复用规则
    f.readline()
    f.readline()
    f.readline()
    cycle = []
    for i in range(3):
        row = f.readline()
        row = re.split(',', row)
        row[0] = float(re.split('-',row[0])[0])
        row[1] = float(row[1])
        cycle.append(row[:2])
    parameter.append(cycle)
    
    f.readline()
    f.readline()
    f.readline()
    warehouses = []
    while(True):
        row = f.readline()
        if row == ',\n' or row == '':
            break
        row = re.split(',', row)
        row[1] = float(row[1])
        row[2] = float(row[2])
        row[3] = float(row[3])
        row[4] = float(row[4])
        warehouses.append(row[:5])
    
    parameter.append(warehouses)
    
    return parameter

def data_clean(data, parameter):
    
    warehouses = parameter[10]
    
    ware = []
    for w in warehouses:
        ware.append(w[0])
        
    data1 = []
    for d in data:
        if d[0] in ware:
            data1.append(d)
    
    return data1

def data_base_read(data, parameter):
    
    #把仓和首分拣收集出来
    warehouses = parameter[10]
    delvs_first = []
    delvs_second = []
    for i in range(len(data)):
        if data[i][3:6] not in delvs_first:
            delvs_first.append(data[i][3:6])
        if data[i][6:9] not in delvs_second:
            delvs_second.append(data[i][6:9])
    warehouses.sort()
    delvs_first.sort()
    delvs_second.sort()
    
    return [warehouses, delvs_first, delvs_second]

def matrix_zero(m, n):
    M = []
    for i in range(m):
        temp = []
        for j in range(n):
            temp.append(0)
        M.append(temp)
    return M

def calculate_Spherical_distance(lat1, lng1, lat2, lng2):
    
    lat1 = lat1*math.pi/180
    lng1 = lng1*math.pi/180
    lat2 = lat2*math.pi/180
    lng2 = lng2*math.pi/180
    
    return  6371.393*math.acos(max(min(math.cos(lat1)*math.cos(lat2)*math.cos(lng1-lng2)+math.sin(lat1)*math.sin(lat2),1),-1))
    #return 6371.393*math.acos(math.cos(lat1)*math.cos(lat2)*math.cos(lng1-lng2)+math.sin(lat1)*math.sin(lat2))

def calculate_Spherical_distance_L_to_L(L_start, L_end):
    
    LL = []
    for i in range(len(L_start)):
        L = []
        for j in range(len(L_end)):
            L.append(calculate_Spherical_distance(L_start[i][1], L_start[i][2], L_end[j][1], L_end[j][2]))
        LL.append(copy.deepcopy(L))
        
    return LL

def L_vehicles_generate(warehouses, vehicles):
    
    L_vehicles = []
    
    for ware in warehouses:
        v_per = ware[3]*ware[4]
        vs = copy.deepcopy(vehicles)
        if v_per != 0:
            vs[0][4] = int(vs[0][4]/v_per)
            vs[0][5] = int(vs[0][5]/v_per)
            vs[1][4] = int(vs[1][4]/v_per)
            vs[1][5] = int(vs[1][5]/v_per)
        L_vehicles.append(vs)
    
    return L_vehicles

def solving_violence(X_set, Y_set, w11, w12, w21, w22):
    
    x_best = [X_set[i][0] for i in range(11)]
    y_best = [Y_set[i][0] for i in range(11)]
    c_best = sum([(w11+w12)*x_best[i] for i in range(11)]) + sum([(w21+w22)*y_best[i] for i in range(11)])
    
    """复杂度上限,超过上限时不计算"""
    limit_iteration = 1e6
    num_iteration = 1
    for i in range(len(X_set)):
        num_iteration *= len(X_set[i])
    if num_iteration > limit_iteration:
        return [x_best, y_best]
    
    for i0 in range(len(X_set[0])):
        x0 = X_set[0][i0]
        y0 = Y_set[0][i0]
        for i1 in range(len(X_set[1])):
            x1 = X_set[1][i1]
            y1 = Y_set[1][i1]
            for i2 in range(len(X_set[2])):
                x2 = X_set[2][i2]
                y2 = Y_set[2][i2]
                for i3 in range(len(X_set[3])):
                    x3 = X_set[3][i3]
                    y3 = Y_set[3][i3]
                    for i4 in range(len(X_set[4])):
                        x4 = X_set[4][i4]
                        y4 = Y_set[4][i4]
                        for i5 in range(len(X_set[5])):
                            x5 = X_set[5][i5]
                            y5 = Y_set[5][i5]
                            for i6 in range(len(X_set[6])):
                                x6 = X_set[6][i6]
                                y6 = Y_set[6][i6]
                                for i7 in range(len(X_set[7])):
                                    x7 = X_set[7][i7]
                                    y7 = Y_set[7][i7]
                                    for i8 in range(len(X_set[8])):
                                        x8 = X_set[8][i8]
                                        y8 = Y_set[8][i8]
                                        for i9 in range(len(X_set[9])):
                                            x9 = X_set[9][i9]
                                            y9 = Y_set[9][i9]
                                            for i10 in range(len(X_set[10])):
                                                x10 = X_set[10][i10]
                                                y10 = Y_set[10][i10]
                                                c = (w11+w12)*(x0+x1+x2+x3+x4+x5+x6+x7+x8+x9+x10) + (w21+w22)*(y0+y1+y2+y3+y4+y5+y6+y7+y8+y9+y10)
                                                if c_best > c:
                                                    c_best = c
                                                    x_best = [x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10]
                                                    y_best = [y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10]

    return [x_best, y_best]

def sub_calculate_cost(nums, dis, vehicles, L_frequency, is_tray):
    
    if dis <= L_frequency[1][0]:
        frequency = L_frequency[0][1]
    elif dis <= L_frequency[2][0]:
        frequency = L_frequency[1][1]
    else:
        frequency = L_frequency[2][1]
    
    w11 = (vehicles[0][1] + vehicles[0][2])/frequency
    w12 = vehicles[0][3]*dis*2
    w21 = (vehicles[1][1] + vehicles[1][2])/frequency
    w22 = vehicles[1][3]*dis*2
    
    if is_tray:
        A = [vehicles[0][5], vehicles[1][5]]
    else:
        A = [vehicles[0][4], vehicles[1][4]]
    
    X_set = []
    Y_set = []
    
    for i in range(11):
        Xi_set = []
        Yi_set = []
        max_xi = math.ceil(nums[i]/A[0])
        max_yi = math.ceil(nums[i]/A[1])
        if max_xi <= max_yi:
            for j in range(max_xi+1):
                Xi_set.append(j)
                Yi_set.append(max(math.ceil((nums[i]-j*A[0])/A[1]),0))
        else:
            for j in range(max_yi+1):
                Yi_set.append(j)
                Xi_set.append(max(math.ceil((nums[i]-j*A[1])/A[0]),0))
        X_set.append(Xi_set)
        Y_set.append(Yi_set)
    
    result_violence = solving_violence(X_set, Y_set, w11, w12, w21, w22)
    
    x_best = result_violence[0]
    y_best = result_violence[1]
    
    cost_fixed = w11*sum(x_best) + w21*sum(y_best)
    cost_variable = w12*sum(x_best) + w22*sum(y_best)
    cost_all = cost_fixed + cost_variable
    
    return [cost_all, cost_variable, cost_fixed] + x_best + y_best

def output_original(cost_all, cost_ware, ware_to_first, name):
    
    if os.path.exists(name):
        os.remove(name)
    
    f1 = open(name, "a" , encoding = 'gb18030')
    
    f1.write("总成本\n")
    f1.write(str(cost_all) + "\n")
    
    f1.write("\n")
    f1.write("仓成本\n")
    f1.write("仓,仓总单量,仓总成本,")
    f1.write("单10_11,单1,单2,单3,单4,单5,单6,单7,单8,单9,单10,")
    f1.write("cost_10_11,cost_1,cost_2,cost_3,cost_4,cost_5,cost_6,cost_7,cost_8,cost_9,cost_10\n")
    for i in range(len(cost_ware)):
        for j in range(len(cost_ware[i])):
            f1.write(str(cost_ware[i][j]))
            f1.write(',')
        f1.write('\n')
    
    f1.write("\n")
    f1.write("仓至首分拣成本\n")
    f1.write("接货仓,首分拣,距离,")
    f1.write("总运单量,单10_11,单1,单2,单3,单4,单5,单6,单7,单8,单9,单10,")
    f1.write("运输成本,固定成本,变动成本,")
    f1.write("9m6_10_11,9m6_1,9m6_2,9m6_3,9m6_4,9m6_5,9m6_6,9m6_7,9m6_8,9m6_9,9m6_10,")
    f1.write("7m6_10_11,7m6_1,7m6_2,7m6_3,7m6_4,7m6_5,7m6_6,7m6_7,7m6_8,7m6_9,7m6_10\n")
    
    for i in range(len(ware_to_first)):
        for j in range(len(ware_to_first[i])):
            f1.write(str(ware_to_first[i][j]))
            f1.write(',')
        f1.write('\n')
    f1.close()

def txt_process(s):
    if os.path.exists("process.txt"):
        os.remove("process.txt")
    f1 = open("process.txt", "a" , encoding = 'gb18030')
    f1.write(s)
    f1.close()

def calculate_cost_original(data, data_base, parameter, output_path):
    
    warehouses = data_base[0]
    delvs_first = data_base[1]
    
    D_ware = {}
    D_delv = {}
    
    for i in range(len(warehouses)):
        D_ware[warehouses[i][0]] = i
    for i in range(len(delvs_first)):
        D_delv[delvs_first[i][0]] = i
    
    """初始化单量矩阵"""
    order = []
    for i in range(11):
        order.append(matrix_zero(len(warehouses),len(delvs_first)))
    
    for d in data:
        for i in range(11):
            order[i][D_ware[d[0]]][D_delv[d[3]]] += d[10+i]
        
    Dis = calculate_Spherical_distance_L_to_L(warehouses, delvs_first)
    
    """单量、距离归纳好了,开始计算原始成本"""
    
    cost_ware = []
    for i in range(len(warehouses)):
        nums_ware_i = []
        for k in range(len(order)):
            nums_k = 0
            for j in range(len(delvs_first)):
                nums_k += order[k][i][j]
            nums_ware_i.append(nums_k)
        cost_ware_i = [nums_ware_i[k]*parameter[2]/parameter[0] for k in range(len(nums_ware_i))]
        cost_ware.append([warehouses[i][0], sum(nums_ware_i), sum(cost_ware_i)] + nums_ware_i + cost_ware_i)
    
    ware_to_first = []
    L_vehicles = L_vehicles_generate(warehouses, parameter[7])
    
    flag = 0
    for i in range(len(warehouses)):
        for j in range(len(delvs_first)):
            nums = []
            for k in range(len(order)):
                nums.append(order[k][i][j])
            """根据单量、距离、车辆、频率计算成本"""
            if sum(nums) == 0 or Dis[i][j] == 0:
                ware_to_first.append([warehouses[i][0], delvs_first[j][0], Dis[i][j], sum(nums)] + nums + [0 for i in range(25)])
            else:
                flag += 1
                print("原始成本第"+str(flag)+"条路线成本测算")
                #txt_process("原始成本第"+str(flag)+"条路线成本测算")
                cost_and_vehicle = sub_calculate_cost(nums, Dis[i][j], L_vehicles[i], parameter[9], True)
                ware_to_first.append([warehouses[i][0], delvs_first[j][0], Dis[i][j], sum(nums)] + nums + cost_and_vehicle)
    
    cost_all = 0
    for i in range(len(warehouses)):
        cost_all += cost_ware[i][2]
    for i in range(len(ware_to_first)):
        cost_all += ware_to_first[i][15]
    
    output_original(cost_all, cost_ware, ware_to_first, output_path+"\\original.csv")
        
    return
    

"""优化计算部分"""  
"""
def clusters_plot(warehouses, L_w):
    x = []
    y = []
    col = []
    for i in range(len(warehouses)):
        x.append(warehouses[i][1])
        y.append(warehouses[i][2])
        col.append(L_w[i])
    plt.scatter(x,y,c = col)
"""
def solving_violence_10_11(Xi_set, Yi_set, w11, w12, w21, w22):
    
    x_best = Xi_set[0]
    y_best = Yi_set[0]
    c_best = (w11+w12)*x_best + (w21+w22)*y_best
    
    for i in range(1,len(Xi_set)):
        x = Xi_set[i]
        y = Yi_set[i]
        c = (w11+w12)*x + (w21+w22)*y
        if c_best > c:
            c_best = c
            x_best = x
            y_best = y
            
    return [x_best, y_best]

def sub_calculate_cost_10_11(num, dis, vehicles, L_frequency, is_tray):
    #sub_calculate_cost_10_11(order_ware_to_first[i][j], Dis_ware_to_first[i][j], L_vehicles[i], parameter[9], True)
    
    if dis <= L_frequency[1][0]:
        frequency = L_frequency[0][1]
    elif dis <= L_frequency[2][0]:
        frequency = L_frequency[1][1]
    else:
        frequency = L_frequency[2][1]
    
    w11 = (vehicles[0][1] + vehicles[0][2])/frequency
    w12 = vehicles[0][3]*dis*2
    w21 = (vehicles[1][1] + vehicles[1][2])/frequency
    w22 = vehicles[1][3]*dis*2
    
    if is_tray:
        A = [vehicles[0][5], vehicles[1][5]]
    else:
        A = [vehicles[0][4], vehicles[1][4]]
    
    Xi_set = []
    Yi_set = []
    max_xi = math.ceil(num/A[0])
    max_yi = math.ceil(num/A[1])
    if max_xi <= max_yi:
        for j in range(max_xi+1):
            Xi_set.append(j)
            Yi_set.append(max(math.ceil((num-j*A[0])/A[1]),0))
    else:
        for j in range(max_yi+1):
            Yi_set.append(j)
            Xi_set.append(max(math.ceil((num-j*A[1])/A[0]),0))
    
    result_violence = solving_violence_10_11(Xi_set, Yi_set, w11, w12, w21, w22)
    
    x_best = result_violence[0]
    y_best = result_violence[1]
    
    cost_fixed = w11*x_best + w21*y_best
    cost_variable = w12*x_best + w22*y_best
    cost_all = cost_fixed + cost_variable
    
    return [cost_all, cost_variable, cost_fixed, x_best, y_best]

def solving_violence_ware_to_front(X_set, Y_set, w11, w12, w21, w22):
    
    x_best = [X_set[i][0] for i in range(10)]
    y_best = [Y_set[i][0] for i in range(10)]
    c_best = sum([(w11+w12)*x_best[i] for i in range(10)]) + sum([(w21+w22)*y_best[i] for i in range(10)])
    
    """复杂度上限,超过上限时不计算"""
    limit_iteration = 1e6
    num_iteration = 1
    for i in range(len(X_set)):
        num_iteration *= len(X_set[i])
    if num_iteration > limit_iteration:
        return [x_best, y_best]
    
    for i0 in range(len(X_set[0])):
        x0 = X_set[0][i0]
        y0 = Y_set[0][i0]
        for i1 in range(len(X_set[1])):
            x1 = X_set[1][i1]
            y1 = Y_set[1][i1]
            for i2 in range(len(X_set[2])):
                x2 = X_set[2][i2]
                y2 = Y_set[2][i2]
                for i3 in range(len(X_set[3])):
                    x3 = X_set[3][i3]
                    y3 = Y_set[3][i3]
                    for i4 in range(len(X_set[4])):
                        x4 = X_set[4][i4]
                        y4 = Y_set[4][i4]
                        for i5 in range(len(X_set[5])):
                            x5 = X_set[5][i5]
                            y5 = Y_set[5][i5]
                            for i6 in range(len(X_set[6])):
                                x6 = X_set[6][i6]
                                y6 = Y_set[6][i6]
                                for i7 in range(len(X_set[7])):
                                    x7 = X_set[7][i7]
                                    y7 = Y_set[7][i7]
                                    for i8 in range(len(X_set[8])):
                                        x8 = X_set[8][i8]
                                        y8 = Y_set[8][i8]
                                        for i9 in range(len(X_set[9])):
                                            x9 = X_set[9][i9]
                                            y9 = Y_set[9][i9]
                                            c = (w11+w12)*(x0+x1+x2+x3+x4+x5+x6+x7+x8+x9) + (w21+w22)*(y0+y1+y2+y3+y4+y5+y6+y7+y8+y9)
                                            if c_best > c:
                                                c_best = c
                                                x_best = [x0,x1,x2,x3,x4,x5,x6,x7,x8,x9]
                                                y_best = [y0,y1,y2,y3,y4,y5,y6,y7,y8,y9]
                                                

    return [x_best, y_best]


def sub_calculate_cost_ware_to_front(nums, dis, vehicles, L_frequency, is_tray):
    
    if dis <= L_frequency[1][0]:
        frequency = L_frequency[0][1]
    elif dis <= L_frequency[2][0]:
        frequency = L_frequency[1][1]
    else:
        frequency = L_frequency[2][1]
    
    w11 = (vehicles[0][1] + vehicles[0][2])/frequency
    w12 = vehicles[0][3]*dis*2
    w21 = (vehicles[1][1] + vehicles[1][2])/frequency
    w22 = vehicles[1][3]*dis*2
    
    if is_tray:
        A = [vehicles[0][5], vehicles[1][5]]
    else:
        A = [vehicles[0][4], vehicles[1][4]]
    
    X_set = []
    Y_set = []
    
    for i in range(10):
        Xi_set = []
        Yi_set = []
        max_xi = math.ceil(nums[i]/A[0])
        max_yi = math.ceil(nums[i]/A[1])
        if max_xi <= max_yi:
            for j in range(max_xi+1):
                Xi_set.append(j)
                Yi_set.append(max(math.ceil((nums[i]-j*A[0])/A[1]),0))
        else:
            for j in range(max_yi+1):
                Yi_set.append(j)
                Xi_set.append(max(math.ceil((nums[i]-j*A[1])/A[0]),0))
        X_set.append(Xi_set)
        Y_set.append(Yi_set)
    
    result_violence = solving_violence_ware_to_front(X_set, Y_set, w11, w12, w21, w22)
    
    x_best = result_violence[0]
    y_best = result_violence[1]
    
    cost_fixed = w11*sum(x_best) + w21*sum(y_best)
    cost_variable = w12*sum(x_best) + w22*sum(y_best)
    cost_all = cost_fixed + cost_variable
    
    return [cost_all, cost_variable, cost_fixed] + x_best + y_best

def vehicles_front_to_second_generate(L_vehicles):
    
    vehicles_front_to_second = copy.deepcopy(L_vehicles[0])
    vehicles_front_to_second[0][4] = sum([L_vehicles[i][0][4] for i in range(len(L_vehicles))])/len(L_vehicles)
    vehicles_front_to_second[0][5] = sum([L_vehicles[i][0][5] for i in range(len(L_vehicles))])/len(L_vehicles)
    vehicles_front_to_second[1][4] = sum([L_vehicles[i][1][4] for i in range(len(L_vehicles))])/len(L_vehicles)
    vehicles_front_to_second[1][5] = sum([L_vehicles[i][1][5] for i in range(len(L_vehicles))])/len(L_vehicles)
    return vehicles_front_to_second

def order_distribute(order_front_to_second, vehicles_front_to_second, idex_second):
    
    num_big = vehicles_front_to_second[0][4]
    num_small = vehicles_front_to_second[1][4]
    
    order_direct = []
    order_left = []
    rate = []
    for i in range(len(order_front_to_second)):
        order_direct.append(matrix_zero(len(order_front_to_second[i]),len(order_front_to_second[i][0])))
        order_left.append(matrix_zero(len(order_front_to_second[i]),len(order_front_to_second[i][0])))
        rate.append(matrix_zero(len(order_front_to_second[i]),len(order_front_to_second[i][0])))
    
    for i in range(len(order_front_to_second)):
        for j in range(len(order_front_to_second[i])):
            for k in range(len(order_front_to_second[i][j])):
                left = order_front_to_second[i][j][k]%num_big%num_small
                if k == idex_second:
                    left = order_front_to_second[i][j][k]
                order_direct[i][j][k] = order_front_to_second[i][j][k] - left
                order_left[i][j][k] = left
                if order_direct[i][j][k] > 0:
                    rate[i][j][k] = left/order_direct[i][j][k]
    
    return [order_direct, order_left, rate]
    
def output_front(cost_all, num_ware_10_11, cost_ware_10_11, num_front, cost_front, result_ware_to_first, 
                 result_ware_to_front, result_front_to_second, result_front_to_first, warehouses, delvs_first, 
                 delvs_second, delvs_front, name):
    
    if os.path.exists(name):
        os.remove(name)
    
    f1 = open(name, "a" , encoding = 'gb18030')
    
    f1.write("成本项,成本,单量\n")
    f1.write("总成本," + str(cost_all) + "\n")
    f1.write("仓," + str(sum(cost_ware_10_11)) + "," + str(sum(num_ware_10_11)) + "\n")
    f1.write("前置分拣," + str(sum(cost_front)) + "," + str(sum(num_front)) + "\n")
    f1.write("仓-首分拣," + str(sum([result_ware_to_first[i][4] for i in range(len(result_ware_to_first))])) + "," + 
             str(sum([result_ware_to_first[i][3] for i in range(len(result_ware_to_first))])) + "\n")
    f1.write("仓-前置分拣," + str(sum([result_ware_to_front[i][14] for i in range(len(result_ware_to_front))])) + "," + 
             str(sum([result_ware_to_front[i][3] for i in range(len(result_ware_to_front))])) + "\n")
    f1.write("前置分拣-首分拣," + str(sum([result_front_to_first[i][14] for i in range(len(result_front_to_first))])) + "," + 
             str(sum([result_front_to_first[i][3] for i in range(len(result_front_to_first))])) + "\n")
    f1.write("前置分拣-二分拣," + str(-sum([result_front_to_second[i][13] for i in range(len(result_front_to_second))])) + "," + 
             str(sum([result_front_to_second[i][2] for i in range(len(result_front_to_second))])) + "\n")
    
    f1.write("\n")
    f1.write("仓成本\n")
    f1.write("仓,仓总成本,仓总单量\n")
    for i in range(len(warehouses)):
        f1.write(warehouses[i][0]+","+str(cost_ware_10_11[i])+","+str(num_ware_10_11[i])+"\n")
    
    f1.write("\n")
    f1.write("前置分拣成本\n")
    f1.write("前置分拣,前置分拣总成本,前置分拣总单量\n")
    for i in range(len(delvs_front)):
        f1.write(delvs_front[i][0]+","+str(cost_front[i])+","+str(num_front[i])+"\n")
    
    f1.write("\n")
    f1.write("仓-首分拣\n")
    f1.write("接货仓,首分拣,距离,总运单量,运输成本,固定成本,变动成本,9m6_10_11,7m6_10_11\n")
    for i in range(len(result_ware_to_first)):
        for j in range(len(result_ware_to_first[i])):
            f1.write(str(result_ware_to_first[i][j]))
            f1.write(',')
        f1.write('\n')
        
    f1.write("\n")
    f1.write("仓-前置分拣\n")
    f1.write("接货仓,前置分拣,距离,")
    f1.write("总运单量,单1,单2,单3,单4,单5,单6,单7,单8,单9,单10,")
    f1.write("运输成本,固定成本,变动成本,")
    f1.write("9m6_1,9m6_2,9m6_3,9m6_4,9m6_5,9m6_6,9m6_7,9m6_8,9m6_9,9m6_10,")
    f1.write("7m6_1,7m6_2,7m6_3,7m6_4,7m6_5,7m6_6,7m6_7,7m6_8,7m6_9,7m6_10\n")
    for i in range(len(result_ware_to_front)):
        for j in range(len(result_ware_to_front[i])):
            f1.write(str(result_ware_to_front[i][j]))
            f1.write(',')
        f1.write('\n')
        
    f1.write("\n")
    f1.write("前置分拣-首分拣\n")
    f1.write("前置分拣,首分拣,距离,")
    f1.write("总运单量,单1,单2,单3,单4,单5,单6,单7,单8,单9,单10,")
    f1.write("运输成本,固定成本,变动成本,")
    f1.write("9m6_1,9m6_2,9m6_3,9m6_4,9m6_5,9m6_6,9m6_7,9m6_8,9m6_9,9m6_10,")
    f1.write("7m6_1,7m6_2,7m6_3,7m6_4,7m6_5,7m6_6,7m6_7,7m6_8,7m6_9,7m6_10\n")
    for i in range(len(result_front_to_first)):
        for j in range(len(result_front_to_first[i])):
            f1.write(str(result_front_to_first[i][j]))
            f1.write(',')
        f1.write('\n')
    
    f1.write("\n")
    f1.write("前置分拣-二分拣\n")
    f1.write("前置分拣,二分拣,")
    f1.write("总运单量,单1,单2,单3,单4,单5,单6,单7,单8,单9,单10,")
    f1.write("降低成本,1,2,3,4,5,6,7,8,9,10\n")
    for i in range(len(result_front_to_second)):
        for j in range(len(result_front_to_second[i])):
            f1.write(str(result_front_to_second[i][j]))
            f1.write(',')
        f1.write('\n')
    f1.close()

def sub_calculate_cost_front(data, warehouses, delvs_first, delvs_second, parameter, delvs_front, flag_print, output_path):
    
    #根据仓库数据调整每种车型的规格
    L_vehicles = L_vehicles_generate(warehouses, parameter[7])
    
    #创建下标字典
    D_ware = {}
    D_first = {}
    D_front = {}
    D_second = {}
    for i in range(len(warehouses)):
        D_ware[warehouses[i][0]] = i
    for i in range(len(delvs_first)):
        D_first[delvs_first[i][0]] = i
    for i in range(len(delvs_front)):
        D_front[delvs_front[i][0]] = i
    for i in range(len(delvs_second)):
        D_second[delvs_second[i][0]] = i
    
    #根据距离就近选择前置分拣
    L_w = []
    for i in range(len(warehouses)):
        idex = 0
        for j in range(len(delvs_front)):
            if calculate_Spherical_distance(warehouses[i][1], warehouses[i][2], delvs_front[idex][1], delvs_front[idex][2]) > calculate_Spherical_distance(warehouses[i][1], warehouses[i][2], delvs_front[j][1], delvs_front[j][2]):
                idex = j
        L_w.append(idex)
    
    #打印聚类结果
    #clusters_plot(warehouses, L_w)
    
    #前置分拣添加至运单数据
    data1 = copy.deepcopy(data)
    for i in range(len(data1)):
        data1[i] = data1[i] + delvs_front[L_w[D_ware[data1[i][0]]]]
    
    #统计10-11点的仓发出单量及结果仓成本
    num_ware_10_11 = [0 for i in range(len(warehouses))]
    for d in data1:
        num_ware_10_11[D_ware[d[0]]] += d[10]
    cost_ware_10_11 = [num_ware_10_11[i]*parameter[2]/parameter[1] for i in range(len(num_ware_10_11))]
    
    #前置分拣成本
    num_front = [0 for i in range(len(delvs_front))]
    for d in data1:
        num_front[D_front[d[21]]] += sum(d[11:21])
    cost_front = [num_front[i]*parameter[5] for i in range(len(num_front))]
    
    #仓到首分拣成本
    order_ware_to_first = matrix_zero(len(warehouses),len(delvs_first))
    
    for d in data1:
        order_ware_to_first[D_ware[d[0]]][D_first[d[3]]] += d[10]
        
    Dis_ware_to_first = calculate_Spherical_distance_L_to_L(warehouses, delvs_first)
    
    result_ware_to_first = []
    
    for i in range(len(warehouses)):
        for j in range(len(delvs_first)):
            if order_ware_to_first[i][j] == 0 or Dis_ware_to_first[i][j] == 0:
                """仓、首分拣、距离、10_11单量、运输成本、固定成本、变动成本、9m6_10_11、7m6_10_11"""
                result_ware_to_first.append([warehouses[i][0], delvs_first[j][0], Dis_ware_to_first[i][j], order_ware_to_first[i][j]] + [0 for i in range(5)])
            else:
                cost_and_vehicle = sub_calculate_cost_10_11(order_ware_to_first[i][j], Dis_ware_to_first[i][j], L_vehicles[i], parameter[9], True)
                result_ware_to_first.append([warehouses[i][0], delvs_first[j][0], Dis_ware_to_first[i][j], order_ware_to_first[i][j]] + cost_and_vehicle)
    
    #仓到前置分拣成本
    order_ware_to_front = []
    for i in range(10):
        order_ware_to_front.append(matrix_zero(len(warehouses),len(delvs_front)))
    
    for d in data1:
        for i in range(10):
            order_ware_to_front[i][D_ware[d[0]]][D_front[d[21]]] += d[11+i]
        
    Dis_ware_to_front = calculate_Spherical_distance_L_to_L(warehouses, delvs_front)
    
    result_ware_to_front = []
    
    flag = 0
    for i in range(len(warehouses)):
        for j in range(len(delvs_front)):
            nums = []
            for k in range(len(order_ware_to_front)):
                nums.append(order_ware_to_front[k][i][j])
            """根据单量、距离、车辆、频率计算成本"""
            if sum(nums) == 0 or Dis_ware_to_front[i][j] == 0:
                result_ware_to_front.append([warehouses[i][0], delvs_front[j][0], Dis_ware_to_front[i][j], sum(nums)] + nums + [0 for i in range(23)])
            else:
                flag += 1
                print("仓到前置分拣优化成本第"+str(flag)+"条路线成本测算")
                #txt_process("仓到前置分拣优化成本第"+str(flag)+"条路线成本测算")
                cost_and_vehicle = sub_calculate_cost_ware_to_front(nums, Dis_ware_to_front[i][j], L_vehicles[i], parameter[9], False)
                result_ware_to_front.append([warehouses[i][0], delvs_front[j][0], Dis_ware_to_front[i][j], sum(nums)] + nums + cost_and_vehicle)
    
    #前置分拣至二级分拣减少成本及明细
    order_front_to_second = []
    for i in range(10):
        order_front_to_second.append(matrix_zero(len(delvs_front),len(delvs_second)))
    
    for d in data1:
        for i in range(10):
            order_front_to_second[i][D_front[d[21]]][D_second[d[6]]] += d[11+i]
    
    vehicles_front_to_second = vehicles_front_to_second_generate(L_vehicles)
    result_distribute = order_distribute(order_front_to_second, vehicles_front_to_second, D_second[""])
    order_direct = result_distribute[0]
    result_front_to_second = []
    for i in range(len(delvs_front)):
        for j in range(len(delvs_second)):
            nums = []
            costs = []
            for k in range(len(order_direct)):
                nums.append(order_direct[k][i][j])
                costs.append(order_direct[k][i][j]*parameter[6])
            result_front_to_second.append([delvs_front[i][0], delvs_second[j][0], sum(nums)] + nums + 
                                           [sum(costs)] + costs)
                                           
    #前置分拣至首分拣成本
    rate_left = result_distribute[2]
    data2 = copy.deepcopy(data1)
    for i in range(len(data2)):
        for j in range(10):
            data2[i][11+j] = data2[i][11+j]*rate_left[j][D_front[data2[i][21]]][D_second[data2[i][6]]]
            
    order_front_to_first = []
    for i in range(10):
        order_front_to_first.append(matrix_zero(len(delvs_front),len(delvs_first)))
    
    for d in data2:
        for i in range(10):
            order_front_to_first[i][D_front[d[21]]][D_first[d[3]]] += d[11+i]
    
    Dis_front_to_first = calculate_Spherical_distance_L_to_L(delvs_front, delvs_first)
    
    result_front_to_first = []
    
    flag = 0
    for i in range(len(delvs_front)):
        for j in range(len(delvs_first)):
            nums = []
            for k in range(len(order_front_to_first)):
                nums.append(order_front_to_first[k][i][j])
            """根据单量、距离、车辆、频率计算成本"""
            if sum(nums) == 0 or Dis_front_to_first[i][j] == 0:
                result_front_to_first.append([delvs_front[i][0], delvs_first[j][0], Dis_front_to_first[i][j], sum(nums)] + nums + [0 for i in range(23)])
            else:
                flag += 1
                print("前置分拣到首分拣优化成本第"+str(flag)+"条路线成本测算")
                #txt_process("前置分拣到首分拣优化成本第"+str(flag)+"条路线成本测算")
                cost_and_vehicle = sub_calculate_cost_ware_to_front(nums, Dis_front_to_first[i][j], vehicles_front_to_second, parameter[9], True)
                result_front_to_first.append([delvs_front[i][0], delvs_first[j][0], Dis_front_to_first[i][j], sum(nums)] + nums + cost_and_vehicle)
    
    cost_all = 0
    cost_all += sum(cost_ware_10_11)
    cost_all += sum(cost_front)
    for i in range(len(result_ware_to_first)):
        cost_all += result_ware_to_first[i][4]
    for i in range(len(result_ware_to_front)):
        cost_all += result_ware_to_front[i][14]
    for i in range(len(result_front_to_first)):
        cost_all += result_front_to_first[i][14]
    for i in range(len(result_front_to_second)):
        cost_all -= result_front_to_second[i][13]
    
    if flag_print:
        output_front(cost_all, num_ware_10_11, cost_ware_10_11, num_front, cost_front, 
                 result_ware_to_first, result_ware_to_front, result_front_to_second,
                 result_front_to_first, warehouses, delvs_first, delvs_second, 
                 delvs_front, output_path + "\\front.csv")
        
    return cost_all

def delvs_possible_generate(warehouses, density):
    
    lat_min = warehouses[0][1]
    lat_max = warehouses[0][1]
    lng_min = warehouses[0][2]
    lng_max = warehouses[0][2]
    
    for ware in warehouses:
        if lat_min > ware[1]:
            lat_min = ware[1]
        if lat_max < ware[1]:
            lat_max = ware[1]
        if lng_min > ware[2]:
            lng_min = ware[2]
        if lng_max < ware[2]:
            lng_max = ware[2]

    delvs = []
    for i in range(density+1):
        for j in range(density+1):
            delvs.append(["delv_"+str(i*(density+1)+j), 
                          lat_min * (density - i) / density + lat_max * i / density, 
                          lng_min * (density - j) / density + lng_max * j / density])
    
    return delvs 

def order_count(warehouses, data):
    D_ware = {}
    for i in range(len(warehouses)):
        D_ware[warehouses[i][0]] = i
    order_sum = [0 for i in range(len(warehouses))]
    
    for d in data:
        order_sum[D_ware[d[0]]] += sum(d[11:])
    
    return order_sum
    
def distance_class(class1, class2):
    
    c1 = [0,0]
    c2 = [0,0]
    
    for i in range(len(class1)):
        c1[0] += class1[i][1]
        c1[1] += class1[i][2]
    
    c1[0] /= len(class1)
    c1[1] /= len(class1)
    
    for i in range(len(class2)):
        c2[0] += class2[i][1]
        c2[1] += class2[i][2]
    
    c2[0] /= len(class2)
    c2[1] /= len(class2)
    
    return calculate_Spherical_distance(c1[0],c1[1],c2[0],c2[1])

def clustering(warehouses, order_sum_warehouse, limit):
    
    clusters = []
    for i in range(len(warehouses)):
        clusters.append([copy.deepcopy(warehouses[i][:3])])
    
    L_w = []
    for i in range(len(warehouses)):
        L_w.append([order_sum_warehouse[i]])
    
    while True:
        print("聚类中,目前size="+str(len(clusters))+",       "+datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        #txt_process("聚类中,目前size="+str(len(clusters))+",       "+datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        idex1 = 0
        idex2 = 1
        flag = 0
        for i in range(len(clusters)-1):
            for j in range(i+1, len(clusters)):
                if (distance_class(clusters[i],clusters[j]) < distance_class(clusters[idex1],clusters[idex2]) and
                    sum(L_w[i]) + sum(L_w[j]) <= limit):
                    idex1 = i
                    idex2 = j
                    flag = 1
                    
        if flag == 0 and sum(L_w[idex1]) + sum(L_w[idex2]) > limit:
            break
        
        clusters_new = []
        L_w_new = []
        for i in range(len(clusters)):
            if i == idex1 or i == idex2:
                continue
            clusters_new.append(copy.deepcopy(clusters[i]))
            L_w_new.append(copy.deepcopy(L_w[i]))
        clusters_new.append(copy.deepcopy(clusters[idex1]+clusters[idex2]))
        L_w_new.append(copy.deepcopy(L_w[idex1]+L_w[idex2]))
        clusters = clusters_new
        L_w = L_w_new
    
    delvs_front = []
    for i in range(len(clusters)):
        idex = 0
        for j in range(len(clusters[i])):
            if L_w[i][idex] < L_w[i][j]:
                idex = j
        delvs_front.append(["delv_"+str(i)] + clusters[i][idex][1:])
    
    return delvs_front

def calculate_cost_front(data, data_base, parameter, output_path):
    
    warehouses = data_base[0]
    delvs_first = data_base[1]
    delvs_second = data_base[2]
    
    #delvs_possible = delvs_possible_generate(warehouses, 20)
    limit = parameter[3]*parameter[4]
    order_sum_warehouse = order_count(warehouses, data)
    delvs_front = clustering(warehouses, order_sum_warehouse, limit)

    """
    delvs_front = [["北京周边",39.69139,116.5659],
                   ["济南",36.82950057,117.0835159],
                   ["青岛",36.11402742,120.103142],
                   ["石家庄太原临汾",37.4018790899999,114.063889899999],
                   ["呼和浩特",40.74075379,111.90701415]]
    """
    cost_front = sub_calculate_cost_front(data, warehouses, delvs_first, delvs_second, parameter, delvs_front, True, output_path)
    
    """
    result_greedy = calculate_greedy(warehouses, delvs_first, delvs_second, parameter, data, 10)
    delvs_best_local = result_greedy[0]
    front_map_best_local = result_greedy[1]
    """
    
    return 


def validCaptcha(code):
    """
    验证License是否正确
    """
    if code is None or code.strip() == '' :
        return False
    
    temp = code.split(':')
    erp = temp[0];
    captach = temp[1];
    
    w=wmi.WMI() 
    cpu_id=w.Win32_Processor()[0].ProcessorId
    
    licenseCode = erp + '::' + cpu_id
    m = hashlib.md5()
    m.update(licenseCode.encode("utf-8"))
    md5 = m.hexdigest().upper()
    return captach == md5

if __name__ == "__main__":
    
    parameter_path = r'配置文件.csv'
    data_path = r"数据.csv"
    output_path = os.getcwd()
    password = ""
    
    print(sys.argv)
    print([parameter_path,data_path,output_path,password])
    if len(sys.argv) >= 2:
        parameter_path = sys.argv[1]
    if len(sys.argv) >= 3:
        data_path = sys.argv[2]
    if len(sys.argv) >= 4:
        output_path = sys.argv[3]
    if len(sys.argv) >= 5:
        password = sys.argv[4]
        
    #password = 'dbwcyang:40A7DC7B71AE12684B97D9DAE2DBA6F4'
    print('License['+password+']验证...')    
    #验证license
    if not validCaptcha(password):
        print('License验证失败,无权使用该程序')
        sys.exit(0)
    print('License['+password+']验证成功')
    
    print([parameter_path,data_path,output_path,password])
    
    print("读取参数")
    """
    原人效(单/人/天)、新人效(只考虑10-11点)、人均工资(元/天/人)、坪效(单/平方米)、
    最大面积(平方米)、操作成本(元/单)、直发二级分拣节省的操作成本(元/单)、车辆配置、
    依据单量百分比确定个数、车辆复用规则
    """
    parameter = read_parameter_csv(open(parameter_path))
    print("读取数据")
    data = read_data_csv(open(data_path))
    #根据parameter中接货仓的信息筛选订单
    data = data_clean(data, parameter)
    #仓、首分拣、二分拣
    data_base = data_base_read(data, parameter)
    print("开始计算")
    #计算原始成本
    calculate_cost_original(data, data_base, parameter, output_path)
    #计算优化成本
    calculate_cost_front(data, data_base, parameter, output_path)
    #txt_process("end")
    print("end")

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值