2022年华中杯A题(暂时做完第一小问,附完整Python源码)

2023-11-19

目的

        虽然比赛时间过去了,但还是可以拿来练一练优化问题的解决,加强自己对于优化算法的巩固。


文章目录

   练题。


一、题目

 

二、思路

1.第一小题:分批算法

利用订单与订单之间经过去重后的商品种类的的相似度,即重合度,每批初始的第一个订单编号为未使用过订单列表中商品种类最多的订单。

 程序思路

三、程序

导入需要的库

import random
import time
import pandas as pd
import math
from collections import Counter
import numpy as np
import os
os.chdir(r'D:\86176\Desktop\6月17日建 订单分拣')
from numba import jit

1.计算相似度的函数

def counter_cosine_similarity(c1, c2):
    '''# 计算列表余弦相似度'''
    c1 = Counter(c1)
    c2 = Counter(c2)
    terms = set(c1).union(c2)
    dotprod = sum(c1.get(k, 0) * c2.get(k, 0) for k in terms)
    magA = math.sqrt(sum(c1.get(k, 0)**2 for k in terms))
    magB = math.sqrt(sum(c2.get(k, 0)**2 for k in terms))

    return dotprod / (magA * magB)

def counter_euler_distance(x, y):
    '''
    输入两个等长数组,计算欧拉距离
    :param x:
    :param y:
    :return: 两个数组之间的欧拉距离对应的相似度
    '''
    return 1 / (1 + np.sqrt(np.sum((x - y) ** 2)))

def two_array_similarity(x, y):
    '''
    通过识别两个相同长度的数组对应位置是否有值来计算相似度
    '''
    return np.sum((x > 0) * (y > 0)) / np.sum((y > 0))

2.分批算法主要部分 

初始化

data = pd.read_csv('附件1:订单信息.csv')

OrderNo = list(pd.unique(data.loc[:, 'OrderNo']))
ItemNo = list(pd.unique(data.loc[:, 'ItemNo']))
Ot = len(OrderNo) # 订单种类
Gt = len(ItemNo) # 货物种类
N = 200 # 一个批次的最大货品种类数
print("列名:" + ' '.join(data.columns))
print("订单种类:", Ot, "种")
print("货品种类:", Gt, "种")
# Start = time.time()
Order_list = []
Order_nums = []
for i in range(Ot):
    Order_list.append(list(data.loc[data['OrderNo'] == OrderNo[i], 'ItemNo']))
    Order_nums.append(len(np.unique(Order_list[-1])))

(1)首先生成想要的相似度矩阵 

 对应函数保存数据

Similars = np.zeros((Ot, Ot))
for i in range(Ot):
    for j in range(i + 1, Ot):
        Similars[i, j] = counter_cosine_similarity(Order_list[i], Order_list[j])
        Similars[j, i] = Similars[i, j]
np.save('Similars', Similars)

 商品数据数组化

# 将商品处理为数组坐标的形式,用于求商品之间的相似度
Order_Goods = pd.DataFrame(np.zeros((Ot, Gt)))
Order_Goods.columns = list(pd.unique(data.loc[:, 'ItemNo']))

for i in range(Ot):
    for j in Counter(Order_list[i]).items():
        Order_Goods.loc[i, j[0]] += j[1]
Order_Goods.index = list(pd.unique(data.loc[:, 'OrderNo']))

 欧拉距离为基础的相似度矩阵

Order_Goods_mat = Order_Goods.values
Eu_distance = np.zeros((Ot, Ot))
for i in range(Ot):
    for j in range(i + 1, Ot):
        Eu_distance[i, j] = counter_euler_distance(Order_Goods_mat[i, :], Order_Goods_mat[j, :])
        Eu_distance[j, i] = Eu_distance[i, j]
np.save('Eu_distance', Eu_distance)

 for循环加速(其实运行速度还行,就是想试试)

start = time.time()
Order_Goods_mat = Order_Goods.values
simple_similarity = np.zeros((Ot, Ot))
for i in range(Ot):
    j_list = set(range(Ot)) - set([i])
    for j in j_list:
        simple_similarity[i, j] = two_array_similarity(Order_Goods_mat[i, :], Order_Goods_mat[j, :])
    print(f"已完成第{i+1}个订单的相似度计算")
np.save('simple_similarity', simple_similarity)
end = time.time()
print("加速前:", end - start)

@jit(parallel=True)
def dump():
    for i in range(10):
        j_list = set(range(Ot)) - set([i])
        for j in j_list:
            simple_similarity[i, j] = two_array_similarity(Order_Goods_mat[i, :], Order_Goods_mat[j, :])
        print(f"已完成第{i+1}个订单的相似度计算")

start = time.time()
dump()
end = time.time()
print("加速后:", end - start)

 (2)主程序(可以将上述求相似度的部分都给注释掉)

所需函数

def Batch_size(path):
    '''根据确定好的所有路径计算总批次'''
    temp = []
    batch = 1
    for i in path:
        temp.extend(Order_list[i])
        temp = list(pd.unique(temp))
        if len(temp) > 200:
            batch += 1
            temp = []
            temp.extend(Order_list[i])
    return batch

def copy_list(old_list):
    '''用来复制列表,是新复制的变量不回改变被赋值的变量'''
    new_list = []
    for element in old_list:
        new_list.append(element)
    return new_list

 主函数

# 下面两种函数功能一样,是我用来调试的,目的是用来观察while循环里嵌套什么语句较好
def get_best_orderId(orderId_list: [str], unUsed: list) -> str:
    '''
        找出某个订单对应符合条件的另一个订单Id,条件是:先判断种类和<=200,
    再找到未使用订单的与其相似度最高的订单Id
    :param orderId_list: 需要配对的订单Id列表
    :param unUsed: 未被使用过的订单列表
    :return: 订单编号
    '''
    # orderId = 'D0898'
    # Start = time.time()
    orderId_list = [OrderNo.index(i) for i in orderId_list]
    orderId = orderId_list[-1]
    # Eu_distance[OrderNo.index(orderId), 638]
    unUsed = [OrderNo.index(i) for i in unUsed]
    x = np.sort(Eu_distance[orderId, :])[::-1] # 降序
    res = np.argsort(-Eu_distance[orderId, :]) # 降序,返回的结果是排完序后对应原先数组的索引值
    for u in np.unique(x)[::-1]:
        # flag = 0
        idx = x == u
        tlist = list(res[idx])
        random.shuffle(tlist) # 在与该需要配对订单相似度相同的订单里随机选一个订单
        # 求交集:保证所求Id在未被使用的Id列表中
        tlist = list(set(tlist) & set(unUsed))
        # print(len(tlist))
        if len(tlist) == 0:
            continue
        t_len = []
        for t in tlist:
            # 先保证两个订单列表之中的货物种类不超过200
            order_len = copy_list(orderId_list)
            order_len.append(t)
            order_len = get_batch_size(order_len)
            if order_len <= 200:
                t_len.append((t, order_len))
            else:
                continue
        t_len = sorted(t_len, key=lambda x: x[1])
        if len(t_len) > 0:
            break
    # End = time.time()
    # print(End - Start)
    assert (u != np.unique(x)[::-1][-1]), "遍历全部后找不到符合条件的订单编号"
    return OrderNo[t_len[0][0]]

def get_best_orderId1(orderId_list: [str], unUsed: list) -> str:
    '''
        找出某个订单对应符合条件的另一个订单Id,条件是:先判断种类和<=200,
    再找到未使用订单的与其相似度最高的订单Id
    :param orderId_list: 需要配对的订单Id列表
    :param unUsed: 未被使用过的订单列表
    :return: 订单编号
    '''
    # orderId = 'D0898'
    # Start = time.time()
    orderId_list = [OrderNo.index(i) for i in orderId_list]
    orderId = orderId_list[-1]
    # Eu_distance[OrderNo.index(orderId), 638]
    unUsed = [OrderNo.index(i) for i in unUsed]
    x = np.sort(Eu_distance[orderId, :])[::-1] # 降序
    res = np.argsort(-Eu_distance[orderId, :]) # 降序,返回的结果是排完序后对应原先数组的索引值
    for u in np.unique(x)[::-1]:
        # flag = 0
        idx = x == u
        tlist = list(res[idx])
        random.shuffle(tlist) # 在与该需要配对订单相似度相同的订单里随机选一个订单
        # 求交集:保证所求Id在未被使用的Id列表中
        tlist = list(set(tlist) & set(unUsed))
        # print(len(tlist))
        if len(tlist) == 0:
            continue
        t_len = []
        for t in tlist:
            # 先保证两个订单列表之中的货物种类不超过200
            order_len = copy_list(orderId_list)
            order_len.append(t)
            order_len = get_batch_size(order_len)
            if order_len <= 200:
                t_len.append((t, order_len))
            else:
                continue
        t_len = sorted(t_len, key=lambda x: x[1])
        if len(t_len) > 0:
            break
    # End = time.time()
    # print(End - Start)
    # assert (u != np.unique(x)[::-1][-1]), "遍历全部后找不到符合条件的订单编号"
    return OrderNo[t_len[0][0]]

主程序 

Eu_distance = np.load('Similars.npy')
# 减少变量
del data, ItemNo, Gt, N

# 数据框内容是每个订单对应的商品种类数
Order_nums = pd.DataFrame({'types': Order_nums})
Order_nums.index = OrderNo

Batches = []
# 防止等下列表变化时,原列表跟着变化
New_OrderNo = copy_list(OrderNo)
max_index = Order_nums.idxmax()[0]
print("最多货品种类的订单是:", max_index)
print(f"有{len(np.unique(Order_list[OrderNo.index(max_index)]))}种订单")
batch = [max_index]
New_OrderNo.remove(batch[-1])
print("开始搜寻……")
print('=' * 50)
print(f"第{len(Batches) + 1}批")
print(f"这批最多货物种类订单是-->{max_index},有{len(np.unique(Order_list[OrderNo.index(max_index)]))}种订单")
order_len = len(pd.unique(Order_list[OrderNo.index(max_index)]))
while len(New_OrderNo) > 0:
    try:
        # 尝试给当前批次添加新的订单,错误就说明没有符合条件的订单,需要转入下一批次
        new_order = get_best_orderId1(batch, New_OrderNo)
        batch.append(new_order)
        order_len = get_batch_size([OrderNo.index(i) for i in batch])
        print(f"{new_order}进入,此时批数种类数为{order_len}")
        New_OrderNo.remove(new_order)
    except:
        Batches.append(batch)
        print("进入订单列表:", batch)
        print("未被使用订单列表:", New_OrderNo)
        print('=' * 50)
        print(f"第{len(Batches) + 1}批")
        max_index = Order_nums.loc[New_OrderNo, :].idxmax()[0]
        print(f"这批最多货物种类订单是-->{max_index},有{len(np.unique(Order_list[OrderNo.index(max_index)]))}种订单")
        batch = [max_index]
        New_OrderNo.remove(max_index)
Batches.append(batch)
print(len(set(sum(Batches, []))))

path = sum(Batches, [])
path = [OrderNo.index(p) for p in path]
print("总批次:", Batch_size(path))

 四、结果

1、第一问

尽力了,57批。


漏了一个函数没给在这:

def get_batch_size(batch_num):
    order_len = []
    for o in batch_num:
        order_len += Order_list[o]
    return len(pd.unique(order_len))

 总结

        待我努力些,搞定后面题!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2022年华中杯A题(暂时做完第一小问,附完整Python源码) 的相关文章

  • 如何使用 Plotly 中的直方图将所有离群值分入一个分箱?

    所以问题是 我可以在 Plotly 中绘制直方图 其中所有大于某个阈值的值都将被分组到一个箱中吗 所需的输出 但使用标准情节Histogram类我只能得到这个输出 import pandas as pd from plotly import
  • 在 Python distutils 中从 setup.py 查找脚本目录的正确方法?

    我正在分发一个具有以下结构的包 mymodule mymodule init py mymodule code py scripts script1 py scripts script2 py The mymodule的子目录mymodul
  • Django 模型在模板中不可迭代

    我试图迭代模型以获取列表中的第一个图像 但它给了我错误 即模型不可迭代 以下是我的模型和模板的代码 我只需要获取与单个产品相关的列表中的第一个图像 模型 py class Product models Model title models
  • Argparse nargs="+" 正在吃位置参数

    这是我的解析器配置的一小部分 parser add argument infile help The file to be imported type argparse FileType r default sys stdin parser
  • 填充两个函数之间的区域

    import matplotlib pyplot as plt import numpy as np def domain x np arange 0 10 0 001 f1 lambda x 2 x x 2 0 5 plt plot x
  • 忽略 Mercurial hook 中的某些 Mercurial 命令

    我有一个像这样的善变钩子 hooks pretxncommit myhook python path to file myhook 代码如下所示 def myhook ui repo kwargs do some stuff 但在我的例子中
  • TensorFlow的./configure在哪里以及如何启用GPU支持?

    在我的 Ubuntu 上安装 TensorFlow 时 我想将 GPU 与 CUDA 结合使用 但我却停在了这一步官方教程 http www tensorflow org get started os setup md 这到底是哪里 con
  • 使用鼻子获取设置中当前测试的名称

    我目前正在使用鼻子编写一些功能测试 我正在测试的库操作目录结构 为了获得可重现的结果 我存储了一个测试目录结构的模板 并在执行测试之前创建该模板的副本 我在测试中执行此操作 setup功能 这确保了我在测试开始时始终具有明确定义的状态 现在
  • 如何解决使用 Spark 从 S3 重新分区大量数据时从内存中逐出缓存的表分区元数据的问题?

    在尝试从 S3 重新分区数据帧时 我收到一个一般错误 Caused by org apache spark SparkException Job aborted due to stage failure Task 33 in stage 1
  • 如何设置 Celery 来调用自定义工作器初始化?

    我对 Celery 很陌生 我一直在尝试设置一个具有 2 个独立队列的项目 一个用于计算 另一个用于执行 到目前为止 一切都很好 我的问题是执行队列中的工作人员需要实例化一个具有唯一 object id 的类 每个工作人员一个 id 我想知
  • Seaborn Pairplot 图例不显示颜色

    我一直在学习如何在Python中使用seaborn和pairplot 这里的一切似乎都工作正常 但由于某种原因 图例不会显示相关的颜色 我无法找到解决方案 因此如果有人有任何建议 请告诉我 x sns pairplot stats2 hue
  • 在 pytube3 中获取 youtube 视频的标题?

    我正在尝试构建一个应用程序来使用 python 下载 YouTube 视频pytube3 但我无法检索视频的标题 这是我的代码 from pytube import YouTube yt YouTube link print yt titl
  • Pandas 根据 diff 列形成簇

    我正在尝试使用 Pandas 根据表示时间 以秒为单位 的列中的差异来消除数据框中的一些接近重复项 例如 import pandas as pd numpy as np df pd DataFrame 1200 1201 1233 1555
  • python Soap zeep模块获取结果

    我从 SOAP API 得到如下结果 client zeep Client wsdl self wsdl transport transport auth header lb E authenticate self login res cl
  • 创建嵌套字典单行

    您好 我有三个列表 我想使用一行创建一个三级嵌套字典 i e l1 a b l2 1 2 3 l3 d e 我想创建以下嵌套字典 nd a 1 d 0 e 0 2 d 0 e 0 3 d 0 e 0 b a 1 d 0 e 0 2 d 0
  • mac osx 10.8 上的初学者 python

    我正在学习编程 并且一直在使用 Ruby 和 ROR 但我觉得我更喜欢 Python 语言来学习编程 虽然我看到了 Ruby 和 Rails 的优点 但我觉得我需要一种更容易学习编程概念的语言 因此是 Python 但是 我似乎找不到适用于
  • 如何在 OSX 上安装 numpy 和 scipy?

    我是 Mac 新手 请耐心等待 我现在使用的是雪豹 10 6 4 我想安装numpy和scipy 所以我从他们的官方网站下载了python2 6 numpy和scipy dmg文件 但是 我在导入 numpy 时遇到问题 Library F
  • Elastic Beanstalk 中的 enum34 问题

    我正在尝试在 Elastic Beanstalk 中设置 django 环境 当我尝试通过requirements txt 文件安装时 我遇到了python3 6 问题 File opt python run venv bin pip li
  • 检查字典键是否有空值

    我有以下字典 dict1 city name yass region zipcode phone address tehsil planet mars 我正在尝试创建一个基于 dict1 的新字典 但是 它不会包含带有空字符串的键 它不会包
  • 迭代 pandas 数据框的最快方法?

    如何运行数据框并仅返回满足特定条件的行 必须在之前的行和列上测试此条件 例如 1 2 3 4 1 1 1999 4 2 4 5 1 2 1999 5 2 3 3 1 3 1999 5 2 3 8 1 4 1999 6 4 2 6 1 5 1

随机推荐

  • VS附加进程调试

    什么是附加进程调试 附加进程调试就是将当前的代码工程附加到一个电脑程序进程中进行调试运行 从而达到调试定位问题的目的 附加进程调试的场景 1 软件运行崩溃 无dump或者dump看不出关键信息 2 当前代码工程编译的库不作为启动项 而是作为
  • SpringBoot+MybatisPlus+Druid极速搭建项目原型

    前言 听说你又有新需求了 什么 又是对某些表的增删改查 什么 还要从数据库一直写到dao层 还要配置mapper xml文件 完事儿之后还要写service层 controller层 什么 遇到条件查询还要写dao层和xml文件中的sql语
  • vscode 如何运行pip_VS Code写Python的一些小技巧

    本文基于 VS Code 1 36 1 为什么要用 VS Code 用 PyCharm 不好吗 VS Code 是开源免费的 PyCharm 是收费的 VS Code 除了 Python 还可以写其他语言 PyCharm 不行 VS Cod
  • 代码迁移_三种类型的代码迁移

    代码迁移 随着代码变老 通常有必要对其进行现代化 有以下动机 我们找到了一种更好的方法 我们需要出于支持 许可或仅出于最佳实践的原因而更新核心库 技术 我们需要在更现代的基础架构上运行该软件 简而言之 几年前编写的软件很少能完美地在我们现有
  • 自变化折线图(两周数据)

  • 小饼干问题 find寻找字符串 substr截取字符串

    所有人的回复都由大写字母 小写字母与 组成 占一行 MJJ认为只要其中包含了连续的10个小写字母 zailaiyihe 就意味着这个人想要再来一盒 题目描述 现在MJJ准备给每一个想要 再来一盒 的人买一盒小饼干 他想知道总共需要买几盒小饼
  • 【多线程例题】顺序打印abc线程

    顺序打印 进阶版 方法一 三个线程竞争同一个锁 通过count判断是否打印 方法二 三个线程同时start 分别上锁 从a开始 打印后唤醒b 三个线程分别打印A B C 方法一 通过count计数打印 三个线程上同样的锁 打印一个 召唤所有
  • msi afterburner怎么调节风扇转速教程

    msi afterburner是集超频 信息检测和参数调节等诸多功能为一体的显卡调节控制软件 要怎么使用msi afterburner调节风扇转速呢 很多小伙伴都不清楚怎么设置吧 下面就来看看详细操作 1 根据Afterburner软件的检
  • java String 转utf-8编码

    Get XML String of utf 8 return XML Formed string public static String getUTF8XMLString String xml A StringBuffer Object
  • Docker学习笔记(四)-docker中的网络与存储

    前言 要了解docker的网络和存储 首先需要知道docker的资源隔离机制 namespace 让某个特定的全局系统资源通过抽象方法使namespace 中的进程看起来拥有它们自己的隔离的全局系统资源实例 The purpose of e
  • 白盒测试怎么做?

    目录 前言 一 什么是白盒测试 二 白盒测试的分类 三 白盒测试的设计方法 四 白盒测试静态方法 五 白盒测试动态方法 六 白盒测试的特点 七 总结 前言 在企业内部 软件测试工程师基本处于 双高 地位 即地位高 待遇高 可以说他们的职业前
  • mysql yum的时候报错处理方法

    报错内容 警告 var cache yum x86 64 7 mysql57 community packages mysql community server 5 7 37 1 el7 x86 64 rpm 头V4 RSA SHA256
  • 键盘的hid描述符例子

    譬如有如下的Report Descriptor 譬如有如下的Report Descriptor C C code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  • 【无标题】乌邦图基础

    1 gt ubuntu的操作 图形界面 当我们ubuntu开启时 会自动进入桌面 桌面拥有很多图标 可以直接通过鼠标点击来完成操作 只适用于不走开发型的纯小白 成本很高 字符界面 没有其他任何的图案和标志 只有黑漆漆的对话框 和冰冷的字眼
  • 基于深度学习实现实时视频目标检测

    前言 实时视频目标检测是计算机视觉领域的研究热点之一 其应用场景包括智能监控 自动驾驶 机器人视觉等多个领域 深度学习技术的快速发展使得实时视频目标检测变得更加可行和准确 本文提出一种基于深度学习实现的实时视频目标检测系统 使用Python
  • 服务器运行python代码报错:intall python Extension

    当我安装时候又报错 WARNING Retrying Retry total 4 connect None read None redirect None status None after connection broken by New
  • 学生管理系统(C语言)

    说明 本程序的基本功能由单链表实现 满足基本的增删改查等功能 包括对文件的读写 由于测试数据较少 项目的鲁棒性可能不是很好 基本功能 退出 输入成绩 计算每名学生加权平均成绩 计算每门课程平均分 按分数降序排列 按学号升序排序 按姓名在字典
  • 如何通过手机拍照生成三维模型

    使用过易模的用户都知道 易模是通过手机扫描拍摄来进行建模的 而手机拍照建模是除扫描拍摄建模方式外迭代升级的一种全新的建模方式 使用手机拍照来进行建模 我们只需要按照要求拍摄并且上传所需建模物体的照片 系统就会自动生成我们所拍摄的物体模型 目
  • Jenkins免密登录gitlab拉取代码

    折腾了一下午 终于弄好了 网上很多博客写的都不清楚 所以记录一下 环境说明 服务器 说明 192 168 199 1 Jenkins 192 168 199 2 gitlab 操作步骤 1 生成公匙 在jenkins服务器执行 ssh ke
  • 2022年华中杯A题(暂时做完第一小问,附完整Python源码)

    目的 虽然比赛时间过去了 但还是可以拿来练一练优化问题的解决 加强自己对于优化算法的巩固 文章目录 目录 目的 前言 一 题目 二 思路 1 第一小题 分批算法 三 程序 1 计算相似度的函数 2 分批算法主要部分 初始化 1 首先生成想要