2023年华为杯研究生数学建模竞赛C题代码分享-spsspro和杉数求解器启动

文摘   2024-09-03 08:03   中国澳门  
本次分享的是2023年华为杯数学建模竞赛的代码。我自己参考了网上的开源的博客。这次写这篇文章是想支持一下杉数求解器和spsspro两个国产软件。我特地把别的求解器给换掉了。代码完全开源。欢迎阅读指出我的问题,那好,我们开始吧。代码是完整的。但是没有跑完。

2023年中国研究生数学建模竞赛C题 大规模创新类竞赛评审方案研究。

问题一 在每个评审阶段,作品通常都是随机分发的,每份作品需要多位评委独立评审。为了增加不同评审专家所给成绩之间的可比性,不同专家评审的作品集合之间应有一些交集。但有的交集大了,则必然有交集小了,则可比性变弱。请针对3000支参赛队和125位评审专家,每份作品由5位专家评审的情况,建立数学模型确定最优的“交叉分发”方案,并讨论该方案的有关指标(自己定义)和实施细节。

这一问我们使用组合优化进攻:

第一问做完了,我们来上代码:
import coptpy as cpfrom coptpy import COPTimport mathimport itertools#第一问
# 定义评审专家数量和作品数量num_experts = 125num_works = 3000
# 定义每位评审专家最多评审的作品数量和每份作品需要被评审的专家数量k = 400 # 最多评审的作品数量m = 5 # 每份作品需要被评审的专家数量

env=cp.Envr()# 创建线性规划问题model = env.createModel("CrossDistribution")
# 创建二进制变量x(i, j)x = model.addVars(num_experts, num_works, vtype=cp.COPT.BINARY, nameprefix="x")
# 定义目标函数:最大化交叉评审数量model.setObjective(cp.quicksum(x[i, j] for i in range(num_experts) for j in range(num_works)), cp.COPT.MAXIMIZE)
# 添加约束条件# 每位评审专家最多评审k份作品的约束for i in range(num_experts): model.addConstr(cp.quicksum(x[i, j] for j in range(num_works)) <= k)
# 每份作品需要被评审m位专家的约束for j in range(num_works): model.addConstr(cp.quicksum(x[i, j] for i in range(num_experts)) == m)
# 求解线性规划问题model.solve()
# 打印结果print("Status:", model.status)

if model.status == cp.COPT.OPTIMAL: # 打印每位评审专家评审的作品列表 for i in range(num_experts): selected_works = [j for j in range(num_works) if x[i, j].X == 1] print(f"评审专家 {i+1} 评审的作品列表:{selected_works}")
# 打印最大化的交叉评审数量 print("最大化的交叉评审数量:", model.objVal)else: print("模型没有找到最优解")

这段代码轻松简单解决了这个问题,我们来看看节选的运行结果:

Cardinal Optimizer v7.1.3. Build date Apr 29 2024Copyright Cardinal Operations 2024. All Rights Reserved
Model fingerprint: d6debe07
Using Cardinal Optimizer v7.1.3 on WindowsHardware has 4 cores and 8 threads. Using instruction set X86_AVX512_E1 (14)Maximizing a MIP problem
The original problem has: 3125 rows, 375000 columns and 750000 non-zero elements 375000 binaries
Starting the MIP solver with 8 threads and 32 tasks
Presolving the problem
The presolved problem has: 3125 rows, 375000 columns and 750000 non-zero elements 375000 binaries

Nodes Active LPit/n IntInf BestBound BestSolution Gap Time 0 1 -- 0 3.750000e+05 -- Inf 1.70sH 0 1 -- 0 3.750000e+05 1.500000e+04 96.0% 2.65s 0 1 -- 0 1.500000e+04 1.500000e+04 0.00% 5.85s 1 0 0.0 0 1.500000e+04 1.500000e+04 0.00% 5.90s 1 0 0.0 0 1.500000e+04 1.500000e+04 0.00% 5.90s
Best solution : 15000.000000000Best bound : 15000.000000000Best gap : 0.0000%Solve time : 5.93Solve node : 1MIP status : solvedSolution status : integer optimal (relative gap limit 0.0001)
Violations : absolute relative bounds : 0 0 rows : 0 0 integrality : 0Status: 1评审专家 1 评审的作品列表:[2600, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773, 2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963, 2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999]

这段运行结果可以直接丢到附件去,至此第一问被我们秒杀了。下面我们看看后面的问题吧!

问题二 在评审中采用标准分(附件1)为基础的排序方法,其假设是不同评审专家评审的作品集合的学术水平分布相同。但在大规模创新类竞赛评审中,通常任意两位专家评审的作品只有小部分是共同的,绝大多数作品是不同的(见问题一),而且每位专家只看到作品集合的很小部分,因此标准分评审方案的假设可能不成立,需要探索新的评审方案。请选择两种或两种以上现有或自己设计的评审方案和题目附件数据,分析每位专家、每份作品原始成绩、调整之后(如取标准分)成绩的分布特点,按不同方案进行排序,并设法比较这些方案的优劣。进而针对大规模创新类竞赛的评审,设计新的标准分(公式)计算模型。另外,一般认为经多位专家协商一致的获奖论文具有最大的可信度,附件2提供的数据1,其第二评审阶段评选出的一等奖作品排序是经专家协商取得一致的,请利用这批数据,改进你们的标准分计算模型。

这一问又是一个统计的问题,不过没有优化,没关系,我们SPSSPRO进攻:


在进行这部操作之前,我们先看看怎么预处理这个数据,其实三个数据长的差不多,不过,我们要修改一下列名,方便spsspro和python读取。

我的思路是这样的,先看分布,这一点可以用spsspro数据探索性分析这样的快速得到结果。接下来,我们可以使用多因素方差分析,探究一下专家对这个比赛结果的影响,其实我们这个比赛的业务背景其实是想整怎么高效分配工作量,快速把奖给出来,然后保证公平,这个大任务一定要明确。

对于变量奖项,从F检验的结果分析可以得到,显著性P值为0.000***,水平上呈现显著性,对名次有显著性影响,存在主效应。对于变量第一次评审成绩专家一专家编码,从F检验的结果分析可以得到,显著性P值为0.038**,水平上呈现显著性,对名次有显著性影响,存在主效应。
接下来我们看看决策树模型:

强特征是最终成绩和第二次评审成绩专家二原始分。

这个结论就已经可以说明一些问题了。

最后是问题三和问题四,我们上代码吧:

import pandas as pdimport numpy as np ## 绘图函数库import matplotlib.pyplot as pltimport seaborn as sns
data = pd.read_excel(r'D:\桌面\华为杯资料合集\题目\C题\预处理数据\已经处理数据1.xlsx')

# In[3]:

data.head()

# In[4]:

data.describe()

# In[5]:

data.info()

# In[6]:

import pandas as pd


# 提取专家编码列expert_codes_first_review = data[['第一次评审成绩专家一专家编码', '第一次评审成绩专家二专家编码', '第一次评审成绩专家三专家编码']]
expert_codes_second_review = data[['第二次评审成绩专家一专家编码', '第二次评审成绩专家二专家编码', '第二次评审成绩专家三专家编码']]
# 统计每列的唯一专家编码个数unique_experts_first_review = pd.unique(expert_codes_first_review.values.ravel())unique_experts_second_review = pd.unique(expert_codes_second_review.values.ravel())
print(f'第一次评审中的唯一专家编码个数: {len(unique_experts_first_review)}')print(f'第二次评审中的唯一专家编码个数: {len(unique_experts_second_review)}')
# 检查是否三次评审使用的是同一批专家common_experts = set(unique_experts_first_review) & set(unique_experts_second_review)print(f'三次评审中共同的专家编码个数: {len(common_experts)}')print(f'共同的专家编码: {common_experts}')

# In[15]:

import pandas as pdimport seaborn as snsimport matplotlib.pyplot as plt


# 创建一个新的列,用于标记不同的奖项类别data['奖项类别'] = data['奖项'].map({ '一等奖': '一等奖', '二等奖': '二等奖', '三等奖': '三等奖', '未获奖': '未获奖'})
# 设置绘图风格sns.set(style="whitegrid")
# 创建一个绘图窗口plt.figure(figsize=(14, 10))
# 绘制一等奖的最终成绩分布图plt.subplot(2, 2, 1)sns.histplot(data[data['奖项类别'] == '一等奖']['最终成绩'], bins=30, kde=True)plt.title('一等奖最终成绩分布')
# 绘制二等奖的最终成绩分布图plt.subplot(2, 2, 2)sns.histplot(data[data['奖项类别'] == '二等奖']['最终成绩'], bins=30, kde=True)plt.title('二等奖最终成绩分布')
# 绘制三等奖的最终成绩分布图plt.subplot(2, 2, 3)sns.histplot(data[data['奖项类别'] == '三等奖']['最终成绩'], bins=30, kde=True)plt.title('三等奖最终成绩分布')
# 绘制未获奖的最终成绩分布图plt.subplot(2, 2, 4)sns.histplot(data[data['奖项类别'] == '未获奖']['最终成绩'], bins=30, kde=True)plt.title('未获奖最终成绩分布')
# 调整布局并显示图形plt.tight_layout()plt.show()



plt.figure(figsize=(14, 10))sns.boxplot(x='奖项类别', y='最终成绩', data=data)plt.title('不同奖项类别最终成绩的箱线图')plt.show()

# In[18]:

import pandas as pd

# 提取每轮评审的评委列first_round_experts = data[['第一次评审成绩专家一专家编码', '第一次评审成绩专家二专家编码', '第一次评审成绩专家三专家编码', '第一次评审成绩专家四专家编码', '第一次评审成绩专家五专家编码']]
second_round_experts = data[['第二次评审成绩专家一专家编码', '第二次评审成绩专家二专家编码', '第二次评审成绩专家三专家编码']]
# 合并所有评委信息到一个列表中all_experts = pd.concat([first_round_experts, second_round_experts], axis=1)
# 将所有评委信息合并到一个长格式的数据框中all_experts_long = all_experts.melt(value_name='Expert').dropna()['Expert']
# 统计每个评委的评选次数expert_counts = all_experts_long.value_counts()
# 打印每个评委的评选次数print(expert_counts)

# In[19]:

import pandas as pd
# 提取每轮评审的评委列first_round_experts = data[['第一次评审成绩专家一专家编码', '第一次评审成绩专家二专家编码', '第一次评审成绩专家三专家编码']]
second_round_experts = data[['第二次评审成绩专家一专家编码', '第二次评审成绩专家二专家编码', '第二次评审成绩专家三专家编码']]
# 合并所有评委信息到一个列表中all_experts = pd.concat([first_round_experts, second_round_experts], axis=1)
# 将所有评委信息合并到一个长格式的数据框中all_experts_long = all_experts.melt(value_name='Expert').dropna()['Expert']
# 统计每个评委的评选次数expert_counts = all_experts_long.value_counts().reset_index()expert_counts.columns = ['Expert', 'Count']
# 保存到 Excel 文件output_file = r'D:\桌面\华为杯资料合集\题目\C题\预处理数据\expert_counts.xlsx'expert_counts.to_excel(output_file, index=False)
print(f'统计结果已保存到 {output_file}')



# In[23]:

import pandas as pdimport matplotlib.pyplot as pltimport seaborn as sns


# 绘图plt.figure(figsize=(14, 7))
# 原始分数的分布图plt.subplot(1, 2, 1)sns.histplot(data[['第一次评审成绩专家一原始分', '第二次评审成绩专家一原始分']], kde=True, palette='husl', binwidth=2)plt.title('Distribution of Original Scores')plt.xlabel('Original Score')plt.ylabel('Frequency')plt.legend(title='Evaluation Rounds', labels=['First Round', 'Second Round'])
# 标准化分数的分布图plt.subplot(1, 2, 2)sns.histplot(data[['第一次评审成绩专家一标准分', '第二次评审成绩专家一标准分']], kde=True, palette='husl', binwidth=0.5)plt.title('Distribution of Standardized Scores')plt.xlabel('Standardized Score')plt.ylabel('Frequency')plt.legend(title='Evaluation Rounds', labels=['First Round', 'Second Round'])

plt.tight_layout()plt.show()

# In[29]:

import pandas as pdimport scipy.stats as stats


# 正态分布检验函数def normality_test(column_data): stat, p_value = stats.shapiro(column_data) return {'Statistic': stat, 'P-Value': p_value}
# 对每个专家在每次评审中的分数进行正态分布检验
# 专家一print("专家一 - 第一次评审:")result = normality_test(data['第一次评审成绩专家一原始分'])print(f" Statistic: {result['Statistic']:.4f}")print(f" P-Value: {result['P-Value']:.4f}")if result['P-Value'] < 0.05: print(" The data is likely not normally distributed.")else: print(" The data is likely normally distributed.")
print("\n专家一 - 第二次评审:")result = normality_test(data['第二次评审成绩专家一原始分'])print(f" Statistic: {result['Statistic']:.4f}")print(f" P-Value: {result['P-Value']:.4f}")if result['P-Value'] < 0.05: print(" The data is likely not normally distributed.")else: print(" The data is likely normally distributed.")
# 专家二print("\n专家二 - 第一次评审:")result = normality_test(data['第一次评审成绩专家二原始分'])print(f" Statistic: {result['Statistic']:.4f}")print(f" P-Value: {result['P-Value']:.4f}")if result['P-Value'] < 0.05: print(" The data is likely not normally distributed.")else: print(" The data is likely normally distributed.")
print("\n专家二 - 第二次评审:")result = normality_test(data['第二次评审成绩专家二原始分'])print(f" Statistic: {result['Statistic']:.4f}")print(f" P-Value: {result['P-Value']:.4f}")if result['P-Value'] < 0.05: print(" The data is likely not normally distributed.")else: print(" The data is likely normally distributed.")
# 专家三print("\n专家三 - 第一次评审:")result = normality_test(data['第一次评审成绩专家三原始分'])print(f" Statistic: {result['Statistic']:.4f}")print(f" P-Value: {result['P-Value']:.4f}")if result['P-Value'] < 0.05: print(" The data is likely not normally distributed.")else: print(" The data is likely normally distributed.")
print("\n专家三 - 第二次评审:")result = normality_test(data['第二次评审成绩专家三原始分'])print(f" Statistic: {result['Statistic']:.4f}")print(f" P-Value: {result['P-Value']:.4f}")if result['P-Value'] < 0.05: print(" The data is likely not normally distributed.")else: print(" The data is likely normally distributed.")
# 专家四print("\n专家四 - 第一次评审:")result = normality_test(data['第一次评审成绩专家四原始分'])print(f" Statistic: {result['Statistic']:.4f}")print(f" P-Value: {result['P-Value']:.4f}")if result['P-Value'] < 0.05: print(" The data is likely not normally distributed.")else: print(" The data is likely normally distributed.")

最后是两段杉数求解器优化的代码

import coptpy as cpfrom coptpy import COPTimport mathimport itertools#第四问
env=cp.Envr()
# 创建模型model = env.createModel("Optimization")
# 定义决策变量x = model.addVars(2, vtype=cp.COPT.CONTINUOUS, nameprefix="x")
# 定义目标函数:最小化 x[0]^2 + x[1]^2model.setObjective(x[0]**2 + x[1]**2, cp.COPT.MINIMIZE)
# 添加约束条件:x[0] + x[1] = 1model.addConstr(x[0] + x[1] == 1)
# 求解模型model.solve()
# 输出结果if model.status == cp.COPT.OPTIMAL: optimal_solution = [x[i].X for i in range(2)] optimal_value = model.objVal print("最优解:", optimal_solution) print("最优值:", optimal_value)else: print("模型没有找到最优解")
Cardinal Optimizer v7.1.3. Build date Apr 29 2024Copyright Cardinal Operations 2024. All Rights Reserved
Model fingerprint: 183fdc56
Using Cardinal Optimizer v7.1.3 on WindowsHardware has 4 cores and 8 threads. Using instruction set X86_AVX512_E1 (14)Minimizing a QP problem
The original problem has: 1 rows, 2 columns and 2 non-zero elements 2 quadratic objective elementsThe presolved problem has: 1 rows, 2 columns and 2 non-zero elements 2 quadratic objective elements
Starting barrier solver using 4 threads
Problem info:Dualized in presolve: NoRange of matrix coefficients: [1e+00,1e+00]Range of rhs coefficients: [1e+00,1e+00]Range of bound coefficients: [0e+00,0e+00]Range of cost coefficients: [0e+00,0e+00]Range of quadcost coefficients: [1e+00,1e+00]
Factor info:Number of free columns: 0Number of dense columns: 0Number of matrix entries: 1.000e+00Number of factor entries: 1.000e+00Number of factor flops: 0.000e+00
Iter Primal.Obj Dual.Obj Compl Primal.Inf Dual.Inf Time 0 +9.68000000e+00 -8.68000000e+00 4.73e+01 3.40e+00 7.35e+00 0.02s 1 +5.12016885e-01 -5.90836971e+00 6.51e+00 1.19e-02 2.58e-02 0.02s 2 +5.00000031e-01 +4.99086847e-01 9.13e-04 3.09e-08 6.68e-08 0.02s 3 +5.00000000e-01 +4.99999999e-01 9.13e-10 3.09e-14 6.69e-14 0.02s
Barrier status: OPTIMALPrimal objective: 5.00000000e-01Dual objective: 4.99999999e-01Duality gap (abs/rel): 9.13e-10 / 9.13e-10Primal infeasibility (abs/rel): 3.09e-14 / 3.09e-14Dual infeasibility (abs/rel): 6.69e-14 / 6.69e-14
Postsolving
Solving finishedStatus: Optimal Objective: 5.0000000000e-01 Iterations: 3 Time: 0.03s最优解: [0.5000000000000154, 0.5000000000000154]最优值: 0.5000000000000309

这一段代码求解的是优化过后的评委评选的数量

import coptpy as cpfrom coptpy import COPTimport mathimport itertools
# 示例数据:每轮的论文数量和评委数量num_papers_round1 = 2015 # 示例数量num_papers_round2 = 352num_papers_round3 = 352num_experts = 10 # 假设有10个评委
env=cp.Envr()# 创建模型m = env.createModel('review_allocation')
# 变量:评委i在轮次j上的评审次数x = {}for i in range(num_experts): for j in range(3): # 0: 第一轮, 1: 第二轮, 2: 第三轮 x[i, j] = m.addVar(vtype=COPT.INTEGER, name=f'x_{i}_{j}')
# 目标函数:最小化每个评委三轮阅卷总和的方差和极差mean_review = num_papers_round1 + num_papers_round2 + num_papers_round3
# 添加目标函数objective = 0for i in range(num_experts): total_reviews = sum(x[i, j] for j in range(3)) mean = mean_review / num_experts variance = (total_reviews - mean) ** 2 objective += variance
m.setObjective(objective, COPT.MINIMIZE)
# 添加约束:每轮评审的总论文数量for j in range(3): m.addConstr(sum(x[i, j] for i in range(num_experts)) == [num_papers_round1, num_papers_round2, num_papers_round3][j])
# 求解模型m.solve()
# 输出结果if m.status == COPT.OPTIMAL: for i in range(num_experts): print(f'评委{i}的评分分配:') for j in range(3): print(f' 第{j+1}轮: {x[i, j].x}')
print('优化完成。')else: print('没有找到最优解。')
Cardinal Optimizer v7.1.3. Build date Apr 29 2024Copyright Cardinal Operations 2024. All Rights Reserved
Model fingerprint: e2a91c70
Using Cardinal Optimizer v7.1.3 on WindowsHardware has 4 cores and 8 threads. Using instruction set X86_AVX512_E1 (14)Minimizing a MIQP problem
The original problem has: 3 rows, 30 columns and 30 non-zero elements 30 integers 60 quadratic objective elements
Starting the MIP solver with 8 threads and 32 tasks
Presolving the problem
The presolved problem has: 13 rows, 50 columns and 70 non-zero elements 10 SOC rows and 30 non-zero elements 30 integers

Nodes Active LPit/n IntInf BestBound BestSolution Gap Time 0 1 -- 0 -1.404663e+07 -- Inf 0.02sH 0 1 -- 0 -1.404663e+07 6.653665e+06 147.4% 0.02s 0 1 -- 11 9.000000e-01 6.653665e+06 100.0% 0.05sH 0 1 -- 11 9.000000e-01 1.600835e+06 100.0% 0.06sH 0 1 -- 11 9.000000e-01 6.131485e+04 100.0% 0.06s 0 1 -- 8 9.000000e-01 6.131485e+04 100.0% 0.06s 0 1 -- 10 9.000000e-01 6.131485e+04 100.0% 0.06s 0 1 -- 10 9.000000e-01 6.131485e+04 100.0% 0.07s 0 1 -- 2 9.000000e-01 6.131485e+04 100.0% 0.07s 0 1 -- 11 9.000000e-01 6.131485e+04 100.0% 0.07s 0 1 -- 10 9.000000e-01 6.131485e+04 100.0% 0.07s 0 1 -- 8 9.000000e-01 6.131485e+04 100.0% 0.07s 0 1 -- 3 9.000000e-01 6.131485e+04 100.0% 0.07s 0 1 -- 0 9.000000e-01 6.131485e+04 100.0% 0.07s 0 1 -- 5 9.000000e-01 6.131485e+04 100.0% 0.07s
Nodes Active LPit/n IntInf BestBound BestSolution Gap Time 0 1 -- 4 9.000000e-01 6.131485e+04 100.0% 0.08s 0 1 -- 4 9.000000e-01 6.131485e+04 100.0% 0.08s 0 1 -- 4 9.000000e-01 6.131485e+04 100.0% 0.08s* 0 1 -- 0 9.000000e-01 9.000000e-01 0.00% 0.08s 0 1 -- 0 9.000000e-01 9.000000e-01 0.00% 0.08s 1 0 89.0 0 9.000000e-01 9.000000e-01 0.00% 0.08s 1 0 89.0 0 9.000000e-01 9.000000e-01 0.00% 0.08s
Best solution : 0.900000000Best bound : 0.900000000Best gap : 0.0000%Solve time : 0.08Solve node : 1MIP status : solvedSolution status : integer optimal (relative gap limit 0.0001)
Violations : absolute relative bounds : 0 0 rows : 0 0 integrality : 0 SOC rows : 0评委0的评分分配: 第1轮: 271.99999999999636 第2轮: 0.0 第3轮: 0.0评委1的评分分配: 第1轮: 192.0000000000166 第2轮: 80.00000000000193 第3轮: 0.0评委2的评分分配: 第1轮: 0.0 第2轮: 271.99999999999807 第3轮: 0.0评委3的评分分配: 第1轮: 192.00000000000165 第2轮: 0.0 第3轮: 80.00000000000773评委4的评分分配: 第1轮: 271.99999999999636 第2轮: 0.0 第3轮: 0.0评委5的评分分配: 第1轮: 271.99999999999636 第2轮: 0.0 第3轮: 0.0评委6的评分分配: 第1轮: 0.0 第2轮: 0.0 第3轮: 271.99999999999227评委7的评分分配: 第1轮: 270.99999999999994 第2轮: 0.0 第3轮: 0.0评委8的评分分配: 第1轮: 271.99999999999636 第2轮: 0.0 第3轮: 0.0评委9的评分分配: 第1轮: 271.99999999999636 第2轮: 0.0 第3轮: 0.0优化完成。
到此这个题目求解完成,我们自己回顾一下这个题目,我们综合运用了统计学的知识做数据分布的分析,建立了很多统计学模型进行数据内部的分析,我们也使用了机器学习模型看强特征,以及组合优化,MIP混合整数规划,是一道非常不错的赛题。
#修改一处报错,字体显示不完全,感谢学弟的贡献import pandas as pdimport numpy as np ## 绘图函数库import matplotlib.pyplot as pltimport seaborn as sns
from matplotlib.font_manager import FontProperties
# 设置我们需要用到的中文字体(字体文件地址)my_font = FontProperties(fname=r"c:\windows\fonts\SimHei.ttf", size=12)
plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falsedata = pd.read_excel(r'已经处理数据1.xlsx')
# 创建一个新的列,用于标记不同的奖项类别data['奖项类别'] = data['奖项'].map({ '一等奖': '一等奖', '二等奖': '二等奖', '三等奖': '三等奖', '未获奖': '未获奖'})
# 设置绘图风格sns.set(style="whitegrid")
# 创建一个绘图窗口plt.figure(figsize=(14, 10))
# 绘制一等奖的最终成绩分布图plt.subplot(2, 2, 1)sns.histplot(data[data['奖项类别'] == '一等奖']['最终成绩'], bins=30, kde=True)plt.title('一等奖最终成绩分布',fontproperties=my_font)plt.xlabel('最终成绩', fontproperties=my_font)
# 绘制二等奖的最终成绩分布图plt.subplot(2, 2, 2)sns.histplot(data[data['奖项类别'] == '二等奖']['最终成绩'], bins=30, kde=True)plt.title('二等奖最终成绩分布',fontproperties=my_font)plt.xlabel('最终成绩', fontproperties=my_font)
# 绘制三等奖的最终成绩分布图plt.subplot(2, 2, 3)sns.histplot(data[data['奖项类别'] == '三等奖']['最终成绩'], bins=30, kde=True)plt.title('三等奖最终成绩分布',fontproperties=my_font)plt.xlabel('最终成绩', fontproperties=my_font) # 绘制未获奖的最终成绩分布图plt.subplot(2, 2, 4)sns.histplot(data[data['奖项类别'] == '未获奖']['最终成绩'], bins=30, kde=True)plt.title('未获奖最终成绩分布',fontproperties=my_font)plt.xlabel('最终成绩', fontproperties=my_font)
# 调整布局并显示图形plt.tight_layout()plt.show()
欢迎关注我们。本文为我原创,转载请注明出处。

师苑数模
发布数模协会培训推文,讲解数模算法。赛题讲解及比赛通知。学校竞赛结果及学校竞赛成绩发布等文章。
 最新文章