作者主页:编程指南针

作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师

主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助

文末获取源码

一,项目简介

如今互联网与电子商务的飞速发展,物流服务行业也日益重要,如何提升物流服务的效率,降低物流服务的成本成为当下人们所关注的内容。大多数的传统物流运输业花费大量的金钱和人力在运输、仓储、配送中,因此这些传统物流企业大多成本高利润低。为了保证物流市场的健康发展,需要有效地支持物流配送,提高物流质量服务。而物流配送活动,作为连接商家和客户的关键环节最应当被重视和优化,从而避免出现物流配送效率低、资源浪费严重和配送成本高等问题,以此来提升我国物流行业的整体发展。

物流配送优化主要可以从2个方面进行优化。一、提高车辆的装载问题:即车辆装载问题(VehicleFillingProblem.VFP)。二、减少车辆运输路径:即车辆装载问题(VehicleRoutingProblem.VRP)。本文将使用IDEA作为开发工具,java作为开发语言,建立货车装载和配送货物的模型,通过算法对VFP和VRP同时进行优化,得到如何进行货物配送才能最优的解决方案。并使用html语言,在web页面上进行动画展示。

目前已经研发完毕,在Web界面上演示效果佳,人机交互效果好,反应较快。同时与未采用该算法的传统配送方案相比,该程序得到的运输方案,货车装载率有了明显提高和运输路途的总里程有显著降低。通过该程序成功实现了物流拼单组合系统,有效提升物流服务的效率

二,环境介绍

语言环境:Java:  jdk1.8

数据库:Mysql: mysql5.7

应用服务器:Tomcat:  tomcat8.5.31

开发工具:IDEA或eclipse

后台开发技术:Springboot+Mybatis

前台开发技术:html5 + javascript+thymeleaf

三,系统展示

3.1 系统的功能点描述

本系统为物流拼单组合系统,主要功能有查看送货地点,分配货车,查看所有的路径规划,查看单个路径动画,查看所有路径动画。

3.2 系统功能的具体测试

3.2.1 查看送货地点

(1)测试用例:

使用随机数随机生成200个起点一致,终点和货物种类、数量不一致的当日订单,生成随机订单程序核心代码截图如下图5-1所示,库中部分订单数据如下图5-2所示。

图5‑1 生成200个随机订单的核心代码

图5‑2 数据库200个订单部分截图

(2)测试结果:

图5‑3 查看送货地点测试结果

(3)结果描述:

选定时间后,点击查看送货地点,前端向后端发送请求,后端将当日所有订单结果返回,如下图5-4所示:

图5‑4 前端发送请求后端返回结果图。

前端解析json后,在地图上进行标注,显示中文名称和需要配送的体积。

3.2.2 分配货车

(1)测试用例:

有5种货车,分别为体积为600,1000,1400,2200,2500,这五种货车,和5.2.1生成的200个订单。

  1. 测试结果:

图5‑5 查看送货地点测试结果

  1. 结果描述:

点击分配货车后,前端向后端发送请求,后端返回如何进行货车分配,前端解析后,显示派出哪种类型的车和派出数量,并计算出满载率并显示在页面上。

图5‑6 前端发送请求后端返回结果图。

3.2.3 查看所有的路径规划

(1)测试用例:

3.2.1生成的200个订单和5.2.2得到的货车分配

  1. 测试结果:

图5‑7 查看所有的路径规划部分结果

  1. 结果描述:

点击查看所有路径规划,向后端发送请求,如下图5-8所示后端返回所有路径返回,解析后显示成文字路径,包含了派出哪种类型的车,使用了多少的体积,起点、途经点、终点的名字和向这些地点配送了多少的体积,并将部分参数放在url中,生成超链接,可以通过单击超链接播放动画

图5‑8 前端发送请求后端返回结果图

3.2.4 查看单个路径动画

(1)测试用例:

3.2.3得到的路径

  1. 测试结果:

图5‑9 查看单个路径动画演示部分结果图

  1. 结果描述:

动态的展示单次货车配送的起点、途经点、终点名字和配送体积,三角形为模拟货车,绿色为货车行经路线。

3.2.5 查看所有路径动画

(1)测试用例:

3.2.3得到的所有路径

  1. 测试结果:

图5‑10 查看所有路径动画演示部分结果图

(3)结果描述:

动态的展示当日所有货车配送的起点、途经点、终点名字和配送体积,三角

形为模拟货车,绿色为货车行经路线。

3.3 本章小结

本章主要讲述了系统整体的功能点和对整体功能点的具体测试,包含测试用例,测试结果,结果分析,保证了系统的可用性

四,核心代码展示

业务层具体实现

业务层采用springboot框架。springboot继承了spring的优秀特性:控制反转,面向切面编程等,同时能帮助我们简化开发,减少XML的配置。

业务层主要通过调用持久层的接口获取存在数据库中的某个日期的订单集合。查询订单集合。根据订单上的起始地点id和终点id关联地点表,获得起始地点和终点的经纬度。根据货物id关联货物表可以得到货物的单位体积,与订单上的货物数量相乘就可以得到该订单需要配送的体积。从货车表知得知有哪些类型的货车可以使用,得到了以上数据,就能解决我们的第一个问题:货物装载问题。

使用Map作为存储的数据结构,key值为当前的体积,value值为构成这个体积的最少用车集合,实现动态规划求解货物装载问题的具体过程为先初始化一个map,key为0,value为””,循环遍历这个map的key,如果存在值,用这个值加货车的体积,就是新key,判断新key是否已经有value,如果没有value为旧key的value+货车的体积,中间用”,”分隔,如果有,将这个新value和老value进行比较,看哪一种“,”少,因为,少说明用车少,成本少,加到key值超过我们需要的货物总体积后遍从换到下一个货车,直到把货车遍历完,拿到最小值,取他的value就是我们的装配方案,关键代码如下图3-4,3-5所示:

图3-4 解决装配问题的核心算法

图3-5 解决装配问题的核心算法

拿到货车的具体安排后,根据具体安排和从数据库拿到的各种数据,即可使用区域划分解决本系统的路径规划问题,具体解决方案如下:

使用Map作为存储地点区域的集合,key值为角度值,例如”0,10”表示是与起点夹角(与x轴正向所成的角度),value值为地点区域的集合,一个键值对就表示与起点夹角为几度到几度的区域内的所有配送点。将从数据库拿到的所有地点放入到Map中后,通过遍历map的key,得到key所对应的value,得到当前区域的该配送的体积,如果大于起送体积,就通过计算各个点之间的距离,将各个点进行排序,根据顺序开始配送,如果小于就换成下一个key,当key遍历完成后,查看是否有剩余货物没被配送,若没有则结束,若有则将角度加大10度,重复上述操作,直到货物全部配送完全为止。关键代码,如下图所示:

图3-6 解决区域划分问题的核心算法

图3-7 解决区域划分问题的核心算法

package com.dwy.logistics.controller;import com.dwy.logistics.model.dto.front.CarFrontDTO;
import com.dwy.logistics.model.dto.front.PlaceFrontDTO;
import com.dwy.logistics.model.dto.front.RouteFrontDTO;
import com.dwy.logistics.model.dto.front.TransportFrontDTO;
import com.dwy.logistics.service.IFrontService;
import com.dwy.logistics.service.IOrdersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.Date;
import java.util.List;/*** @Author: znz* @Date: 2022/8/12 15:42*/
@RestController
@Slf4j
@RequestMapping("/front")
public class FrontController {@ResourceIFrontService frontService;@GetMapping("/place")public List<PlaceFrontDTO> getPlaceFrontDTO(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") Date date){return frontService.getPlaceFrontDTO(date);}@GetMapping("/car")public  List<CarFrontDTO> getCarFrontDTO(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") Date date){return frontService.getCarFrontDTO(date);}@GetMapping("/transport")public  List<TransportFrontDTO> getTransportFrontDTO(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") Date date){return frontService.getTransportFrontDTO(date);}@GetMapping("/route")public  List<RouteFrontDTO> getRouteFrontDTO(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") Date date){return frontService.getRouteFrontDTO(date);}
}
package com.dwy.logistics.service.impl;import com.dwy.logistics.consts.CONST;
import com.dwy.logistics.model.dto.distance.report.CarRouteReportDTO;
import com.dwy.logistics.model.dto.distance.report.TruckRouteReportDTO;
import com.dwy.logistics.model.dto.distance.PathDTO;
import com.dwy.logistics.model.dto.front.PlaceFrontDTO;
import com.dwy.logistics.model.dto.place.PlaceDTO;
import com.dwy.logistics.service.IPlaceDTOService;
import com.dwy.logistics.service.IRouteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;/*** @Author: znz* @Date: 2022/8/4 16:52*/
@Service
@Slf4j
public class RouteServiceImpl extends AbstractServiceImpl implements IRouteService {@ResourceIPlaceDTOService placeService;@Overridepublic double getTrunkMinDistance(PlaceDTO startPlace, PlaceDTO endPlace, int size) {//https://restapi.amap.com/v4/direction/truck?parametersTruckRouteReportDTO truckRouteReportDTO =sendGet("https://restapi.amap.com/v4/direction/truck?key="+ CONST.GAODE_MAP_KEY+"&origin="+startPlace.getLocation()+"&originid="+startPlace.getId()+"&destination="+endPlace.getLocation()+"&destinationid="+endPlace.getId()+"&size="+size).toJavaObject(TruckRouteReportDTO.class);List<PathDTO> paths = truckRouteReportDTO.getData().getRoute().getPaths();return getMinDistance(paths);}@Overridepublic double getCarMinDistance(PlaceDTO startPlace, PlaceDTO endPlace) {CarRouteReportDTO carRouteReportDTO =sendGet("https://restapi.amap.com/v3/direction/driving?key="+ CONST.GAODE_MAP_KEY+"&origin="+startPlace.getLocation()+"&originid="+startPlace.getId()+"&destination="+endPlace.getLocation()+"&destinationid="+endPlace.getId()+"&strategy="+"10").toJavaObject(CarRouteReportDTO.class);List<PathDTO> paths = carRouteReportDTO.getRoute().getPaths();return getMinDistance(paths);}@Overridepublic double getCarMinDistance(String startPlaceID, String endPlaceID) {PlaceDTO startPlace = placeService.getPlaceDTOByID(startPlaceID);PlaceDTO endPlace = placeService.getPlaceDTOByID(endPlaceID);return getCarMinDistance(startPlace,endPlace);}@Overridepublic double getCarMinDistance(PlaceFrontDTO startPlace, PlaceFrontDTO endPlace) {String url = "https://restapi.amap.com/v3/direction/driving?key="+ CONST.GAODE_MAP_KEY+"&origin="+startPlace.getLng()+","+startPlace.getLat()+"&destination="+endPlace.getLng()+","+endPlace.getLat()+"&strategy="+"10";log.info("url:"+url);CarRouteReportDTO carRouteReportDTO =sendGet(url).toJavaObject(CarRouteReportDTO.class);List<PathDTO> paths = carRouteReportDTO.getRoute().getPaths();return getMinDistance(paths);}private double getMinDistance(List<PathDTO> paths){double minDistance = paths.get(0).getDistance();for (int i = 1 ; i <paths.size() ; i++){if (minDistance > paths.get(i).getDistance()) {minDistance = paths.get(i).getDistance();}}return minDistance;}
}
package com.dwy.logistics.service.impl;import com.dwy.logistics.mapper.PlaceMapper;
import com.dwy.logistics.model.dto.place.PlaceDTO;
import com.dwy.logistics.model.entities.Place;
import com.dwy.logistics.model.entities.PlaceKey;
import com.dwy.logistics.service.IPlaceDTOService;
import com.dwy.logistics.service.IPlaceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** @Author: znz* @Date: 2022/8/5 17:52*/
@Service
@Slf4j
public class PlaceServiceImpl implements IPlaceService {@ResourcePlaceMapper placeMapper;@ResourceIPlaceDTOService placeDTOService;@Overridepublic Place selectPlaceByID(String id) {PlaceKey placeKey = new PlaceKey();placeKey.setUid(id);return placeMapper.selectByPrimaryKey(placeKey);}@Overridepublic int insertPlace(Place place) {log.debug("insertPlace:"+place.toString());return placeMapper.insert(place);}@Overridepublic int insertPlaceByName(String keywords, String cityName) {log.debug("insertPlaceByName,keywords:"+keywords+",cityName:"+cityName);PlaceDTO placeDTO = placeDTOService.getFirstPlaceDTO(keywords, cityName);Place place = PlaceDTOToPlace(placeDTO);log.debug("insertPlaceByName:"+place.toString());return placeMapper.insert(place);}@Overridepublic int deletePlace(String id) {PlaceKey placeKey = new PlaceKey();placeKey.setUid(id);return placeMapper.deleteByPrimaryKey(placeKey);}private Place PlaceDTOToPlace(PlaceDTO placeDTO){Place place = new Place();String s[] = placeDTO.getLocation().split(",");place.setUid(placeDTO.getId());place.setLat(Double.parseDouble(s[1]));place.setLng(Double.parseDouble(s[0]));place.setName(placeDTO.getName());return place;}
}

五,项目总结

Springboot智能物流拼单组合系统设计与实现相关推荐

  1. 基于SpringBoot的智能物流监控系统数据系统

    摘 要 在万物互联的大背景下,将物流行业纳入物联网生态中是一件非常有必要的事情.本课题希冀为完善物联网生态中的物流行业而贡献自己的力量,其目的是构建一套适合预设物流监控需求的系统,让物流运输相对于所有 ...

  2. (附源码)基于springboot的物流配货管理系统的设计与实现 毕业设计 250858

    基于springboot物流配货管理系统的设计与实现 摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这 ...

  3. (附源码)springboot 智能停车场系统 毕业设计065415

    springboot智能停车场管理系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用.信息时代的到来已成为不可阻挡的时 ...

  4. 智能物流给力零售业跨越式发展

    2010年,我国社会物流总额达到125万亿元,是"十五"末期的1.26倍,"十一五"年均增长21%,而物流业增加值每多一个百分点,将多10万个工作岗位.可以说, ...

  5. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java智能物流管理系统k852w

    好的选题直接决定了毕业设计好坏,甚至决定了能否毕业.今天,我们就来聊一聊毕设该怎么选题. 这里分三个选题标准. 第一,参考所在学校往年选题类型和难度 可以向学长学姐了解往年的选题类型,以及使用的技术, ...

  6. 【智能物流】200亿规模的制造企业,如何规划供应链物流体系?

    作者 | 黄尧笛 来源 | 环球物流咨询 模拟集团公司的背景:行业:某离散型制造企业:公司营收:规模200亿,增长速度20%:下属子公司:集团有物流公司:物流公司营收:10亿. "场景一&q ...

  7. java-php-python-springboot智能物流运输管理系统登录计算机毕业设计

    java-php-python-springboot智能物流运输管理系统登录计算机毕业设计 java-php-python-springboot智能物流运输管理系统登录计算机毕业设计 本源码技术栈: ...

  8. springboot+mysql物流车辆管理系统-计算机设计源码84722

    摘要 由于数据库和数据仓库技术的快速发展,物流车辆管理系统建设越来越向模块化.智能化.自我服务和管理科学化的方向发展.物流车辆管理系统对处理对象和服务对象,自身的系统结构,处理能力,都将适应技术发展的 ...

  9. bulter机器人_双十一来了,盘点全球最受欢迎的10大智能物流机器人

    原标题:双十一来了,盘点全球最受欢迎的10大智能物流机器人 近年来的双十一可谓堪比春运,据<中国新闻网>报道,2018年天猫双11再创历史新高.截止11月11日24点,成交额达2135亿元 ...

最新文章

  1. 互联网协议 — TCP — (面向面向连接的)三次握手、四次挥手
  2. 004_Icon图标
  3. Redis的简单实践
  4. ServletRequest startAsync()的有用性有限
  5. 如何使柱状图左右展示_Excel多次层柱状图,让数据展示更清晰,简单五步就完成...
  6. linux-压缩与解压缩
  7. 在线JSON美化格式化工具
  8. docker 拷贝镜像文件
  9. WPF教程二:布局之StackPanel面板
  10. javaweb开发后端常用技术_Java web开发需要学习哪些技术?
  11. Word怎么转换成长图
  12. 如何破解终端算力困局?PRCV这篇论文让机器人“算有余力”
  13. 1至10根号计算机,根号1到10分别约等于多少
  14. C++--数字转大写金额
  15. 全国企业信用信息公示系统
  16. 定制嵌入式主板需要考虑的功能
  17. 【我上岸了】干了两年外包的我拿到阿里offer了,在此总结一下我从外包到阿里的经验吧
  18. 小博无线认证无法连接服务器,路由器wan口认证失败
  19. oracle数据库报300006,Bad HDD - Restoring VMs
  20. 浮士德html5图片裁剪器2016开源版

热门文章

  1. kill命令——系统内部执行流程
  2. 公司有了智能人脸识别门禁考勤机让员工考勤更轻松
  3. 项目经理怎么做,才能让领导爱听你的工作汇报?
  4. access 查询符合条件的第一条记录
  5. 名编辑电子杂志大师教程 | 电脑版、手机版设置
  6. COUNT函数的使用
  7. 新版Maixhub部署(V831与K210)
  8. 49深入聚合数据分析_cardinality算法之优化内存开销以及HLL算法
  9. Java-IO File
  10. HTML5 canvas基础与「生成名片」应用程序