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源码) 的相关文章

  • Python 的键盘中断不会中止 Rust 函数 (PyO3)

    我有一个使用 PyO3 用 Rust 编写的 Python 库 它涉及一些昂贵的计算 单个函数调用最多需要 10 分钟 从 Python 调用时如何中止执行 Ctrl C 好像只有执行结束后才会处理 所以本质上没什么用 最小可重现示例 Ca
  • Python(Selenium):如何通过登录重定向/组织登录登录网站

    我不是专业程序员 所以请原谅任何愚蠢的错误 我正在做一些研究 我正在尝试使用 Selenium 登录数据库来搜索大约 1000 个术语 我有两个问题 1 重定向到组织登录页面后如何使用 Selenium 登录 2 如何检索数据库 在我解决
  • 如何使用Conda下载python包并随后离线安装?

    我知道通过 pip 我可以使用以下命令下载 Python 包 但 pip install 破坏了我的内部包依赖关系 当我做 pip download
  • OpenCV 无法从 MacBook Pro iSight 捕获

    几天后 我无法再从 opencv 应用程序内部打开我的 iSight 相机 cap cv2 VideoCapture 0 返回 并且cap isOpened 回报true 然而 cap grab 刚刚返回false 有任何想法吗 示例代码
  • 绘制方程

    我正在尝试创建一个函数 它将绘制我告诉它的任何公式 import numpy as np import matplotlib pyplot as plt def graph formula x range x np array x rang
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • 添加不同形状的 numpy 数组

    我想添加两个不同形状的 numpy 数组 但不进行广播 而是将 缺失 值视为零 可能最简单的例子是 1 2 3 2 gt 3 2 3 or 1 2 3 2 1 gt 3 2 3 1 0 0 我事先不知道形状 我正在弄乱每个 np shape
  • 如何在seaborn displot中使用hist_kws

    我想在同一图中用不同的颜色绘制直方图和 kde 线 我想为直方图设置绿色 为 kde 线设置蓝色 我设法弄清楚使用 line kws 来更改 kde 线条颜色 但 hist kws 不适用于显示 我尝试过使用 histplot 但我无法为
  • Conda SafetyError:文件大小不正确

    使用创建 Conda 环境时conda create n env name python 3 6 我收到以下警告 Preparing transaction done Verifying transaction SafetyError Th
  • Python:如何将列表列表的元素转换为无向图?

    我有一个程序 可以检索 PubMed 出版物列表 并希望构建一个共同作者图 这意味着对于每篇文章 我想将每个作者 如果尚未存在 添加为顶点 并添加无向边 或增加每个合著者之间的权重 我设法编写了第一个程序 该程序检索每个出版物的作者列表 并
  • 如何计算 pandas 数据帧上的连续有序值

    我试图从给定的数据帧中获取连续 0 值的最大计数 其中包含来自 pandas 数据帧的 id date value 列 如下所示 id date value 354 2019 03 01 0 354 2019 03 02 0 354 201
  • 识别 pandas 数据框中各组之间的差异

    我有一个按日期和 ID 索引的 pandas 数据框 我想 识别日期之间增删的ID 将 ID 添加到另一个数据帧以及添加 删除的日期 date ID value 12 31 2010 13 0 124409 9 0 555959 1 0 7
  • Scrapy:如何使用元在方法之间传递项目

    我是 scrapy 和 python 的新手 我试图将 parse quotes 中的项目 item author 传递给下一个解析方法 parse bio 我尝试了 request meta 和 response meta 方法 如 sc
  • 发送用户注册密码,django-allauth

    我在 django 应用程序上使用 django alluth 进行身份验证 注册 我需要创建一个自定义注册表单 其中只有一个字段 电子邮件 密码将在服务器上生成 这是我创建的表格 from django import forms from
  • 在 Qt 中自动调整标签文本大小 - 奇怪的行为

    在 Qt 中 我有一个复合小部件 它由排列在 QBoxLayouts 内的多个 QLabels 组成 当小部件调整大小时 我希望标签文本缩放以填充标签区域 并且我已经在 resizeEvent 中实现了文本大小的调整 这可行 但似乎发生了某
  • Rocket UniData/UniVerse:ODBC 无法分配足够的内存

    每当我尝试使用pyodbc连接到 Rocket UniData UniVerse 数据时我不断遇到错误 pyodbc Error 00000 00000 Rocket U2 U2ODBC 0302810 Unable to allocate
  • 从列表指向字典变量

    假设你有一个清单 a 3 4 1 我想用这些信息来指向字典 b 3 4 1 现在 我需要的是一个常规 看到该值后 在 b 的位置内读写一个值 我不喜欢复制变量 我想直接改变变量b的内容 假设b是一个嵌套字典 你可以这样做 reduce di
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2
  • Statsmodels.formula.api OLS不显示截距的统计值

    我正在运行以下源代码 import statsmodels formula api as sm Add one column of ones for the intercept term X np append arr np ones 50

随机推荐

  • 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 首先生成想要