DCIC-早高峰共享单车潮汐点的群智优化(1)

2023-11-06 20:30

本文主要是介绍DCIC-早高峰共享单车潮汐点的群智优化(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 学习主题
  • 赛题说明
  • 赛题任务
  • 代码

学习主题

比赛链接: https://data.xm.gov.cn/contest-series-api/promote/register/3/UrnA69nb.

赛题说明

共享单车,延伸了城市公共交通脉络,解决了市民出行“最后一公里”问题。然而,随着共享经济模式被越来越多市民接受,成为出行习惯,潮汐现象也随之出现。白天工作、晚上休息的人类活动规律的客观存在,加之上下班时间段的集中,导致早晚高峰“一车难寻”、“无地可停”的供需矛盾。本题希望通过对车辆数据的综合分析,对厦门岛内早高峰阶段潮汐点进行有效定位,进一步设计高峰期群智优化方案,缓解潮汐点供需问题,以期为城市管理部门和共享单车运营方研究制定下一步优化措施提供数据支撑。

赛题任务

任务一: 为更好地掌握早高峰潮汐现象的变化规律与趋势,参赛者需基于主办方提供的数据进行数据分析和计算模型构建等工作,识别出工作日早高峰07:00-09:00潮汐现象最突出的40个区域,列出各区域所包含的共享单车停车点位编号名称,并提供计算方法说明及计算模型,为下一步优化措施提供辅助支撑。

任务二: 参赛者根据任务一Top40区域计算结果进一步设计高峰期共享单车潮汐点优化方案,通过主动引导停车用户到邻近停车点位停车,进行削峰填谷,缓解潮汐点停车位(如地铁口)的拥堵问题。允许参赛者自带训练数据,但需在参赛作品中说明所自带数据的来源及使用方式,并保证其合法合规。(城市公共自行车从业者将发生在早晚高峰时段共享单车“借不到、还不进”的问题称之为“潮汐”现象。本题涉及的“潮汐现象”聚焦“还不进”的问题,识别出早高峰共享单车最淤积的40个区域)

代码

import os, codecs
import pandas as pd
import numpy as npPATH = './data/'
# 共享单车轨迹数据
bike_track = pd.concat([pd.read_csv(PATH + 'gxdc_gj20201221.csv'),pd.read_csv(PATH + 'gxdc_gj20201222.csv'),pd.read_csv(PATH + 'gxdc_gj20201223.csv'),pd.read_csv(PATH + 'gxdc_gj20201224.csv'),pd.read_csv(PATH + 'gxdc_gj20201225.csv')
])# 按照单车ID和时间进行排序
bike_track = bike_track.sort_values(['BICYCLE_ID', 'LOCATING_TIME'])
import folium
m = folium.Map(location=[24.482426, 118.157606], zoom_start=12)
my_PolyLine=folium.PolyLine(locations=bike_track[bike_track['BICYCLE_ID'] == '000152773681a23a7f2d9af8e8902703'][['LATITUDE', 'LONGITUDE']].values,weight=5)
m.add_children(my_PolyLine)

在这里插入图片描述

def bike_fence_format(s):s = s.replace('[', '').replace(']', '').split(',')s = np.array(s).astype(float).reshape(5, -1)return s# 共享单车停车点位(电子围栏)数据
bike_fence = pd.read_csv(PATH + 'gxdc_tcd.csv')
bike_fence['FENCE_LOC'] = bike_fence['FENCE_LOC'].apply(bike_fence_format)
import folium
m = folium.Map(location=[24.482426, 118.157606], zoom_start=12)# for data in bike_fence['FENCE_LOC'].values[:100]:
#     folium.Marker([data[0,1],data[0,0]]).add_to(m)
for data in bike_fence['FENCE_LOC'].values[:100]:folium.Marker(list(data[0, ::-1])).add_to(m)
m

在这里插入图片描述

# 共享单车订单数据
bike_order = pd.read_csv(PATH + 'gxdc_dd.csv')
bike_order = bike_order.sort_values(['BICYCLE_ID', 'UPDATE_TIME'])
import folium
m = folium.Map(location=[24.482426, 118.157606], zoom_start=12)
my_PolyLine=folium.PolyLine(locations=bike_order[bike_order['BICYCLE_ID'] == '0000ff105fd5f9099b866bccd157dc50'][['LATITUDE', 'LONGITUDE']].values,weight=5)
m.add_children(my_PolyLine)

在这里插入图片描述

# 轨道站点进站客流数据
rail_inflow = pd.read_excel(PATH + 'gdzdtjsj_jzkl.csv')
rail_inflow = rail_inflow.drop(0)# 轨道站点出站客流数据
rail_outflow = pd.read_excel(PATH + 'gdzdtjsj_czkl.csv')
rail_outflow = rail_outflow.drop(0)# 轨道站点闸机设备编码数据
rail_device = pd.read_excel(PATH + 'gdzdkltj_zjbh.csv')
rail_device.columns = ['LINE_NO', 'STATION_NO', 'STATION_NAME','A_IN_MANCHINE', 'A_OUT_MANCHINE', 'B_IN_MANCHINE', 'B_OUT_MANCHINE'
]
rail_device = rail_device.drop(0)
# 得出停车点 LATITUDE 范围
bike_fence['MIN_LATITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.min(x[:, 1]))
bike_fence['MAX_LATITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.max(x[:, 1]))# 得到停车点 LONGITUDE 范围
bike_fence['MIN_LONGITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.min(x[:, 0]))
bike_fence['MAX_LONGITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.max(x[:, 0]))from geopy.distance import geodesic
# 根据停车点 范围 计算具体的面积
bike_fence['FENCE_AREA'] = bike_fence.apply(lambda x: geodesic((x['MIN_LATITUDE'], x['MIN_LONGITUDE']), (x['MAX_LATITUDE'], x['MAX_LONGITUDE'])
).meters, axis=1)# 根据停车点 计算中心经纬度
bike_fence['FENCE_CENTER'] = bike_fence['FENCE_LOC'].apply(lambda x: np.mean(x[:-1, ::-1], 0)
)

深入了解Geohash可参考下面文章:

Geohash

import geohash
bike_order['geohash'] = bike_order.apply(lambda x: geohash.encode(x['LATITUDE'], x['LONGITUDE'], precision=6), 
axis=1)bike_fence['geohash'] = bike_fence['FENCE_CENTER'].apply(lambda x: geohash.encode(x[0], x[1], precision=6)
)
bike_order['UPDATE_TIME'] = pd.to_datetime(bike_order['UPDATE_TIME'])
bike_order['DAY'] = bike_order['UPDATE_TIME'].dt.day.astype(object)
bike_order['DAY'] = bike_order['DAY'].apply(str)bike_order['HOUR'] = bike_order['UPDATE_TIME'].dt.hour.astype(object)
bike_order['HOUR'] = bike_order['HOUR'].apply(str)
bike_order['HOUR'] = bike_order['HOUR'].str.pad(width=2,side='left',fillchar='0')# 日期和时间进行拼接
bike_order['DAY_HOUR'] = bike_order['DAY'] + bike_order['HOUR']
bike_order[bike_order['geohash'] == 'ws7gx9']

在这里插入图片描述
区域流量与潮汐统计
在完成具体的经纬度匹配后,接下来就需要完成具体的区域流量统计,即统计某一范围内的不同时间的流量(入流量和出流量)。

首先对订单数据进行时间提取:

bike_order['UPDATE_TIME'] = pd.to_datetime(bike_order['UPDATE_TIME'])
bike_order['DAY'] = bike_order['UPDATE_TIME'].dt.day.astype(object)
bike_order['DAY'] = bike_order['DAY'].apply(str)bike_order['HOUR'] = bike_order['UPDATE_TIME'].dt.hour.astype(object)
bike_order['HOUR'] = bike_order['HOUR'].apply(str)
bike_order['HOUR'] = bike_order['HOUR'].str.pad(width=2,side='left',fillchar='0')# 日期和时间进行拼接
bike_order['DAY_HOUR'] = bike_order['DAY'] + bike_order['HOUR']

使用透视表统计每个区域在不同时间的入流量和出流量:

bike_inflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 1], values='LOCK_STATUS', index=['geohash'],columns=['DAY_HOUR'], aggfunc='count', fill_value=0
)bike_outflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 0], values='LOCK_STATUS', index=['geohash'],columns=['DAY_HOUR'], aggfunc='count', fill_value=0
)
bike_inflow.loc['wsk593'].plot()
bike_outflow.loc['wsk593'].plot()
plt.xticks(list(range(bike_inflow.shape[1])), bike_inflow.columns, rotation=40)
plt.legend(['入流量', '出流量'])

在这里插入图片描述

bike_inflow.loc['wsk52r'].plot()
bike_outflow.loc['wsk52r'].plot()
plt.xticks(list(range(bike_inflow.shape[1])), bike_inflow.columns, rotation=40)
plt.legend(['入流量', '出流量'], prop = None)

在这里插入图片描述
方法1:Geohash匹配计算潮汐
由于赛题需要统计工作日早高峰期间的潮汐现象,所以我们可以按照天进行单车流量统计:

bike_inflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 1], values='LOCK_STATUS', index=['geohash'],columns=['DAY'], aggfunc='count', fill_value=0
)bike_outflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 0], values='LOCK_STATUS', index=['geohash'],columns=['DAY'], aggfunc='count', fill_value=0
)

根据入流量和出流量,可以计算得到每个位置的留存流量:

bike_remain = (bike_inflow - bike_outflow).fillna(0)# 存在骑走的车数量 大于 进来的车数量
bike_remain[bike_remain < 0] = 0  # 按照天求平均
bike_remain = bike_remain.sum(1)

就可以得到潮汐情况最严重的道路,并且导出结果并提交测试:

# 总共有993条街
bike_fence['STREET'] = bike_fence['FENCE_ID'].apply(lambda x: x.split('_')[0])# 留存车辆 / 街道停车位总面积,计算得到密度
bike_density = bike_fence.groupby(['STREET'])['geohash'].unique().apply(lambda hs: np.sum([bike_remain[x] for x in hs])
) / bike_fence.groupby(['STREET'])['FENCE_AREA'].sum()# 按照密度倒序
bike_density = bike_density.sort_values(ascending=False).reset_index()
bike_density.to_csv('./result.txt', index=None, sep='|')

方法2:距离匹配计算潮汐
如果使用Geohash来统计会存在一个问题,统计的方法会不准确,导致只能精确到街道信息。本节将使用经纬度距离匹配的方法来进行尝试,具体的思路为计算订单最近的停车点,进而计算具体的潮汐情况。

对于经纬度距离计算,可以直接使用sklearn中的NearestNeighbors,通过设置haversine距离可以很方便的完成最近停车点的计算。

from sklearn.neighbors import NearestNeighbors# https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.DistanceMetric.html
knn = NearestNeighbors(metric = "haversine", n_jobs=-1, algorithm='brute')
knn.fit(np.stack(bike_fence['FENCE_CENTER'].values))

在这里插入图片描述
但是如果直接使用NearestNeighbors计算速度会非常慢,如果是全量定量订单数据可能需要较长时间。因此可以用hnsw做近似搜索,速度较快但精度差一点。

import hnswlib
import numpy as npp = hnswlib.Index(space='l2', dim=2)
p.init_index(max_elements=300000, ef_construction=1000, M=32)
p.set_ef(1024)
p.set_num_threads(14)p.add_items(np.stack(bike_fence['FENCE_CENTER'].values))

计算所有订单的停车位置:

index, dist = p.knn_query(bike_order[['LATITUDE','LONGITUDE']].values[:], k=1)

计算所有停车点的潮汐流量:

bike_order['fence'] = bike_fence.iloc[index.flatten()]['FENCE_ID'].valuesbike_inflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 1], values='LOCK_STATUS', index=['fence'],columns=['DAY'], aggfunc='count', fill_value=0
)bike_outflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 0], values='LOCK_STATUS', index=['fence'],columns=['DAY'], aggfunc='count', fill_value=0
)bike_remain = (bike_inflow - bike_outflow).fillna(0)
bike_remain[bike_remain < 0] = 0  
bike_remain = bike_remain.sum(1)

计算停车点的密度:

bike_density = bike_remain / bike_fence.set_index('FENCE_ID')['FENCE_AREA']
bike_density = bike_density.sort_values(ascending=False).reset_index()
bike_density = bike_density.fillna(0)

最终提交结果:
在这里插入图片描述

这篇关于DCIC-早高峰共享单车潮汐点的群智优化(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/358893

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

# VMware 共享文件

VMware tools快速安装 VMware 提供了 open-vm-tools,这是 VMware 官方推荐的开源工具包,通常不需要手动安装 VMware Tools,因为大多数 Linux 发行版(包括 Ubuntu、CentOS 等)都包含了 open-vm-tools,并且已经优化以提供与 VMware 环境的兼容性和功能支持。 建议按照以下步骤安装 open-vm-tools 而不

未来工作趋势:零工小程序在共享经济中的作用

经济在不断发展的同时,科技也在飞速发展。零工经济作为一种新兴的工作模式,正在全球范围内迅速崛起。特别是在中国,随着数字经济的蓬勃发展和共享经济模式的深入推广,零工小程序在促进就业、提升资源利用效率方面显示出了巨大的潜力和价值。 一、零工经济的定义及现状 零工经济是指通过临时性、自由职业或项目制的工作形式,利用互联网平台快速匹配供需双方的新型经济模式。这种模式打破了传统全职工作的界限,为劳动

构建高性能WEB之HTTP首部优化

0x00 前言 在讨论浏览器优化之前,首先我们先分析下从客户端发起一个HTTP请求到用户接收到响应之间,都发生了什么?知己知彼,才能百战不殆。这也是作为一个WEB开发者,为什么一定要深入学习TCP/IP等网络知识。 0x01 到底发生什么了? 当用户发起一个HTTP请求时,首先客户端将与服务端之间建立TCP连接,成功建立连接后,服务端将对请求进行处理,并对客户端做出响应,响应内容一般包括响应