Commit ca9dd7dbc3d13a38ad784f87ef62cf3571e5d4bc
1 parent
abd1f204
时刻表v2_2.2
1、将选择班次逻辑,生成间隔逻辑单独成策略类,放在v2版本的StrategyUtils里引用 2、修正班次选择逻辑,其他分班选择班次逻辑,下午车次链定在15:00后所有班次都出,并且如果超出了总班次数,且当前班次还是高峰的话,也添加 3、修正生成间隔逻辑,高峰间隔也使用步长的方式从最小值开始添加,当前班次时间段全看前一个班次时间段,迭代频率改成3 4、行车计划对象计算最小周转时间使用主站停站时间,最大周转时间使用2倍的主站停站时间
Showing
9 changed files
with
829 additions
and
489 deletions
src/main/resources/static/pages/base/timesmodel/gantt.html
| ... | ... | @@ -179,7 +179,6 @@ |
| 179 | 179 | <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS2.js"></script> |
| 180 | 180 | <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS3.js"></script> |
| 181 | 181 | <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS4.js"></script> |
| 182 | -<script src="/pages/base/timesmodel/js/v2/strategy/StrategyUtils.js"></script> | |
| 183 | 182 | <script src="/pages/base/timesmodel/js/v2/main_v2.js"></script> |
| 184 | 183 | |
| 185 | 184 | <!-- |
| ... | ... | @@ -189,6 +188,10 @@ |
| 189 | 188 | |
| 190 | 189 | <script src="/pages/base/timesmodel/js/v2_2/InternalScheduleObj.js"></script> |
| 191 | 190 | <script src="/pages/base/timesmodel/js/v2_2/main_v2_2.js"></script> |
| 191 | +<script src="/pages/base/timesmodel/js/v2_2/strategy/bc/DecideBcTripS1.js"></script> | |
| 192 | +<script src="/pages/base/timesmodel/js/v2_2/strategy/interval/CalcuIntervalS1.js"></script> | |
| 193 | +<script src="/pages/base/timesmodel/js/v2/strategy/StrategyUtils.js"></script> | |
| 194 | + | |
| 192 | 195 | <script src="/pages/base/timesmodel/js/errorinfo.js"></script> |
| 193 | 196 | <script src="/pages/base/timesmodel/js/parameters.js"></script> |
| 194 | 197 | <script src="/pages/base/timesmodel/js/systemTools.js"></script> | ... | ... |
src/main/resources/static/pages/base/timesmodel/js/d3.relationshipgraph.js
| ... | ... | @@ -321,7 +321,7 @@ $('.parambtn').on('click', function() { |
| 321 | 321 | $.get('/pages/base/timesmodel/paramadd.html', function(m){ |
| 322 | 322 | $(pjaxContainer).append(m); |
| 323 | 323 | // 规定被选元素要触发的事件。可以使自定义事件(使用 bind() 函数来附加),或者任何标准事件。 |
| 324 | - $('#paramadd_mobal').trigger('paramAddMobal.show', [Main_v2, Main_v2_2]); | |
| 324 | + $('#paramadd_mobal').trigger('paramAddMobal.show', [Main_v2, Main_v2_2, InternalScheduleObj_v2_2]); | |
| 325 | 325 | }); |
| 326 | 326 | }); |
| 327 | 327 | ... | ... |
src/main/resources/static/pages/base/timesmodel/js/v2/core/InternalLpObj.js
| ... | ... | @@ -267,6 +267,33 @@ InternalLpObj.prototype.getBcArray = function() { |
| 267 | 267 | }; |
| 268 | 268 | |
| 269 | 269 | /** |
| 270 | + * 返回指定时间后的班次列表。 | |
| 271 | + * @param oFromTime | |
| 272 | + * @return {Array} | |
| 273 | + */ | |
| 274 | +InternalLpObj.prototype.getBcArrayFromTime = function(oFromTime) { | |
| 275 | + var bcArray = []; | |
| 276 | + var i; | |
| 277 | + var group; | |
| 278 | + var oBc; | |
| 279 | + for (i = 0; i < this._$_groupBcArray.length; i++) { | |
| 280 | + group = this._$_groupBcArray[i]; | |
| 281 | + if (group) { | |
| 282 | + oBc = group.getBc1(); | |
| 283 | + if (oBc && oBc.getFcTimeObj().isAfter(oFromTime)) { | |
| 284 | + bcArray.push(oBc); | |
| 285 | + } | |
| 286 | + oBc = group.getBc2(); | |
| 287 | + if (oBc && oBc.getFcTimeObj().isAfter(oFromTime)) { | |
| 288 | + bcArray.push(oBc); | |
| 289 | + } | |
| 290 | + } | |
| 291 | + } | |
| 292 | + | |
| 293 | + return bcArray; | |
| 294 | +}; | |
| 295 | + | |
| 296 | +/** | |
| 270 | 297 | * 获取最小(最早)班次对象。 |
| 271 | 298 | * @returns [{圈index},{班次index}] |
| 272 | 299 | */ |
| ... | ... | @@ -1136,7 +1163,7 @@ InternalLpObj.prototype.modifyLayoverTimeWithoutFcTime = function() { |
| 1136 | 1163 | iDiff = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m"); |
| 1137 | 1164 | if (oNextBc.fnGetEatTime() > 0) { |
| 1138 | 1165 | oBc.setStopTime(iDiff - oNextBc.fnGetEatTime()); |
| 1139 | - } else if (iDiff > 60) { // 大于60分钟,肯定车次链结束班次,停站0 | |
| 1166 | + } else if (iDiff > 120) { // 大于60分钟,肯定车次链结束班次,停站0 | |
| 1140 | 1167 | oBc.setStopTime(0); |
| 1141 | 1168 | } else { |
| 1142 | 1169 | oBc.setStopTime(iDiff); | ... | ... |
src/main/resources/static/pages/base/timesmodel/js/v2/strategy/StrategyUtils.js
| 1 | -/** | |
| 2 | - * 策略工具类。 | |
| 3 | - */ | |
| 4 | -var StrategyUtils = (function() { | |
| 5 | - /** | |
| 6 | - * 内部策略配置封装类。 | |
| 7 | - * @constructor | |
| 8 | - */ | |
| 9 | - function InternalStrategy() { | |
| 10 | - // 策略函数对应,每个函数都由一个标识符号对应,类似配置函数 | |
| 11 | - this._oSTRATIGIS = { | |
| 12 | - // ADJUST_TRIP表示调整发车间隔的策略,都放在strategy/adjust目录下 | |
| 13 | - // 每种策略对应一个js文件,里面的变量名就是策略名 | |
| 14 | - "ADJUST_TRIP": AdjustTripS1 | |
| 15 | - }; | |
| 16 | - } | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * 返回策略函数 | |
| 20 | - * @param str 标识 | |
| 21 | - * @returns {function} | |
| 22 | - */ | |
| 23 | - InternalStrategy.prototype.sFn = function(str) { | |
| 24 | - if (!this._oSTRATIGIS[str]) { | |
| 25 | - throw "指定标识" + str + "策略函数不存在!"; | |
| 26 | - } | |
| 27 | - return this._oSTRATIGIS[str]; | |
| 28 | - }; | |
| 29 | - /** | |
| 30 | - * 替换策略配置 | |
| 31 | - * @param str 策略函数标识 | |
| 32 | - * @param fn 策略函数 | |
| 33 | - */ | |
| 34 | - InternalStrategy.prototype.sConfig = function(str, fn) { | |
| 35 | - this._oSTRATIGIS[str] = fn; | |
| 36 | - }; | |
| 37 | - | |
| 38 | - return new InternalStrategy(); | |
| 1 | +/** | |
| 2 | + * 策略工具类。 | |
| 3 | + */ | |
| 4 | +var StrategyUtils = (function() { | |
| 5 | + /** | |
| 6 | + * 内部策略配置封装类。 | |
| 7 | + * @constructor | |
| 8 | + */ | |
| 9 | + function InternalStrategy() { | |
| 10 | + // 策略函数对应,每个函数都由一个标识符号对应,类似配置函数 | |
| 11 | + this._oSTRATIGIS = { | |
| 12 | + // ADJUST_TRIP表示调整发车间隔的策略,都放在strategy/adjust目录下 | |
| 13 | + // 每种策略对应一个js文件,里面的变量名就是策略名 | |
| 14 | + "ADJUST_TRIP": AdjustTripS1, | |
| 15 | + // DECIDE_TRIP表示不同的班型路牌判定每一圈每个位置是否有班次,v2_2版本中使用 | |
| 16 | + "DECIDE_TRIP": DecideBcTripS1, | |
| 17 | + // CALCU_INTERVAL表示每一圈的发车间隔计算,v2_2版本中使用 | |
| 18 | + "CALCU_INTERVAL": CalcuIntervalS1 | |
| 19 | + }; | |
| 20 | + } | |
| 21 | + | |
| 22 | + /** | |
| 23 | + * 返回策略函数 | |
| 24 | + * @param str 标识 | |
| 25 | + * @returns {function} | |
| 26 | + */ | |
| 27 | + InternalStrategy.prototype.sFn = function(str) { | |
| 28 | + if (!this._oSTRATIGIS[str]) { | |
| 29 | + throw "指定标识" + str + "策略函数不存在!"; | |
| 30 | + } | |
| 31 | + return this._oSTRATIGIS[str]; | |
| 32 | + }; | |
| 33 | + /** | |
| 34 | + * 替换策略配置 | |
| 35 | + * @param str 策略函数标识 | |
| 36 | + * @param fn 策略函数 | |
| 37 | + */ | |
| 38 | + InternalStrategy.prototype.sConfig = function(str, fn) { | |
| 39 | + this._oSTRATIGIS[str] = fn; | |
| 40 | + }; | |
| 41 | + | |
| 42 | + return new InternalStrategy(); | |
| 39 | 43 | } ()); |
| 40 | 44 | \ No newline at end of file | ... | ... |
src/main/resources/static/pages/base/timesmodel/js/v2_2/InternalScheduleObj.js
| ... | ... | @@ -328,7 +328,7 @@ var InternalScheduleObj_v2_2 = (function() { |
| 328 | 328 | // 总共车辆数(高峰最大车辆数) |
| 329 | 329 | var iCls = InternalScheduleObj.calcuClzx(this._oParam); |
| 330 | 330 | // 低谷最少配车(连班车数量) |
| 331 | - var iDgminpc = Math.round(this._oParam.calcuTroughZzsj() / this._oParam.getTroughMaxFcjx()); | |
| 331 | + var iDgminpc = Math.ceil(this._oParam.calcuTroughZzsj() / this._oParam.getTroughMaxFcjx()); | |
| 332 | 332 | // 加班车路牌数(做5休2的路牌数) |
| 333 | 333 | var i_5_2_lpes = this._oParam.getJBLpes(); |
| 334 | 334 | |
| ... | ... | @@ -351,6 +351,9 @@ var InternalScheduleObj_v2_2 = (function() { |
| 351 | 351 | iDgminpc = iCls - i_5_2_lpes; |
| 352 | 352 | } |
| 353 | 353 | |
| 354 | + // TODO:如果其他分班路牌数,连班路牌数相差比较远,则可以让二者对半分 | |
| 355 | + // TODO:前提是对半分之后连班路牌数要大于等于最少连班路牌数 | |
| 356 | + | |
| 354 | 357 | //// 修正连班路牌数,班次间隔大于20的,加1,直至班次间隔小于20 |
| 355 | 358 | //while(_paramObj.calcuPeakZzsj() / iDgminpc > 20) { |
| 356 | 359 | // iDgminpc ++; |
| ... | ... | @@ -527,7 +530,12 @@ var InternalScheduleObj_v2_2 = (function() { |
| 527 | 530 | var _modifyTime; // 上标线下一个圈班次的前一个班次的调整时间 |
| 528 | 531 | |
| 529 | 532 | if (oSlaveBc) { |
| 530 | - aBcInterval = this._$fnGetBcInterval(iSlaveGroupIndex, iSlaveBcIndex, 3); | |
| 533 | + aBcInterval = this._$fnGetBcInterval( | |
| 534 | + iSlaveGroupIndex, iSlaveBcIndex, | |
| 535 | + this._$calcuCycleTime(oSlaveBc.getFcTimeObj())[0], // 最小周转时间 | |
| 536 | + this._$calcuCycleTime(oSlaveBc.getFcTimeObj())[1] // 最大周转时间 | |
| 537 | + ); | |
| 538 | + console.log(this._$calcuCycleTime(oSlaveBc.getFcTimeObj())); | |
| 531 | 539 | oPreBc = this._internalLpArray[0].getBc(iSlaveGroupIndex, iSlaveBcIndex); |
| 532 | 540 | for (i = 1; i < this._internalLpArray.length; i++) { |
| 533 | 541 | oBcInterval = aBcInterval[i - 1]; |
| ... | ... | @@ -668,21 +676,23 @@ var InternalScheduleObj_v2_2 = (function() { |
| 668 | 676 | if (!this._internalLpArray[i - 1].getBc(0, 1)) { |
| 669 | 677 | // 上一个路牌没有班次,添加 |
| 670 | 678 | oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次 |
| 671 | - oSLp.setBc( | |
| 672 | - 0, 1, | |
| 673 | - _utils.createBcObj( | |
| 674 | - oSLp, | |
| 675 | - "normal", | |
| 676 | - !this._qIsUp, | |
| 677 | - 1, | |
| 678 | - this._oParam.addMinute(oSBc.getFcTimeObj(), -(iStRuntime + 1)), | |
| 679 | - this._oParam) | |
| 680 | - ); | |
| 681 | - | |
| 682 | - // 如果生成的班次行驶时间不足,删除这个班次 | |
| 683 | - if (oSLp.getBc(1, 0).getFcTimeObj().isBefore(oSLp.getBc(0, 1).getArrTimeObj())) { | |
| 684 | - oSLp.getGroup(0).setBc1(undefined); | |
| 685 | - oSLp.getGroup(0).setBc2(undefined); | |
| 679 | + if (oSBc) { | |
| 680 | + oSLp.setBc( | |
| 681 | + 0, 1, | |
| 682 | + _utils.createBcObj( | |
| 683 | + oSLp, | |
| 684 | + "normal", | |
| 685 | + !this._qIsUp, | |
| 686 | + 1, | |
| 687 | + this._oParam.addMinute(oSBc.getFcTimeObj(), -(iStRuntime + 1)), | |
| 688 | + this._oParam) | |
| 689 | + ); | |
| 690 | + | |
| 691 | + // 如果生成的班次行驶时间不足,删除这个班次 | |
| 692 | + if (oSLp.getBc(1, 0).getFcTimeObj().isBefore(oSLp.getBc(0, 1).getArrTimeObj())) { | |
| 693 | + oSLp.getGroup(0).setBc1(undefined); | |
| 694 | + oSLp.getGroup(0).setBc2(undefined); | |
| 695 | + } | |
| 686 | 696 | } |
| 687 | 697 | } |
| 688 | 698 | } |
| ... | ... | @@ -701,211 +711,41 @@ var InternalScheduleObj_v2_2 = (function() { |
| 701 | 711 | * @param oPreBc 上一个班次 |
| 702 | 712 | * @param iPreLpIndex 上一个班次路牌索引 |
| 703 | 713 | * @param iCurrentLpIndex 当前路牌索引 |
| 704 | - * @param iGroupIndex 圈索引 | |
| 705 | - * @param iBcIndex 班次索引 | |
| 714 | + * @param iCurrentGroupIndex 圈索引 | |
| 715 | + * @param iCurrentBcIndex 班次索引 | |
| 706 | 716 | * @private |
| 707 | 717 | */ |
| 708 | 718 | InternalScheduleObj.prototype._$fnDecideBxBc = function( |
| 709 | 719 | oPreBc, iPreLpIndex, |
| 710 | 720 | iCurrentLpIndex, |
| 711 | - iGroupIndex, iBcIndex) { | |
| 712 | - | |
| 713 | - var oCurrentLp = this._internalLpArray[iCurrentLpIndex]; // 当前路牌 | |
| 714 | - var oLpPreBc; // 当前路牌前一个班次 | |
| 715 | - | |
| 716 | - var iBxBcount; // 分班班型的可能班次数 | |
| 717 | - | |
| 718 | - if (oCurrentLp.isBxFb()) { // 分班 | |
| 719 | - // 关联的因素 | |
| 720 | - // 1、当前班次方向 | |
| 721 | - // 2、上一个班次情况 | |
| 722 | - // 3、同路牌前一个班次情况 | |
| 723 | - // 4、分班路牌工时限制 | |
| 721 | + iCurrentGroupIndex, iCurrentBcIndex) { | |
| 724 | 722 | |
| 723 | + // 使用策略函数方式 | |
| 724 | + return StrategyUtils.sFn("DECIDE_TRIP")( | |
| 725 | + this, this._oParam, | |
| 726 | + oPreBc, iPreLpIndex, | |
| 727 | + iCurrentLpIndex, iCurrentGroupIndex, iCurrentBcIndex | |
| 728 | + ); | |
| 725 | 729 | |
| 726 | - if (oCurrentLp.isBxFb5_2()) { // 5休2分班 | |
| 727 | - // 大致计算5休2班型班次数 | |
| 728 | - iBxBcount = this._aBxDesc[6].fBcCount; | |
| 729 | - if (iBxBcount - Math.floor(iBxBcount) > 0.7) { | |
| 730 | - iBxBcount = Math.floor(iBxBcount) + 1; | |
| 731 | - } else { | |
| 732 | - iBxBcount = Math.floor(iBxBcount); | |
| 733 | - } | |
| 734 | - | |
| 735 | - // 计算可能的5休2班次时间,供下一步判定 | |
| 736 | - var oNext5_2_bc_fctime_m = undefined; // 上午车次链参考班次时间 | |
| 737 | - var oNext5_2_bc_fctime_e = undefined; // 下午车次链参考班次时间 | |
| 738 | - if (oPreBc.getFcTimeObj().isBefore(this._oParam.toTimeObj("12:00"))) { // 上午车次链 | |
| 739 | - oNext5_2_bc_fctime_m = this._oParam.addMinute( | |
| 740 | - oPreBc.getFcTimeObj(), | |
| 741 | - Math.ceil((this._oParam.getMPeakMinFcjx() + this._oParam.getMPeakMaxFcjx()) / 2) | |
| 742 | - ); | |
| 743 | - } else { // 下午车次链 | |
| 744 | - oNext5_2_bc_fctime_e = this._oParam.addMinute( | |
| 745 | - oPreBc.getFcTimeObj(), | |
| 746 | - Math.ceil((this._oParam.getEPeakMinFcjx() + this._oParam.getEPeakMaxFcjx()) / 2) | |
| 747 | - ); | |
| 748 | - } | |
| 749 | - | |
| 750 | - // 先处理上午车次链 | |
| 751 | - if (oNext5_2_bc_fctime_m) { | |
| 752 | - if (oNext5_2_bc_fctime_m.isBefore(this._oParam.getMPeakStartTimeObj())) { | |
| 753 | - // 5休2班型第一个班次,如果在早高峰开始前低谷,不添加 | |
| 754 | - return false; | |
| 755 | - } else if (!oNext5_2_bc_fctime_m.isAfter(this._oParam.getMPeakEndTimeObj())) { | |
| 756 | - // 早高峰期间,添加 | |
| 757 | - return true; | |
| 758 | - } else { | |
| 759 | - // 早高峰之后低谷到12:00之间 | |
| 760 | - | |
| 761 | - // 当前路牌的前一个班次 | |
| 762 | - oLpPreBc = oCurrentLp.getBc(iBcIndex == 0 ? iGroupIndex - 1 : iGroupIndex, iBcIndex == 0 ? 1 : 0); | |
| 763 | - if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) { | |
| 764 | - // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 765 | - return false; | |
| 766 | - } else { | |
| 767 | - if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) { | |
| 768 | - // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次 | |
| 769 | - return true; | |
| 770 | - } else if (oLpPreBc.isUp() == this._oParam.isUpOneWayStop()) { | |
| 771 | - // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 772 | - // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 773 | - return true; | |
| 774 | - } else { | |
| 775 | - return false; | |
| 776 | - } | |
| 777 | - } | |
| 778 | - } | |
| 779 | - } | |
| 780 | - | |
| 781 | - // 再处理下午车次链 | |
| 782 | - if (oNext5_2_bc_fctime_e) { | |
| 783 | - if (oNext5_2_bc_fctime_e.isBefore(this._oParam.getEPeakStartTimeObj())) { | |
| 784 | - // 5休2班型第一个班次,如果在晚高峰开始前低谷,不添加 | |
| 785 | - return false; | |
| 786 | - } else if (!oNext5_2_bc_fctime_e.isAfter(this._oParam.getEPeakEndTimeObj())) { | |
| 787 | - // 晚高峰期间,添加 | |
| 788 | - return true; | |
| 789 | - } else { | |
| 790 | - // 晚高峰之后低谷 | |
| 791 | - | |
| 792 | - // 当前路牌的前一个班次 | |
| 793 | - oLpPreBc = oCurrentLp.getBc(iBcIndex == 0 ? iGroupIndex - 1 : iGroupIndex, iBcIndex == 0 ? 1 : 0); | |
| 794 | - if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) { | |
| 795 | - // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 796 | - return false; | |
| 797 | - } else { | |
| 798 | - if (oCurrentLp.getBcArray().length < iBxBcount) { | |
| 799 | - // 如果总班次数比iBxBcount少,加班次 | |
| 800 | - return true; | |
| 801 | - } else if (oLpPreBc.isUp() == this._oParam.isUpOneWayStop()) { | |
| 802 | - // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 803 | - // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 804 | - return true; | |
| 805 | - } else { | |
| 806 | - return false; | |
| 807 | - } | |
| 808 | - } | |
| 809 | - } | |
| 810 | - } | |
| 811 | - | |
| 812 | - } else { // 其他分班 | |
| 813 | - // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一 | |
| 814 | - var oSt = this._qIsUp ? this._oParam.getUpFirstDTimeObj() : this._oParam.getDownFirstDTimeObj(); | |
| 815 | - var iBxIndex = 4; | |
| 816 | - if (oSt.isBefore(this._oParam.toTimeObj("05:59"))) { | |
| 817 | - iBxIndex = 5; | |
| 818 | - } | |
| 819 | - // 大致计算做其他班型所需的班次数 | |
| 820 | - var iQBcount = this._aBxDesc[iBxIndex].fQCount; | |
| 821 | - iBxBcount = Math.round(iQBcount) * 2; | |
| 822 | - | |
| 823 | - // 计算可能的其他分班当前班次时间,供下一步判定 | |
| 824 | - var oNext_other_bc_fctime_m = undefined; // 上午车次链参考班次时间 | |
| 825 | - var oNext_other_bc_fctime_e = undefined; // 下午车次链参考班次时间 | |
| 826 | - if (oPreBc.getFcTimeObj().isBefore(this._oParam.toTimeObj("14:00"))) { // 上午车次链 | |
| 827 | - oNext_other_bc_fctime_m = this._oParam.addMinute( | |
| 828 | - oPreBc.getFcTimeObj(), | |
| 829 | - Math.ceil((this._oParam.getMPeakMinFcjx() + this._oParam.getMPeakMaxFcjx()) / 2) | |
| 830 | - ); | |
| 831 | - } else { // 下午车次链 | |
| 832 | - oNext_other_bc_fctime_e = this._oParam.addMinute( | |
| 833 | - oPreBc.getFcTimeObj(), | |
| 834 | - Math.ceil((this._oParam.getEPeakMinFcjx() + this._oParam.getEPeakMaxFcjx()) / 2) | |
| 835 | - ); | |
| 836 | - } | |
| 837 | - | |
| 838 | - // TODO:暂时使用5休2的判定方法,测试 | |
| 839 | - | |
| 840 | - // 先处理上午车次链 | |
| 841 | - if (oNext_other_bc_fctime_m) { | |
| 842 | - if (oNext_other_bc_fctime_m.isBefore(this._oParam.getMPeakStartTimeObj())) { | |
| 843 | - // 5休2班型第一个班次,如果在早高峰开始前低谷,不添加 | |
| 844 | - return false; | |
| 845 | - } else if (!oNext_other_bc_fctime_m.isAfter(this._oParam.getMPeakEndTimeObj())) { | |
| 846 | - // 早高峰期间,添加 | |
| 847 | - return true; | |
| 848 | - } else { | |
| 849 | - // 早高峰之后低谷到12:00之间 | |
| 850 | - | |
| 851 | - // 当前路牌的前一个班次 | |
| 852 | - oLpPreBc = oCurrentLp.getBc(iBcIndex == 0 ? iGroupIndex - 1 : iGroupIndex, iBcIndex == 0 ? 1 : 0); | |
| 853 | - if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) { | |
| 854 | - // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 855 | - return false; | |
| 856 | - } else { | |
| 857 | - if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) { | |
| 858 | - // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次 | |
| 859 | - return true; | |
| 860 | - } else if (oLpPreBc.isUp() == this._oParam.isUpOneWayStop()) { | |
| 861 | - // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 862 | - // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 863 | - return true; | |
| 864 | - } else { | |
| 865 | - return false; | |
| 866 | - } | |
| 867 | - } | |
| 868 | - } | |
| 869 | - } | |
| 870 | - | |
| 871 | - // 再处理下午车次链 | |
| 872 | - if (oNext_other_bc_fctime_e) { | |
| 873 | - if (oNext_other_bc_fctime_e.isBefore(this._oParam.getEPeakStartTimeObj())) { | |
| 874 | - // 5休2班型第一个班次,如果在晚高峰开始前低谷,不添加 | |
| 875 | - return false; | |
| 876 | - } else if (!oNext_other_bc_fctime_e.isAfter(this._oParam.getEPeakEndTimeObj())) { | |
| 877 | - // 晚高峰期间,添加 | |
| 878 | - return true; | |
| 879 | - } else { | |
| 880 | - // 晚高峰之后低谷 | |
| 881 | - | |
| 882 | - // 当前路牌的前一个班次 | |
| 883 | - oLpPreBc = oCurrentLp.getBc(iBcIndex == 0 ? iGroupIndex - 1 : iGroupIndex, iBcIndex == 0 ? 1 : 0); | |
| 884 | - | |
| 885 | - if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) { | |
| 886 | - // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 887 | - // TODO:晚高峰后第一个班次也要添加,这里以后细化 | |
| 888 | - return true; | |
| 889 | - } else { | |
| 890 | - if (oCurrentLp.getBcArray().length < iBxBcount) { | |
| 891 | - // 如果总班次数比iBxBcount少,加班次 | |
| 892 | - return true; | |
| 893 | - } else if (oLpPreBc.isUp() == this._oParam.isUpOneWayStop()) { | |
| 894 | - // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 895 | - // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 896 | - return true; | |
| 897 | - } else { | |
| 898 | - return false; | |
| 899 | - } | |
| 900 | - } | |
| 901 | - } | |
| 902 | - } | |
| 903 | - | |
| 904 | - } | |
| 905 | - } else { // 连班班型,高峰低谷都有班次 | |
| 906 | - return true; | |
| 907 | - } | |
| 730 | + }; | |
| 908 | 731 | |
| 732 | + /** | |
| 733 | + * 计算生成发车间隔值。 | |
| 734 | + * @param groupIndex 圈索引 | |
| 735 | + * @param bcIndex 班次索引 | |
| 736 | + * @param iMinCycleTime 最小周转时间 | |
| 737 | + * @param iMaxCycleTime 最大周转时间 | |
| 738 | + * @private | |
| 739 | + */ | |
| 740 | + InternalScheduleObj.prototype._$fnGetBcInterval = function( | |
| 741 | + groupIndex, bcIndex, iMinCycleTime, iMaxCycleTime | |
| 742 | + ) { | |
| 743 | + // 使用策略函数方式 | |
| 744 | + return StrategyUtils.sFn("CALCU_INTERVAL")( | |
| 745 | + this, this._oParam, | |
| 746 | + groupIndex, bcIndex, | |
| 747 | + iMinCycleTime, iMaxCycleTime | |
| 748 | + ); | |
| 909 | 749 | }; |
| 910 | 750 | |
| 911 | 751 | /** |
| ... | ... | @@ -933,7 +773,12 @@ var InternalScheduleObj_v2_2 = (function() { |
| 933 | 773 | var _modifyBc; // 上标线下一个圈的班次 |
| 934 | 774 | |
| 935 | 775 | for (i = this._iMPeakMasterBcGroupIndex; i < this._qCount; i++) { |
| 936 | - aBcInterval = this._$fnGetBcInterval(i, this._iMPeakMasterBcIndex, 3); | |
| 776 | + aBcInterval = this._$fnGetBcInterval( | |
| 777 | + i, this._iMPeakMasterBcIndex, | |
| 778 | + this._$calcuCycleTime(oPreBc.getFcTimeObj())[0], // 最小周转时间 | |
| 779 | + this._$calcuCycleTime(oPreBc.getFcTimeObj())[1] // 最大周转时间 | |
| 780 | + ); | |
| 781 | + | |
| 937 | 782 | if (aBcInterval.length == 0) { |
| 938 | 783 | // 等于0说明上标线没班次了 |
| 939 | 784 | break; |
| ... | ... | @@ -1040,232 +885,6 @@ var InternalScheduleObj_v2_2 = (function() { |
| 1040 | 885 | } |
| 1041 | 886 | }; |
| 1042 | 887 | |
| 1043 | - /** | |
| 1044 | - * 核心方法,获取发车间隔(从上标线指定班次开始网下拉一圈间隔)。 | |
| 1045 | - * @param groupIndex 圈索引 | |
| 1046 | - * @param bcIndex 班次索引 | |
| 1047 | - * @param normalFre 连续相同发车间隔班次数 | |
| 1048 | - * @private | |
| 1049 | - */ | |
| 1050 | - InternalScheduleObj.prototype._$fnGetBcInterval = function( | |
| 1051 | - groupIndex, bcIndex, | |
| 1052 | - normalFre) { | |
| 1053 | - | |
| 1054 | - if (normalFre < 1 || normalFre > this._internalLpArray.length) { | |
| 1055 | - alert("连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre); | |
| 1056 | - throw "连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre; | |
| 1057 | - } | |
| 1058 | - | |
| 1059 | - // 这个方法很重要用于生成每圈每个方向上的班次发车间隔 | |
| 1060 | - // 1、高峰班次全部高峰最大发车间隔 | |
| 1061 | - // 2、低谷第一个班次使用低谷最小发车间隔,连续相等的间隔班次数=normalFre,然后加1分钟,最大值是高峰最大发车间隔 | |
| 1062 | - // 3、TODO:高峰班次的间隔应该从最大缓慢变成最小然后再缓慢变成最大 | |
| 1063 | - // 4、TODO:分班班型可能在指定位置没有班次,需要合理判定(5休2,其他班型) | |
| 1064 | - // 5、TODO:主站方向在低谷拉间隔的时候,低谷拉到多少才是合理的(当行驶时间很大时,低谷最大发车间隔不一定合理), | |
| 1065 | - // TODO: 此时需要和连班的间隔分班路牌数(抽车数),以及吃饭时间的大小共同考虑, | |
| 1066 | - // TODO: 目前这样考虑,因为要抽车,如果没有足够的停站时间做调整,肯定会大间隔,当要抽车时, | |
| 1067 | - // TODO:获取当前连班路牌和上一个连班路牌在前半圈的间隔值,当前连班路牌班次的停站时间至少大于低谷最大发车间隔减去这个值 | |
| 1068 | - | |
| 1069 | - var i; | |
| 1070 | - var j; | |
| 1071 | - var oPreBc; // 上一个班次(从上标线班次开始) | |
| 1072 | - var oCurrentBcFcTime; // 当前班次的发车时间 | |
| 1073 | - var oCurrentBcInterval; // 当前班次的发车间隔 | |
| 1074 | - | |
| 1075 | - // 班次发车间隔,从oPreBc向前推normalFre个班次 | |
| 1076 | - var aBcInterval = []; | |
| 1077 | - var iBcInterval; | |
| 1078 | - var bIsIntervalEquale; | |
| 1079 | - var iPreBcIntervalIndex; | |
| 1080 | - var aBcInterval_rtn = []; // 最终返回的对象数组 | |
| 1081 | - | |
| 1082 | - oPreBc = this._internalLpArray[0].getBc(groupIndex, bcIndex); | |
| 1083 | - if (oPreBc) { | |
| 1084 | - // 先尝试获取上标线班次的interval | |
| 1085 | - iBcInterval = this._internalLpArray[0].fnGetVerticalIntervalTime( | |
| 1086 | - groupIndex, bcIndex); | |
| 1087 | - if (iBcInterval) { // 存在发车间隔 | |
| 1088 | - aBcInterval.push(iBcInterval); | |
| 1089 | - | |
| 1090 | - // 尝试获取前一圈同方向的(normalFre -1)个班次的发车间隔 | |
| 1091 | - j = 1; | |
| 1092 | - if (groupIndex - 1 >= 0) { | |
| 1093 | - for (i = this._internalLpArray.length - 1; i >= 0; i--) { | |
| 1094 | - if (j < normalFre) { | |
| 1095 | - iBcInterval = this._internalLpArray[i].fnGetVerticalIntervalTime( | |
| 1096 | - groupIndex - 1, bcIndex); | |
| 1097 | - if (iBcInterval) { // 存在发车间隔 | |
| 1098 | - aBcInterval.push(iBcInterval); | |
| 1099 | - j++; | |
| 1100 | - } | |
| 1101 | - } else { | |
| 1102 | - break; | |
| 1103 | - } | |
| 1104 | - } | |
| 1105 | - } | |
| 1106 | - } | |
| 1107 | - | |
| 1108 | - aBcInterval.reverse(); | |
| 1109 | - // 上一个班次间隔index | |
| 1110 | - iPreBcIntervalIndex = aBcInterval.length - 1; | |
| 1111 | - | |
| 1112 | - var _iLpIndex; | |
| 1113 | - for (i = 1; i <= this._internalLpArray.length; i++) { | |
| 1114 | - var oBcInterval_rtn = | |
| 1115 | - {iLpIndex: null, hasBc: false, iFcInterval: null, iGroupIndex: null, iBcIndex: null}; | |
| 1116 | - // 注意这里是 this._internalLpArray.length,最后一个班次是下标线下一圈的同方向班次 | |
| 1117 | - _iLpIndex = i % this._internalLpArray.length; | |
| 1118 | - | |
| 1119 | - if (_iLpIndex == 0) { // 下一圈的上标线同方向班次 | |
| 1120 | - oBcInterval_rtn.iLpIndex = 0; | |
| 1121 | - oBcInterval_rtn.iGroupIndex = groupIndex + 1; | |
| 1122 | - oBcInterval_rtn.iBcIndex = bcIndex; | |
| 1123 | - } else { | |
| 1124 | - oBcInterval_rtn.iLpIndex = _iLpIndex; | |
| 1125 | - oBcInterval_rtn.iGroupIndex = groupIndex; | |
| 1126 | - oBcInterval_rtn.iBcIndex = bcIndex; | |
| 1127 | - } | |
| 1128 | - | |
| 1129 | - // 班型判定 | |
| 1130 | - if (_iLpIndex != 0) { // 回到上标线不用判定了 | |
| 1131 | - if (!this._$fnDecideBxBc( | |
| 1132 | - oPreBc, _iLpIndex - 1, | |
| 1133 | - _iLpIndex, | |
| 1134 | - groupIndex, bcIndex | |
| 1135 | - )) { | |
| 1136 | - aBcInterval_rtn.push(oBcInterval_rtn); | |
| 1137 | - continue; | |
| 1138 | - } | |
| 1139 | - } | |
| 1140 | - | |
| 1141 | - if (this._oParam.isMPeakBc(oPreBc.getFcTimeObj())) { // 早高峰 | |
| 1142 | - // 如果上一个班次是早高峰班次,下一个班次使用早高峰平均发车间隔(ceil) | |
| 1143 | - // 如果下一个班次(加上早高峰最大发车间隔后)是低谷班次,使用低谷最小发车间隔 | |
| 1144 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1145 | - oPreBc.getFcTimeObj(), | |
| 1146 | - Math.ceil((this._oParam.getMPeakMaxFcjx() + this._oParam.getMPeakMinFcjx()) / 2)); | |
| 1147 | - if (this._oParam.isTroughBc(oCurrentBcFcTime)) { | |
| 1148 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1149 | - oPreBc.getFcTimeObj(), | |
| 1150 | - this._oParam.getTroughMinFcjx()); | |
| 1151 | - } | |
| 1152 | - | |
| 1153 | - } else if (this._oParam.isEPeakBc(oPreBc.getFcTimeObj())) { // 晚高峰 | |
| 1154 | - // 如果上一个班次是晚高峰班次,下一个班次使用晚高峰平均发车间隔(ceil) | |
| 1155 | - // 如果下一个班次(加上晚高峰最大发车间隔后)是低谷班次,使用低谷最小发车间隔 | |
| 1156 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1157 | - oPreBc.getFcTimeObj(), | |
| 1158 | - Math.ceil((this._oParam.getEPeakMaxFcjx() + this._oParam.getEPeakMinFcjx()) / 2)); | |
| 1159 | - if (this._oParam.isTroughBc(oCurrentBcFcTime)) { | |
| 1160 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1161 | - oPreBc.getFcTimeObj(), | |
| 1162 | - this._oParam.getTroughMinFcjx()); | |
| 1163 | - } | |
| 1164 | - } else { | |
| 1165 | - | |
| 1166 | - if (aBcInterval.length < normalFre) { // 没有足够的连续班次间隔 | |
| 1167 | - // 使用低谷最小发车间隔,如果跨入高峰,使用高峰平均发车间隔(ceil) | |
| 1168 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1169 | - oPreBc.getFcTimeObj(), | |
| 1170 | - this._oParam.getTroughMinFcjx() | |
| 1171 | - ); | |
| 1172 | - if (this._oParam.isMPeakBc(oCurrentBcFcTime)) { | |
| 1173 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1174 | - oPreBc.getFcTimeObj(), | |
| 1175 | - Math.ceil((this._oParam.getMPeakMaxFcjx() + this._oParam.getMPeakMinFcjx()) / 2) | |
| 1176 | - ); | |
| 1177 | - } | |
| 1178 | - if (this._oParam.isEPeakBc(oCurrentBcFcTime)) { | |
| 1179 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1180 | - oPreBc.getFcTimeObj(), | |
| 1181 | - Math.ceil((this._oParam.getEPeakMaxFcjx() + this._oParam.getEPeakMinFcjx()) / 2) | |
| 1182 | - ); | |
| 1183 | - } | |
| 1184 | - } else { // 有足够的连续班次间隔 | |
| 1185 | - // 看连续班次间隔是否一致,一致+1分钟(不能超过低谷最大发车间隔),不一致就相等间隔 | |
| 1186 | - // 加了间隔后,如果是高峰班次,则使用高峰平均发车间隔(ceil) | |
| 1187 | - // TODO:什么时候开始减低谷发车间隔到最小发车间隔,应该是在吃了饭之后 | |
| 1188 | - | |
| 1189 | - bIsIntervalEquale = true; | |
| 1190 | - for (j = iPreBcIntervalIndex; j > iPreBcIntervalIndex - normalFre + 1; j--) { | |
| 1191 | - if (aBcInterval[j] != aBcInterval[j - 1]) { | |
| 1192 | - bIsIntervalEquale = false; | |
| 1193 | - break; | |
| 1194 | - } | |
| 1195 | - } | |
| 1196 | - if (bIsIntervalEquale) { | |
| 1197 | - if (aBcInterval[iPreBcIntervalIndex] + 1 > this._oParam.getTroughMaxFcjx()) { | |
| 1198 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1199 | - oPreBc.getFcTimeObj(), | |
| 1200 | - this._oParam.getTroughMaxFcjx() | |
| 1201 | - ); | |
| 1202 | - } else { | |
| 1203 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1204 | - oPreBc.getFcTimeObj(), | |
| 1205 | - aBcInterval[iPreBcIntervalIndex] + 1 | |
| 1206 | - ); | |
| 1207 | - } | |
| 1208 | - } else { | |
| 1209 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1210 | - oPreBc.getFcTimeObj(), | |
| 1211 | - aBcInterval[iPreBcIntervalIndex] | |
| 1212 | - ); | |
| 1213 | - } | |
| 1214 | - | |
| 1215 | - if (this._oParam.isMPeakBc(oCurrentBcFcTime)) { | |
| 1216 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1217 | - oPreBc.getFcTimeObj(), | |
| 1218 | - Math.ceil((this._oParam.getMPeakMaxFcjx() + this._oParam.getMPeakMinFcjx()) / 2) | |
| 1219 | - ); | |
| 1220 | - } | |
| 1221 | - if (this._oParam.isEPeakBc(oCurrentBcFcTime)) { | |
| 1222 | - oCurrentBcFcTime = this._oParam.addMinute( | |
| 1223 | - oPreBc.getFcTimeObj(), | |
| 1224 | - Math.ceil((this._oParam.getEPeakMaxFcjx() + this._oParam.getEPeakMinFcjx()) / 2) | |
| 1225 | - ); | |
| 1226 | - } | |
| 1227 | - | |
| 1228 | - } | |
| 1229 | - | |
| 1230 | - } | |
| 1231 | - | |
| 1232 | - // 判定超出末班车,就没有班次 | |
| 1233 | - if (oPreBc.isUp()) { | |
| 1234 | - if (oCurrentBcFcTime.isAfter( | |
| 1235 | - this._oParam.addMinute(this._oParam.getUpLastDtimeObj(), 30))) { | |
| 1236 | - aBcInterval_rtn.push(oBcInterval_rtn); | |
| 1237 | - continue; | |
| 1238 | - } | |
| 1239 | - } else { | |
| 1240 | - if (oCurrentBcFcTime.isAfter( | |
| 1241 | - this._oParam.addMinute(this._oParam.getDownLastDTimeObj(), 30))) { | |
| 1242 | - aBcInterval_rtn.push(oBcInterval_rtn); | |
| 1243 | - continue; | |
| 1244 | - } | |
| 1245 | - } | |
| 1246 | - | |
| 1247 | - oCurrentBcInterval = oCurrentBcFcTime.diff(oPreBc.getFcTimeObj(), "m"); | |
| 1248 | - aBcInterval.push(oCurrentBcInterval); | |
| 1249 | - oPreBc = _utils.createBcObj( | |
| 1250 | - this._internalLpArray[_iLpIndex], | |
| 1251 | - "normal", | |
| 1252 | - oPreBc.isUp(), | |
| 1253 | - 1, | |
| 1254 | - oCurrentBcFcTime, | |
| 1255 | - this._oParam | |
| 1256 | - ); | |
| 1257 | - iPreBcIntervalIndex++; | |
| 1258 | - oBcInterval_rtn.hasBc = true; | |
| 1259 | - oBcInterval_rtn.iFcInterval = oCurrentBcInterval; | |
| 1260 | - aBcInterval_rtn.push(oBcInterval_rtn); | |
| 1261 | - } | |
| 1262 | - | |
| 1263 | - } | |
| 1264 | - | |
| 1265 | - return aBcInterval_rtn; | |
| 1266 | - | |
| 1267 | - }; | |
| 1268 | - | |
| 1269 | 888 | //------------- 其他业务方法 -------------// |
| 1270 | 889 | |
| 1271 | 890 | /** |
| ... | ... | @@ -1295,7 +914,7 @@ var InternalScheduleObj_v2_2 = (function() { |
| 1295 | 914 | oPreBc = oLp.getPreBc(oBc); |
| 1296 | 915 | |
| 1297 | 916 | if (!oEatFlag[oLp.getLpNo()]["isLaunch"]) { |
| 1298 | - if (oPreBc && oBc.getFcTimeObj().diff(oPreBc.getArrTimeObj(), 'm') > this._oParam.fnGetLunchTime()) { | |
| 917 | + if (oPreBc && oBc.getFcTimeObj().diff(oPreBc.getArrTimeObj(), 'm') >= this._oParam.fnGetLunchTime()) { | |
| 1299 | 918 | oBc.fnSetEatTime(this._oParam.fnGetLunchTime()); |
| 1300 | 919 | oEatFlag[oLp.getLpNo()]["isLaunch"] = true; |
| 1301 | 920 | } |
| ... | ... | @@ -1308,7 +927,7 @@ var InternalScheduleObj_v2_2 = (function() { |
| 1308 | 927 | oPreBc = oLp.getPreBc(oBc); |
| 1309 | 928 | |
| 1310 | 929 | if (!oEatFlag[oLp.getLpNo()]["isDinner"]) { |
| 1311 | - if (oPreBc && oBc.getFcTimeObj().diff(oPreBc.getArrTimeObj(), 'm') > this._oParam.fnGetDinnerTime()) { | |
| 930 | + if (oPreBc && oBc.getFcTimeObj().diff(oPreBc.getArrTimeObj(), 'm') >= this._oParam.fnGetDinnerTime()) { | |
| 1312 | 931 | oBc.fnSetEatTime(this._oParam.fnGetDinnerTime()); |
| 1313 | 932 | oEatFlag[oLp.getLpNo()]["isDinner"] = true; |
| 1314 | 933 | } |
| ... | ... | @@ -1626,6 +1245,30 @@ var InternalScheduleObj_v2_2 = (function() { |
| 1626 | 1245 | }; |
| 1627 | 1246 | |
| 1628 | 1247 | /** |
| 1248 | + * 获取班型描述。 | |
| 1249 | + * @return {*[]} | |
| 1250 | + */ | |
| 1251 | + InternalScheduleObj.prototype.fnGetBxDesc = function() { | |
| 1252 | + return this._aBxDesc; | |
| 1253 | + }; | |
| 1254 | + | |
| 1255 | + /** | |
| 1256 | + * 获取圈的第一个班次是上行还是下行。 | |
| 1257 | + * @return {boolean|*} | |
| 1258 | + */ | |
| 1259 | + InternalScheduleObj.prototype.fnGetGroupIsUp = function() { | |
| 1260 | + return this._qIsUp; | |
| 1261 | + }; | |
| 1262 | + | |
| 1263 | + /** | |
| 1264 | + * 返回内部工具对象。 | |
| 1265 | + * @return {{createBcObj, modifySBXMasterBc}} | |
| 1266 | + */ | |
| 1267 | + InternalScheduleObj.prototype.fnGetUitls = function() { | |
| 1268 | + return _utils; | |
| 1269 | + }; | |
| 1270 | + | |
| 1271 | + /** | |
| 1629 | 1272 | * 内部数据转化成显示用的班次数组。 |
| 1630 | 1273 | */ |
| 1631 | 1274 | InternalScheduleObj.prototype.fnToGanttBcArray = function() { |
| ... | ... | @@ -1682,7 +1325,88 @@ var InternalScheduleObj_v2_2 = (function() { |
| 1682 | 1325 | return aGanttBc; |
| 1683 | 1326 | }; |
| 1684 | 1327 | |
| 1328 | + /** | |
| 1329 | + * 计算指定时间,指定方向开始的最大最小周转时间 | |
| 1330 | + * @param oStartFcTime 开始发车时间时间 | |
| 1331 | + * @param isUp 是否上行 | |
| 1332 | + * @returns array [最小值,最大值] | |
| 1333 | + * @private | |
| 1334 | + */ | |
| 1335 | + InternalScheduleObj.prototype._$calcuCycleTime = function(oStartFcTime, isUp) { | |
| 1336 | + var a_rtn = []; | |
| 1337 | + var iMinCycleTime; // 最小周转时间(最少停站时间) | |
| 1338 | + var iMaxCycleTime; // 最大周转时间(最大停站时间),TODO:这个最大值只是参考用 | |
| 1339 | + | |
| 1340 | + var iRunningTime_1; // 行驶时间1 | |
| 1341 | + var iStopTime_1; // 停站时间1 | |
| 1342 | + var iRunningTime_2; // 行驶时间2 | |
| 1343 | + var iStopTime_2; // 停站时间2 | |
| 1344 | + | |
| 1345 | + // 计算最小周转时间 | |
| 1346 | + iRunningTime_1 = this._oParam.calcuTravelTime( | |
| 1347 | + oStartFcTime, isUp); | |
| 1348 | + iStopTime_1 = this._oParam.calcuTripLayoverTimeRange( | |
| 1349 | + this._oParam.addMinute(oStartFcTime, iRunningTime_1), | |
| 1350 | + isUp, iRunningTime_1)[0]; | |
| 1351 | + iRunningTime_2 = this._oParam.calcuTravelTime( | |
| 1352 | + this._oParam.addMinute(oStartFcTime, iRunningTime_1 + iStopTime_1), | |
| 1353 | + !isUp); | |
| 1354 | + iStopTime_2 = this._oParam.calcuTripLayoverTimeRange( | |
| 1355 | + this._oParam.addMinute(oStartFcTime, iRunningTime_2), | |
| 1356 | + !isUp, iRunningTime_2)[0]; | |
| 1357 | + // if (this._oParam.isUpOneWayStop()) { // 如果上行主站 | |
| 1358 | + // if (isUp) { | |
| 1359 | + // iStopTime_2 += iStopTime_2; | |
| 1360 | + // } else { | |
| 1361 | + // iStopTime_1 += iStopTime_1; | |
| 1362 | + // } | |
| 1363 | + // } | |
| 1364 | + // if (this._oParam.isDownOneWayStop()) { // 如果下行主站 | |
| 1365 | + // if (isUp) { | |
| 1366 | + // iStopTime_1 += iStopTime_1; | |
| 1367 | + // } else { | |
| 1368 | + // iStopTime_2 += iStopTime_2; | |
| 1369 | + // } | |
| 1370 | + // } | |
| 1371 | + iMinCycleTime = iRunningTime_1 + iStopTime_1 + iRunningTime_2 + iStopTime_2; | |
| 1372 | + | |
| 1373 | + // 计算最大周转时间 | |
| 1374 | + iRunningTime_1 = this._oParam.calcuTravelTime( | |
| 1375 | + oStartFcTime, isUp); | |
| 1376 | + iStopTime_1 = this._oParam.calcuTripLayoverTimeRange( | |
| 1377 | + this._oParam.addMinute(oStartFcTime, iRunningTime_1), | |
| 1378 | + isUp, iRunningTime_1)[1]; | |
| 1379 | + iRunningTime_2 = this._oParam.calcuTravelTime( | |
| 1380 | + this._oParam.addMinute(oStartFcTime, iRunningTime_1 + iStopTime_1), | |
| 1381 | + !isUp); | |
| 1382 | + iStopTime_2 = this._oParam.calcuTripLayoverTimeRange( | |
| 1383 | + this._oParam.addMinute(oStartFcTime, iRunningTime_2), | |
| 1384 | + !isUp, iRunningTime_2)[1]; | |
| 1385 | + if (this._oParam.isUpOneWayStop()) { // 如果上行主站 | |
| 1386 | + if (isUp) { | |
| 1387 | + iStopTime_2 += iStopTime_2; | |
| 1388 | + } else { | |
| 1389 | + iStopTime_1 += iStopTime_1; | |
| 1390 | + } | |
| 1391 | + } | |
| 1392 | + if (this._oParam.isDownOneWayStop()) { // 如果下行主站 | |
| 1393 | + if (isUp) { | |
| 1394 | + iStopTime_1 += iStopTime_1; | |
| 1395 | + } else { | |
| 1396 | + iStopTime_2 += iStopTime_2; | |
| 1397 | + } | |
| 1398 | + } | |
| 1399 | + | |
| 1400 | + iMaxCycleTime = iRunningTime_1 + iStopTime_1 + iRunningTime_2 + iStopTime_2; | |
| 1401 | + | |
| 1402 | + a_rtn.push(iMinCycleTime); | |
| 1403 | + a_rtn.push(iMaxCycleTime); | |
| 1404 | + | |
| 1405 | + return a_rtn; | |
| 1406 | + }; | |
| 1407 | + | |
| 1685 | 1408 | //-------------------- static静态方法 ----------------------// |
| 1409 | + | |
| 1686 | 1410 | /** |
| 1687 | 1411 | * 计算车辆数。 |
| 1688 | 1412 | * @param oParam 参数对象 | ... | ... |
src/main/resources/static/pages/base/timesmodel/js/v2_2/main_v2_2.js
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/bc/DecideBcTripS1.js
0 → 100644
| 1 | +/** | |
| 2 | + * 判定路牌每圈是否出班次。 | |
| 3 | + */ | |
| 4 | +var DecideBcTripS1 = (function() { | |
| 5 | + | |
| 6 | + /** | |
| 7 | + * 判定班型班次,主方法。 | |
| 8 | + * @param oInternalSchedule | |
| 9 | + * @param oParam | |
| 10 | + * @param oPreBc | |
| 11 | + * @param iPreLpIndex | |
| 12 | + * @param iCurrentLpIndex | |
| 13 | + * @param iCurrentGroupIndex | |
| 14 | + * @param iCurrentBcIndex | |
| 15 | + */ | |
| 16 | + function main( | |
| 17 | + oInternalSchedule, oParam, | |
| 18 | + oPreBc, iPreLpIndex, | |
| 19 | + iCurrentLpIndex, iCurrentGroupIndex, iCurrentBcIndex) { | |
| 20 | + | |
| 21 | + | |
| 22 | + var oCurrentLp = oInternalSchedule.fnGetLpArray()[iCurrentLpIndex]; // 当前路牌 | |
| 23 | + var oLpPreBc; // 当前路牌前一个班次 | |
| 24 | + | |
| 25 | + var iBxBcount; // 分班班型的可能班次数 | |
| 26 | + | |
| 27 | + if (oCurrentLp.isBxFb()) { // 分班 | |
| 28 | + // 关联的因素 | |
| 29 | + // 1、当前班次方向 | |
| 30 | + // 2、上一个班次情况 | |
| 31 | + // 3、同路牌前一个班次情况 | |
| 32 | + // 4、分班路牌工时限制 | |
| 33 | + | |
| 34 | + | |
| 35 | + if (oCurrentLp.isBxFb5_2()) { // 5休2分班 | |
| 36 | + // 大致计算5休2班型班次数 | |
| 37 | + iBxBcount = oInternalSchedule.fnGetBxDesc()[6].fBcCount; | |
| 38 | + if (iBxBcount - Math.floor(iBxBcount) > 0.7) { | |
| 39 | + iBxBcount = Math.floor(iBxBcount) + 1; | |
| 40 | + } else { | |
| 41 | + iBxBcount = Math.floor(iBxBcount); | |
| 42 | + } | |
| 43 | + | |
| 44 | + // 计算可能的5休2班次时间,供下一步判定 | |
| 45 | + var oNext5_2_bc_fctime_m = undefined; // 上午车次链参考班次时间 | |
| 46 | + var oNext5_2_bc_fctime_e = undefined; // 下午车次链参考班次时间 | |
| 47 | + if (oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("12:00"))) { // 上午车次链 | |
| 48 | + oNext5_2_bc_fctime_m = oParam.addMinute( | |
| 49 | + oPreBc.getFcTimeObj(), | |
| 50 | + Math.ceil((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2) | |
| 51 | + ); | |
| 52 | + } else { // 下午车次链 | |
| 53 | + oNext5_2_bc_fctime_e = oParam.addMinute( | |
| 54 | + oPreBc.getFcTimeObj(), | |
| 55 | + Math.ceil((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2) | |
| 56 | + ); | |
| 57 | + } | |
| 58 | + | |
| 59 | + // 先处理上午车次链 | |
| 60 | + if (oNext5_2_bc_fctime_m) { | |
| 61 | + if (oNext5_2_bc_fctime_m.isBefore(oParam.getMPeakStartTimeObj())) { | |
| 62 | + // 5休2班型第一个班次,如果在早高峰开始前低谷,不添加 | |
| 63 | + return false; | |
| 64 | + } else if (!oNext5_2_bc_fctime_m.isAfter(oParam.getMPeakEndTimeObj())) { | |
| 65 | + // 早高峰期间,添加 | |
| 66 | + return true; | |
| 67 | + } else { | |
| 68 | + // 早高峰之后低谷到12:00之间 | |
| 69 | + | |
| 70 | + // 当前路牌的前一个班次 | |
| 71 | + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ? | |
| 72 | + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0); | |
| 73 | + if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) { | |
| 74 | + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 75 | + return false; | |
| 76 | + } else { | |
| 77 | + if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) { | |
| 78 | + // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次 | |
| 79 | + return true; | |
| 80 | + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) { | |
| 81 | + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 82 | + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 83 | + return true; | |
| 84 | + } else { | |
| 85 | + return false; | |
| 86 | + } | |
| 87 | + } | |
| 88 | + } | |
| 89 | + } | |
| 90 | + | |
| 91 | + // 再处理下午车次链 | |
| 92 | + if (oNext5_2_bc_fctime_e) { | |
| 93 | + if (oNext5_2_bc_fctime_e.isBefore(oParam.getEPeakStartTimeObj())) { | |
| 94 | + if (oParam.isEPeakBc(oPreBc.getArrTimeObj())) { | |
| 95 | + // 如果上一个班次的到达时间在高峰内,也要加 | |
| 96 | + return true; | |
| 97 | + } | |
| 98 | + | |
| 99 | + // 5休2班型第一个班次,如果在晚高峰开始前低谷,不添加 | |
| 100 | + return false; | |
| 101 | + } else if (!oNext5_2_bc_fctime_e.isAfter(oParam.getEPeakEndTimeObj())) { | |
| 102 | + // 晚高峰期间,添加 | |
| 103 | + return true; | |
| 104 | + } else { | |
| 105 | + // 晚高峰之后低谷 | |
| 106 | + | |
| 107 | + // 当前路牌的前一个班次 | |
| 108 | + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ? | |
| 109 | + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0); | |
| 110 | + if (oCurrentLp.getBcArray().length > 0 && (!oLpPreBc)) { | |
| 111 | + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 112 | + return false; | |
| 113 | + } else { | |
| 114 | + if (oCurrentLp.getBcArray().length < iBxBcount) { | |
| 115 | + // 如果总班次数比iBxBcount少,加班次 | |
| 116 | + return true; | |
| 117 | + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) { | |
| 118 | + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 119 | + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 120 | + return true; | |
| 121 | + } else { | |
| 122 | + return false; | |
| 123 | + } | |
| 124 | + } | |
| 125 | + } | |
| 126 | + } | |
| 127 | + | |
| 128 | + } else { // 其他分班 | |
| 129 | + // TODO:根据上标线的首班时间确定班型,小于05:59的做一休一,否则做二休一 | |
| 130 | + var oSt = oInternalSchedule.fnGetGroupIsUp() ? | |
| 131 | + oParam.getUpFirstDTimeObj() : oParam.getDownFirstDTimeObj(); | |
| 132 | + var iBxIndex = 4; | |
| 133 | + if (oSt.isBefore(oParam.toTimeObj("05:59"))) { | |
| 134 | + iBxIndex = 5; | |
| 135 | + } | |
| 136 | + // 大致计算做其他班型所需的班次数 | |
| 137 | + var iQBcount = oInternalSchedule.fnGetBxDesc()[iBxIndex].fQCount; | |
| 138 | + iBxBcount = Math.ceil(iQBcount) * 2; | |
| 139 | + | |
| 140 | + // 计算可能的其他分班当前班次时间,供下一步判定 | |
| 141 | + var oNext_other_bc_fctime_m = undefined; // 上午车次链参考班次时间 | |
| 142 | + var oNext_other_bc_fctime_e = undefined; // 下午车次链参考班次时间 | |
| 143 | + if (oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("15:00"))) { // 上午车次链 | |
| 144 | + oNext_other_bc_fctime_m = oParam.addMinute( | |
| 145 | + oPreBc.getFcTimeObj(), | |
| 146 | + Math.ceil((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2) | |
| 147 | + ); | |
| 148 | + } else { // 下午车次链 | |
| 149 | + oNext_other_bc_fctime_e = oParam.addMinute( | |
| 150 | + oPreBc.getFcTimeObj(), | |
| 151 | + Math.ceil((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2) | |
| 152 | + ); | |
| 153 | + } | |
| 154 | + | |
| 155 | + // 先处理上午车次链 | |
| 156 | + if (oNext_other_bc_fctime_m) { | |
| 157 | + // TODO:其他分班随连班上午开始就出车,具体出车时间可能还要和低谷周转时间一起考虑 | |
| 158 | + // 当前路牌的前一个班次 | |
| 159 | + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ? | |
| 160 | + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0); | |
| 161 | + if (oCurrentLp.getBcArray().length == 0) { | |
| 162 | + return true; | |
| 163 | + } else if (!oLpPreBc) { | |
| 164 | + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 165 | + return false; | |
| 166 | + } else { | |
| 167 | + if (oCurrentLp.getBcArray().length < Math.ceil(iBxBcount / 2)) { | |
| 168 | + // 如果总班次数比iBxBcount的一半的班次(ceil)少,加班次 | |
| 169 | + return true; | |
| 170 | + } else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) { | |
| 171 | + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 172 | + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 173 | + return true; | |
| 174 | + } else { | |
| 175 | + return false; | |
| 176 | + } | |
| 177 | + } | |
| 178 | + | |
| 179 | + } | |
| 180 | + | |
| 181 | + // 再处理下午车次链 | |
| 182 | + if (oNext_other_bc_fctime_e) { | |
| 183 | + // TODO:下午14:00后开始添加,加入时间可能还要和低谷周转时间一起考虑 | |
| 184 | + // 当前路牌的前一个班次 | |
| 185 | + oLpPreBc = oCurrentLp.getBc(iCurrentBcIndex == 0 ? | |
| 186 | + iCurrentGroupIndex - 1 : iCurrentGroupIndex, iCurrentBcIndex == 0 ? 1 : 0); | |
| 187 | + if (oCurrentLp.getBcArrayFromTime(oParam.toTimeObj("15:00")).length == 0) { | |
| 188 | + return true; | |
| 189 | + } else if (!oLpPreBc) { | |
| 190 | + // 不存在当前路牌的前一个班次,说明车次链已经结束了,不添加 | |
| 191 | + return false; | |
| 192 | + } else { | |
| 193 | + if (oCurrentLp.getBcArray().length < iBxBcount) { | |
| 194 | + // 如果总班次数比iBxBcount少,加班次 | |
| 195 | + return true; | |
| 196 | + } else if (oParam.isEPeakBc(oNext_other_bc_fctime_e)) { | |
| 197 | + return true; | |
| 198 | + } | |
| 199 | + else if (oLpPreBc.isUp() == oParam.isUpOneWayStop()) { | |
| 200 | + // 超过一半的班次,判定当前路牌前一个班次是否主站班次,说明当前班次是副站 | |
| 201 | + // 作为分班单向进出场的车次链最后一个班次必须副站(因为要抽车),必须添加班次 | |
| 202 | + return true; | |
| 203 | + } else { | |
| 204 | + return false; | |
| 205 | + } | |
| 206 | + } | |
| 207 | + | |
| 208 | + } | |
| 209 | + | |
| 210 | + } | |
| 211 | + } else { // 连班班型,高峰低谷都有班次 | |
| 212 | + return true; | |
| 213 | + } | |
| 214 | + | |
| 215 | + | |
| 216 | + } | |
| 217 | + | |
| 218 | + return main; | |
| 219 | +} ()); | |
| 0 | 220 | \ No newline at end of file | ... | ... |
src/main/resources/static/pages/base/timesmodel/js/v2_2/strategy/interval/CalcuIntervalS1.js
0 → 100644
| 1 | +/** | |
| 2 | + * 计算发车间隔,每一圈的间隔,从上标线的班次开始。 | |
| 3 | + */ | |
| 4 | +var CalcuIntervalS1 = (function() { | |
| 5 | + | |
| 6 | + | |
| 7 | + /** | |
| 8 | + * 根据上一个班次的发车时间计算下一个班次的发车间隔。 | |
| 9 | + * @param oPreBcFcTime 上一个班次发车时间 | |
| 10 | + * @param oParam 参数对象 | |
| 11 | + * @private | |
| 12 | + */ | |
| 13 | + function _peakInterval(oPreBcFcTime, oParam, normalStep) { | |
| 14 | + var iBcInterval; | |
| 15 | + if (oParam.isMPeakBc(oPreBcFcTime)) { | |
| 16 | + iBcInterval = oParam.getMPeakMinFcjx() + normalStep; | |
| 17 | + return iBcInterval > oParam.getMPeakMaxFcjx() ? oParam.getMPeakMaxFcjx() : iBcInterval; | |
| 18 | + | |
| 19 | + } else if (oParam.isEPeakBc(oPreBcFcTime)) { | |
| 20 | + iBcInterval = oParam.getEPeakMinFcjx() + normalStep; | |
| 21 | + return iBcInterval > oParam.getEPeakMaxFcjx() ? oParam.getEPeakMaxFcjx() : iBcInterval; | |
| 22 | + } else { | |
| 23 | + throw "必须高峰班次"; | |
| 24 | + } | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + // 一般高峰时间段2个小时,使用如下间隔方法,以后还会修正 | |
| 29 | + // 1、第一个20分钟使用高峰最大发车间隔 | |
| 30 | + // 2、第二个20分钟使用高峰平均发车间隔(floor) | |
| 31 | + // 3、第三个20分钟使用高峰最小发车间隔 | |
| 32 | + // 4、第四个20分钟使用高峰最小发车间隔 | |
| 33 | + // 5、第五个20分钟使用高峰平均发车间隔(floor) | |
| 34 | + // 6、第六个20分钟使用高峰最大发车间隔 | |
| 35 | + | |
| 36 | + // if (oParam.isMPeakBc(oPreBcFcTime)) { | |
| 37 | + // return oParam.getMPeakMaxFcjx(); | |
| 38 | + // // if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 1 * 20))) { | |
| 39 | + // // return oParam.getMPeakMaxFcjx(); | |
| 40 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 2 * 20))) { | |
| 41 | + // // return Math.floor((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2); | |
| 42 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 3 * 20))) { | |
| 43 | + // // return oParam.getMPeakMinFcjx(); | |
| 44 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 4 * 20))) { | |
| 45 | + // // return oParam.getMPeakMinFcjx(); | |
| 46 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 5 * 20))) { | |
| 47 | + // // return Math.floor((oParam.getMPeakMinFcjx() + oParam.getMPeakMaxFcjx()) / 2); | |
| 48 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getMPeakStartTimeObj(), 6 * 20))) { | |
| 49 | + // // return oParam.getMPeakMaxFcjx(); | |
| 50 | + // // } else { | |
| 51 | + // // return oParam.getMPeakMaxFcjx(); | |
| 52 | + // // } | |
| 53 | + // } else if (oParam.isEPeakBc(oPreBcFcTime)) { | |
| 54 | + // return oParam.getEPeakMaxFcjx(); | |
| 55 | + // // if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 1 * 20))) { | |
| 56 | + // // return oParam.getEPeakMaxFcjx(); | |
| 57 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 2 * 20))) { | |
| 58 | + // // return Math.floor((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2); | |
| 59 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 3 * 20))) { | |
| 60 | + // // return oParam.getEPeakMinFcjx(); | |
| 61 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 4 * 20))) { | |
| 62 | + // // return oParam.getEPeakMinFcjx(); | |
| 63 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 5 * 20))) { | |
| 64 | + // // return Math.floor((oParam.getEPeakMinFcjx() + oParam.getEPeakMaxFcjx()) / 2); | |
| 65 | + // // } else if (oPreBcFcTime.isBefore(oParam.addMinute(oParam.getEPeakStartTimeObj(), 6 * 20))) { | |
| 66 | + // // return oParam.getEPeakMaxFcjx(); | |
| 67 | + // // } else { | |
| 68 | + // // return oParam.getEPeakMaxFcjx(); | |
| 69 | + // // } | |
| 70 | + // } else { | |
| 71 | + // throw "必须高峰班次"; | |
| 72 | + // } | |
| 73 | + } | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * 计算班次发车间隔。 | |
| 80 | + * @param oInternalSchedule 行车计划对象 | |
| 81 | + * @param oParam 参数对象 | |
| 82 | + * @param groupIndex 圈索引 | |
| 83 | + * @param bcIndex 班次索引 | |
| 84 | + * @param normalFre 相同发车间隔班次数,频率 | |
| 85 | + * @param normalStep 每次间隔变化的添加的分钟,步长 | |
| 86 | + * @return {Array} | |
| 87 | + * @private | |
| 88 | + */ | |
| 89 | + function _internalBcInterval( | |
| 90 | + oInternalSchedule, oParam, | |
| 91 | + groupIndex, bcIndex, normalFre, normalStep) { | |
| 92 | + | |
| 93 | + // 路牌列表 | |
| 94 | + var aLp = oInternalSchedule.fnGetLpArray(); | |
| 95 | + | |
| 96 | + if (normalFre < 1 || normalFre > aLp.length) { | |
| 97 | + alert("连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre); | |
| 98 | + throw "连续相同发车间隔班次数区间[1,路牌数],当前值=" + normalFre; | |
| 99 | + } | |
| 100 | + | |
| 101 | + // 这个方法很重要用于生成每圈每个方向上的班次发车间隔 | |
| 102 | + // 1、高峰班次全部高峰最大发车间隔 | |
| 103 | + // 2、低谷第一个班次使用低谷最小发车间隔,连续相等的间隔班次数=normalFre,然后加1分钟,最大值是高峰最大发车间隔 | |
| 104 | + // 5、TODO:主站方向在低谷拉间隔的时候,低谷拉到多少才是合理的(当行驶时间很大时,低谷最大发车间隔不一定合理), | |
| 105 | + // TODO: 此时需要和连班的间隔分班路牌数(抽车数),以及吃饭时间的大小共同考虑, | |
| 106 | + // TODO: 目前这样考虑,因为要抽车,如果没有足够的停站时间做调整,肯定会大间隔,当要抽车时, | |
| 107 | + // TODO:获取当前连班路牌和上一个连班路牌在前半圈的间隔值,当前连班路牌班次的停站时间至少大于低谷最大发车间隔减去这个值 | |
| 108 | + | |
| 109 | + var i; | |
| 110 | + var j; | |
| 111 | + var oPreBc; // 上一个班次(从上标线班次开始) | |
| 112 | + var oCurrentBcFcTime; // 当前班次的发车时间 | |
| 113 | + var oCurrentBcInterval; // 当前班次的发车间隔 | |
| 114 | + | |
| 115 | + // 班次发车间隔,从oPreBc向前推normalFre个班次 | |
| 116 | + var aBcInterval = []; | |
| 117 | + var iBcInterval; | |
| 118 | + var bIsIntervalEquale; | |
| 119 | + var iPreBcIntervalIndex; | |
| 120 | + var aBcInterval_rtn = []; // 最终返回的对象数组 | |
| 121 | + | |
| 122 | + oPreBc = aLp[0].getBc(groupIndex, bcIndex); | |
| 123 | + if (oPreBc) { | |
| 124 | + // 先尝试获取上标线班次的interval | |
| 125 | + iBcInterval = aLp[0].fnGetVerticalIntervalTime( | |
| 126 | + groupIndex, bcIndex); | |
| 127 | + if (iBcInterval) { // 存在发车间隔 | |
| 128 | + aBcInterval.push(iBcInterval); | |
| 129 | + | |
| 130 | + // 尝试获取前一圈同方向的(normalFre -1)个班次的发车间隔 | |
| 131 | + j = 1; | |
| 132 | + if (groupIndex - 1 >= 0) { | |
| 133 | + for (i = aLp.length - 1; i >= 0; i--) { | |
| 134 | + if (j < normalFre) { | |
| 135 | + iBcInterval = aLp[i].fnGetVerticalIntervalTime( | |
| 136 | + groupIndex - 1, bcIndex); | |
| 137 | + if (iBcInterval) { // 存在发车间隔 | |
| 138 | + aBcInterval.push(iBcInterval); | |
| 139 | + j++; | |
| 140 | + } | |
| 141 | + } else { | |
| 142 | + break; | |
| 143 | + } | |
| 144 | + } | |
| 145 | + } | |
| 146 | + } | |
| 147 | + | |
| 148 | + aBcInterval.reverse(); | |
| 149 | + // 上一个班次间隔index | |
| 150 | + iPreBcIntervalIndex = aBcInterval.length - 1; | |
| 151 | + | |
| 152 | + var _iLpIndex; | |
| 153 | + for (i = 1; i <= aLp.length; i++) { | |
| 154 | + var oBcInterval_rtn = | |
| 155 | + {iLpIndex: null, hasBc: false, iFcInterval: null, iGroupIndex: null, iBcIndex: null}; | |
| 156 | + // 注意这里是 this._internalLpArray.length,最后一个班次是下标线下一圈的同方向班次 | |
| 157 | + _iLpIndex = i % aLp.length; | |
| 158 | + | |
| 159 | + if (_iLpIndex == 0) { // 下一圈的上标线同方向班次 | |
| 160 | + oBcInterval_rtn.iLpIndex = 0; | |
| 161 | + oBcInterval_rtn.iGroupIndex = groupIndex + 1; | |
| 162 | + oBcInterval_rtn.iBcIndex = bcIndex; | |
| 163 | + } else { | |
| 164 | + oBcInterval_rtn.iLpIndex = _iLpIndex; | |
| 165 | + oBcInterval_rtn.iGroupIndex = groupIndex; | |
| 166 | + oBcInterval_rtn.iBcIndex = bcIndex; | |
| 167 | + } | |
| 168 | + | |
| 169 | + // 班型判定 | |
| 170 | + if (_iLpIndex != 0) { // 回到上标线不用判定了 | |
| 171 | + if (!oInternalSchedule._$fnDecideBxBc( | |
| 172 | + oPreBc, _iLpIndex - 1, | |
| 173 | + _iLpIndex, | |
| 174 | + groupIndex, bcIndex | |
| 175 | + )) { | |
| 176 | + aBcInterval_rtn.push(oBcInterval_rtn); | |
| 177 | + continue; | |
| 178 | + } | |
| 179 | + } | |
| 180 | + | |
| 181 | + if (oParam.isMPeakBc(oPreBc.getFcTimeObj())) { // 早高峰 | |
| 182 | + // 如果上一个班次是早高峰班次,下一个班次使用_peakInterval计算早高峰发车间隔 | |
| 183 | + // 如果下一个班次(加上_peakInterval计算的早高峰发车间隔后)是低谷班次,使用低谷最小发车间隔加一个步长值 | |
| 184 | + oCurrentBcFcTime = oParam.addMinute( | |
| 185 | + oPreBc.getFcTimeObj(), | |
| 186 | + _peakInterval(oPreBc.getFcTimeObj(), oParam, normalStep)); | |
| 187 | + // if (oParam.isTroughBc(oCurrentBcFcTime)) { | |
| 188 | + // iBcInterval = oParam.getTroughMinFcjx() + normalStep; | |
| 189 | + // oCurrentBcFcTime = oParam.addMinute( | |
| 190 | + // oPreBc.getFcTimeObj(), | |
| 191 | + // iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval | |
| 192 | + // ); | |
| 193 | + // } | |
| 194 | + | |
| 195 | + } else if (oParam.isEPeakBc(oPreBc.getFcTimeObj())) { // 晚高峰 | |
| 196 | + // 如果上一个班次是晚高峰班次,下一个班次使用_peakInterval计算晚高峰发车间隔 | |
| 197 | + // 如果下一个班次(加上_peakInterval计算的晚高峰发车间隔后)是低谷班次,使用低谷最小发车间隔加一个步长值 | |
| 198 | + oCurrentBcFcTime = oParam.addMinute( | |
| 199 | + oPreBc.getFcTimeObj(), | |
| 200 | + _peakInterval(oPreBc.getFcTimeObj(), oParam, normalStep)); | |
| 201 | + // if (oParam.isTroughBc(oCurrentBcFcTime)) { | |
| 202 | + // iBcInterval = oParam.getTroughMinFcjx() + normalStep; | |
| 203 | + // oCurrentBcFcTime = oParam.addMinute( | |
| 204 | + // oPreBc.getFcTimeObj(), | |
| 205 | + // iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval | |
| 206 | + // ); | |
| 207 | + // } | |
| 208 | + } else { // 上一个班次是低谷 | |
| 209 | + if (aBcInterval.length < normalFre) { // 没有足够的连续班次间隔 | |
| 210 | + // 如果没有足够的连续班次间隔,那一定是在初始化第一圈的班次 | |
| 211 | + // 使用低谷最小发车间隔加一个步长值 | |
| 212 | + iBcInterval = oParam.getTroughMinFcjx() + normalStep; | |
| 213 | + oCurrentBcFcTime = oParam.addMinute( | |
| 214 | + oPreBc.getFcTimeObj(), | |
| 215 | + iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval | |
| 216 | + ); | |
| 217 | + // // 如果进入高峰,使用最大发车间隔 | |
| 218 | + // if (oParam.isMPeakBc(oCurrentBcFcTime)) { | |
| 219 | + // oCurrentBcFcTime = oParam.addMinute( | |
| 220 | + // oPreBc.getFcTimeObj(), | |
| 221 | + // oParam.getMPeakMaxFcjx() | |
| 222 | + // ); | |
| 223 | + // } | |
| 224 | + // if (oParam.isEPeakBc(oCurrentBcFcTime)) { | |
| 225 | + // oCurrentBcFcTime = oParam.addMinute( | |
| 226 | + // oPreBc.getFcTimeObj(), | |
| 227 | + // oParam.getEPeakMaxFcjx() | |
| 228 | + // ); | |
| 229 | + // } | |
| 230 | + } else { // 有足够的连续班次间隔 | |
| 231 | + // 看连续班次间隔是否一致,一致 加 normalStep 分钟(不能超过低谷最大发车间隔),不一致就相等间隔 | |
| 232 | + // 加了间隔后,如果是高峰班次,则使用高峰最大发车间隔 | |
| 233 | + // TODO:什么时候开始减低谷发车间隔到最小发车间隔,应该是在吃了饭之后 | |
| 234 | + | |
| 235 | + bIsIntervalEquale = true; | |
| 236 | + for (j = iPreBcIntervalIndex; j > iPreBcIntervalIndex - normalFre + 1; j--) { | |
| 237 | + if (aBcInterval[j] != aBcInterval[j - 1]) { | |
| 238 | + bIsIntervalEquale = false; | |
| 239 | + break; | |
| 240 | + } | |
| 241 | + } | |
| 242 | + if (bIsIntervalEquale) { | |
| 243 | + // 需要变换频率数据了 | |
| 244 | + | |
| 245 | + // TODO:14:00后开始到16:00之间减少低谷发车间隔 | |
| 246 | + if (oPreBc.getFcTimeObj().isAfter(oParam.toTimeObj("14:00")) && | |
| 247 | + oPreBc.getFcTimeObj().isBefore(oParam.toTimeObj("16:00"))) { | |
| 248 | + iBcInterval = aBcInterval[iPreBcIntervalIndex] - normalStep; | |
| 249 | + oCurrentBcFcTime = oParam.addMinute( | |
| 250 | + oPreBc.getFcTimeObj(), | |
| 251 | + iBcInterval < oParam.getTroughMinFcjx() ? oParam.getTroughMinFcjx() : iBcInterval | |
| 252 | + ); | |
| 253 | + } else { | |
| 254 | + iBcInterval = aBcInterval[iPreBcIntervalIndex] + normalStep; | |
| 255 | + oCurrentBcFcTime = oParam.addMinute( | |
| 256 | + oPreBc.getFcTimeObj(), | |
| 257 | + iBcInterval > oParam.getTroughMaxFcjx() ? oParam.getTroughMaxFcjx() : iBcInterval | |
| 258 | + ); | |
| 259 | + } | |
| 260 | + } else { | |
| 261 | + // 不需要变换频率,使用上一个班次的间隔 | |
| 262 | + oCurrentBcFcTime = oParam.addMinute( | |
| 263 | + oPreBc.getFcTimeObj(), | |
| 264 | + aBcInterval[iPreBcIntervalIndex] | |
| 265 | + ); | |
| 266 | + } | |
| 267 | + | |
| 268 | + // // 如果进入高峰使用高峰最大发车间隔 | |
| 269 | + // if (oParam.isMPeakBc(oCurrentBcFcTime)) { | |
| 270 | + // oCurrentBcFcTime = oParam.addMinute( | |
| 271 | + // oPreBc.getFcTimeObj(), | |
| 272 | + // oParam.getMPeakMaxFcjx() | |
| 273 | + // ); | |
| 274 | + // } | |
| 275 | + // if (oParam.isEPeakBc(oCurrentBcFcTime)) { | |
| 276 | + // oCurrentBcFcTime = oParam.addMinute( | |
| 277 | + // oPreBc.getFcTimeObj(), | |
| 278 | + // oParam.getEPeakMaxFcjx() | |
| 279 | + // ); | |
| 280 | + // } | |
| 281 | + | |
| 282 | + } | |
| 283 | + | |
| 284 | + } | |
| 285 | + | |
| 286 | + // 判定超出末班车,就没有班次 | |
| 287 | + if (oPreBc.isUp()) { | |
| 288 | + if (oCurrentBcFcTime.isAfter( | |
| 289 | + oParam.addMinute(oParam.getUpLastDtimeObj(), 30))) { | |
| 290 | + aBcInterval_rtn.push(oBcInterval_rtn); | |
| 291 | + continue; | |
| 292 | + } | |
| 293 | + } else { | |
| 294 | + if (oCurrentBcFcTime.isAfter( | |
| 295 | + oParam.addMinute(oParam.getDownLastDTimeObj(), 30))) { | |
| 296 | + aBcInterval_rtn.push(oBcInterval_rtn); | |
| 297 | + continue; | |
| 298 | + } | |
| 299 | + } | |
| 300 | + | |
| 301 | + oCurrentBcInterval = oCurrentBcFcTime.diff(oPreBc.getFcTimeObj(), "m"); | |
| 302 | + aBcInterval.push(oCurrentBcInterval); | |
| 303 | + oPreBc = oInternalSchedule.fnGetUitls().createBcObj( | |
| 304 | + aLp[_iLpIndex], | |
| 305 | + "normal", | |
| 306 | + oPreBc.isUp(), | |
| 307 | + 1, | |
| 308 | + oCurrentBcFcTime, | |
| 309 | + oParam | |
| 310 | + ); | |
| 311 | + iPreBcIntervalIndex++; | |
| 312 | + oBcInterval_rtn.hasBc = true; | |
| 313 | + oBcInterval_rtn.iFcInterval = oCurrentBcInterval; | |
| 314 | + aBcInterval_rtn.push(oBcInterval_rtn); | |
| 315 | + } | |
| 316 | + | |
| 317 | + } | |
| 318 | + | |
| 319 | + return aBcInterval_rtn; | |
| 320 | + } | |
| 321 | + | |
| 322 | + | |
| 323 | + function main( | |
| 324 | + oInternalSchedule, oParam, | |
| 325 | + iGroupIndex, iBcIndex, iMinCycleTime, iMaxCycleTime) { | |
| 326 | + | |
| 327 | + var iFre = 3; // 频率,连续相同发车间隔班次数 | |
| 328 | + var iStep = 1; // 步长,每个频率后变化1分钟 | |
| 329 | + var aBcInterval; // 每次计算返回的指定圈的间隔数组 | |
| 330 | + var iCycleTime = 0; // 每次计算放回的周转时间(把所有的间隔加在一起) | |
| 331 | + var i; | |
| 332 | + | |
| 333 | + var iterCount = 0; | |
| 334 | + var maxIter = 50; // 最多5次迭代,防止死循环 | |
| 335 | + | |
| 336 | + console.log(iMinCycleTime); | |
| 337 | + console.log(iMaxCycleTime); | |
| 338 | + | |
| 339 | + // TODO:先用最小值判定,后面再考虑最大值 | |
| 340 | + while (iCycleTime < iMinCycleTime && iterCount <= maxIter) { | |
| 341 | + aBcInterval = _internalBcInterval( | |
| 342 | + oInternalSchedule, oParam, | |
| 343 | + iGroupIndex, iBcIndex, iFre, iStep); | |
| 344 | + iCycleTime = 0; // 间隔加在一起就是周转 | |
| 345 | + for (i = 0; i < aBcInterval.length; i++) { | |
| 346 | + if (aBcInterval[i].hasBc) { | |
| 347 | + iCycleTime += aBcInterval[i].iFcInterval; | |
| 348 | + } | |
| 349 | + } | |
| 350 | + | |
| 351 | + // 下一次迭代,先降低频率直到1,然后再增加步长 | |
| 352 | + iFre = iFre > 1 ? iFre - 1 : 1; | |
| 353 | + iStep = iFre == 1 ? (iStep + 1) : 1; | |
| 354 | + iterCount ++; | |
| 355 | + } | |
| 356 | + | |
| 357 | + return aBcInterval; | |
| 358 | + | |
| 359 | + } | |
| 360 | + | |
| 361 | + return main; | |
| 362 | + | |
| 363 | +} ()); | |
| 364 | + | ... | ... |
src/main/resources/static/pages/base/timesmodel/paramadd.html
| ... | ... | @@ -423,9 +423,10 @@ |
| 423 | 423 | </script> |
| 424 | 424 | |
| 425 | 425 | <script type="text/javascript"> |
| 426 | - $('#paramadd_mobal').on('paramAddMobal.show', function(e, mainFun, mainFun2_2){ | |
| 426 | + $('#paramadd_mobal').on('paramAddMobal.show', function(e, mainFun, mainFun2_2, oSchedule_v2_2){ | |
| 427 | 427 | var _mainFun = mainFun; |
| 428 | 428 | var _mainFun_v2_2 = mainFun2_2; |
| 429 | + var _oSchedule_v2_2 = oSchedule_v2_2; | |
| 429 | 430 | |
| 430 | 431 | // 加载延迟200毫秒显示mobal |
| 431 | 432 | setTimeout(function(){$('#paramadd_mobal').modal({show : true,backdrop: 'static', keyboard: false});},200); |
| ... | ... | @@ -867,7 +868,7 @@ |
| 867 | 868 | var _paramObj = _mainFun.getFactory().createParameterObj(map, dataMap); |
| 868 | 869 | |
| 869 | 870 | if (!_paramObj.isTwoWayStop()) { // 主站停站使用v2_2版本 |
| 870 | - map.clzs = InternalScheduleObj_v2_2.calcuClzx(_paramObj); | |
| 871 | + map.clzs = _oSchedule_v2_2.calcuClzx(_paramObj); | |
| 871 | 872 | } else { |
| 872 | 873 | map.clzs = _paramObj.calcuClzx(); |
| 873 | 874 | } |
| ... | ... | @@ -890,7 +891,7 @@ |
| 890 | 891 | 'fcjx': {'gffcjx': Math.round(parmObj.calcuPeakZzsj()/parmObj.calcuClzx()) , |
| 891 | 892 | 'dgfcjx': Math.round(parmObj.calcuTroughZzsj()/parmObj.calcuClzx()), |
| 892 | 893 | 'dgmaxfcjx' : parseInt(map.dgmaxfcjx)}, |
| 893 | - 'maxCar':getYAxisCarArray(InternalScheduleObj_v2_2.calcuClzx(parmObj))}; | |
| 894 | + 'maxCar':getYAxisCarArray(_oSchedule_v2_2.calcuClzx(parmObj))}; | |
| 894 | 895 | } |
| 895 | 896 | |
| 896 | 897 | ... | ... |