Commit ca9dd7dbc3d13a38ad784f87ef62cf3571e5d4bc

Authored by 徐烜
1 parent abd1f204

时刻表v2_2.2

1、将选择班次逻辑,生成间隔逻辑单独成策略类,放在v2版本的StrategyUtils里引用
2、修正班次选择逻辑,其他分班选择班次逻辑,下午车次链定在15:00后所有班次都出,并且如果超出了总班次数,且当前班次还是高峰的话,也添加
3、修正生成间隔逻辑,高峰间隔也使用步长的方式从最小值开始添加,当前班次时间段全看前一个班次时间段,迭代频率改成3
4、行车计划对象计算最小周转时间使用主站停站时间,最大周转时间使用2倍的主站停站时间
src/main/resources/static/pages/base/timesmodel/gantt.html
@@ -179,7 +179,6 @@ @@ -179,7 +179,6 @@
179 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS2.js"></script> 179 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS2.js"></script>
180 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS3.js"></script> 180 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS3.js"></script>
181 <script src="/pages/base/timesmodel/js/v2/strategy/adjust/AdjustTripS4.js"></script> 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 <script src="/pages/base/timesmodel/js/v2/main_v2.js"></script> 182 <script src="/pages/base/timesmodel/js/v2/main_v2.js"></script>
184 183
185 <!-- 184 <!--
@@ -189,6 +188,10 @@ @@ -189,6 +188,10 @@
189 188
190 <script src="/pages/base/timesmodel/js/v2_2/InternalScheduleObj.js"></script> 189 <script src="/pages/base/timesmodel/js/v2_2/InternalScheduleObj.js"></script>
191 <script src="/pages/base/timesmodel/js/v2_2/main_v2_2.js"></script> 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 <script src="/pages/base/timesmodel/js/errorinfo.js"></script> 195 <script src="/pages/base/timesmodel/js/errorinfo.js"></script>
193 <script src="/pages/base/timesmodel/js/parameters.js"></script> 196 <script src="/pages/base/timesmodel/js/parameters.js"></script>
194 <script src="/pages/base/timesmodel/js/systemTools.js"></script> 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 @@ $(&#39;.parambtn&#39;).on(&#39;click&#39;, function() { @@ -321,7 +321,7 @@ $(&#39;.parambtn&#39;).on(&#39;click&#39;, function() {
321 $.get('/pages/base/timesmodel/paramadd.html', function(m){ 321 $.get('/pages/base/timesmodel/paramadd.html', function(m){
322 $(pjaxContainer).append(m); 322 $(pjaxContainer).append(m);
323 // 规定被选元素要触发的事件。可以使自定义事件(使用 bind() 函数来附加),或者任何标准事件。 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,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 * @returns [{圈index},{班次index}] 298 * @returns [{圈index},{班次index}]
272 */ 299 */
@@ -1136,7 +1163,7 @@ InternalLpObj.prototype.modifyLayoverTimeWithoutFcTime = function() { @@ -1136,7 +1163,7 @@ InternalLpObj.prototype.modifyLayoverTimeWithoutFcTime = function() {
1136 iDiff = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m"); 1163 iDiff = oNextBc.getFcTimeObj().diff(oBc.getArrTimeObj(), "m");
1137 if (oNextBc.fnGetEatTime() > 0) { 1164 if (oNextBc.fnGetEatTime() > 0) {
1138 oBc.setStopTime(iDiff - oNextBc.fnGetEatTime()); 1165 oBc.setStopTime(iDiff - oNextBc.fnGetEatTime());
1139 - } else if (iDiff > 60) { // 大于60分钟,肯定车次链结束班次,停站0 1166 + } else if (iDiff > 120) { // 大于60分钟,肯定车次链结束班次,停站0
1140 oBc.setStopTime(0); 1167 oBc.setStopTime(0);
1141 } else { 1168 } else {
1142 oBc.setStopTime(iDiff); 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 \ No newline at end of file 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,7 +328,7 @@ var InternalScheduleObj_v2_2 = (function() {
328 // 总共车辆数(高峰最大车辆数) 328 // 总共车辆数(高峰最大车辆数)
329 var iCls = InternalScheduleObj.calcuClzx(this._oParam); 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 // 加班车路牌数(做5休2的路牌数) 332 // 加班车路牌数(做5休2的路牌数)
333 var i_5_2_lpes = this._oParam.getJBLpes(); 333 var i_5_2_lpes = this._oParam.getJBLpes();
334 334
@@ -351,6 +351,9 @@ var InternalScheduleObj_v2_2 = (function() { @@ -351,6 +351,9 @@ var InternalScheduleObj_v2_2 = (function() {
351 iDgminpc = iCls - i_5_2_lpes; 351 iDgminpc = iCls - i_5_2_lpes;
352 } 352 }
353 353
  354 + // TODO:如果其他分班路牌数,连班路牌数相差比较远,则可以让二者对半分
  355 + // TODO:前提是对半分之后连班路牌数要大于等于最少连班路牌数
  356 +
354 //// 修正连班路牌数,班次间隔大于20的,加1,直至班次间隔小于20 357 //// 修正连班路牌数,班次间隔大于20的,加1,直至班次间隔小于20
355 //while(_paramObj.calcuPeakZzsj() / iDgminpc > 20) { 358 //while(_paramObj.calcuPeakZzsj() / iDgminpc > 20) {
356 // iDgminpc ++; 359 // iDgminpc ++;
@@ -527,7 +530,12 @@ var InternalScheduleObj_v2_2 = (function() { @@ -527,7 +530,12 @@ var InternalScheduleObj_v2_2 = (function() {
527 var _modifyTime; // 上标线下一个圈班次的前一个班次的调整时间 530 var _modifyTime; // 上标线下一个圈班次的前一个班次的调整时间
528 531
529 if (oSlaveBc) { 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 oPreBc = this._internalLpArray[0].getBc(iSlaveGroupIndex, iSlaveBcIndex); 539 oPreBc = this._internalLpArray[0].getBc(iSlaveGroupIndex, iSlaveBcIndex);
532 for (i = 1; i < this._internalLpArray.length; i++) { 540 for (i = 1; i < this._internalLpArray.length; i++) {
533 oBcInterval = aBcInterval[i - 1]; 541 oBcInterval = aBcInterval[i - 1];
@@ -668,21 +676,23 @@ var InternalScheduleObj_v2_2 = (function() { @@ -668,21 +676,23 @@ var InternalScheduleObj_v2_2 = (function() {
668 if (!this._internalLpArray[i - 1].getBc(0, 1)) { 676 if (!this._internalLpArray[i - 1].getBc(0, 1)) {
669 // 上一个路牌没有班次,添加 677 // 上一个路牌没有班次,添加
670 oSBc = oSLp.getBc(1, 0); // 第一圈第一个班次 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,211 +711,41 @@ var InternalScheduleObj_v2_2 = (function() {
701 * @param oPreBc 上一个班次 711 * @param oPreBc 上一个班次
702 * @param iPreLpIndex 上一个班次路牌索引 712 * @param iPreLpIndex 上一个班次路牌索引
703 * @param iCurrentLpIndex 当前路牌索引 713 * @param iCurrentLpIndex 当前路牌索引
704 - * @param iGroupIndex 圈索引  
705 - * @param iBcIndex 班次索引 714 + * @param iCurrentGroupIndex 圈索引
  715 + * @param iCurrentBcIndex 班次索引
706 * @private 716 * @private
707 */ 717 */
708 InternalScheduleObj.prototype._$fnDecideBxBc = function( 718 InternalScheduleObj.prototype._$fnDecideBxBc = function(
709 oPreBc, iPreLpIndex, 719 oPreBc, iPreLpIndex,
710 iCurrentLpIndex, 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,7 +773,12 @@ var InternalScheduleObj_v2_2 = (function() {
933 var _modifyBc; // 上标线下一个圈的班次 773 var _modifyBc; // 上标线下一个圈的班次
934 774
935 for (i = this._iMPeakMasterBcGroupIndex; i < this._qCount; i++) { 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 if (aBcInterval.length == 0) { 782 if (aBcInterval.length == 0) {
938 // 等于0说明上标线没班次了 783 // 等于0说明上标线没班次了
939 break; 784 break;
@@ -1040,232 +885,6 @@ var InternalScheduleObj_v2_2 = (function() { @@ -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,7 +914,7 @@ var InternalScheduleObj_v2_2 = (function() {
1295 oPreBc = oLp.getPreBc(oBc); 914 oPreBc = oLp.getPreBc(oBc);
1296 915
1297 if (!oEatFlag[oLp.getLpNo()]["isLaunch"]) { 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 oBc.fnSetEatTime(this._oParam.fnGetLunchTime()); 918 oBc.fnSetEatTime(this._oParam.fnGetLunchTime());
1300 oEatFlag[oLp.getLpNo()]["isLaunch"] = true; 919 oEatFlag[oLp.getLpNo()]["isLaunch"] = true;
1301 } 920 }
@@ -1308,7 +927,7 @@ var InternalScheduleObj_v2_2 = (function() { @@ -1308,7 +927,7 @@ var InternalScheduleObj_v2_2 = (function() {
1308 oPreBc = oLp.getPreBc(oBc); 927 oPreBc = oLp.getPreBc(oBc);
1309 928
1310 if (!oEatFlag[oLp.getLpNo()]["isDinner"]) { 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 oBc.fnSetEatTime(this._oParam.fnGetDinnerTime()); 931 oBc.fnSetEatTime(this._oParam.fnGetDinnerTime());
1313 oEatFlag[oLp.getLpNo()]["isDinner"] = true; 932 oEatFlag[oLp.getLpNo()]["isDinner"] = true;
1314 } 933 }
@@ -1626,6 +1245,30 @@ var InternalScheduleObj_v2_2 = (function() { @@ -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 InternalScheduleObj.prototype.fnToGanttBcArray = function() { 1274 InternalScheduleObj.prototype.fnToGanttBcArray = function() {
@@ -1682,7 +1325,88 @@ var InternalScheduleObj_v2_2 = (function() { @@ -1682,7 +1325,88 @@ var InternalScheduleObj_v2_2 = (function() {
1682 return aGanttBc; 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 //-------------------- static静态方法 ----------------------// 1408 //-------------------- static静态方法 ----------------------//
  1409 +
1686 /** 1410 /**
1687 * 计算车辆数。 1411 * 计算车辆数。
1688 * @param oParam 参数对象 1412 * @param oParam 参数对象
src/main/resources/static/pages/base/timesmodel/js/v2_2/main_v2_2.js
@@ -779,8 +779,6 @@ var Main_v2_2 = function() { @@ -779,8 +779,6 @@ var Main_v2_2 = function() {
779 // 6、补进出场例保班次 779 // 6、补进出场例保班次
780 schedule.fnCalcuOtherBc(); 780 schedule.fnCalcuOtherBc();
781 781
782 - // TODO  
783 -  
784 //-------------------- 输出ganut图上的班次,班型描述 ----------------------// 782 //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
785 // TODO:班型再议 783 // TODO:班型再议
786 return { 784 return {
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 \ No newline at end of file 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,9 +423,10 @@
423 </script> 423 </script>
424 424
425 <script type="text/javascript"> 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 var _mainFun = mainFun; 427 var _mainFun = mainFun;
428 var _mainFun_v2_2 = mainFun2_2; 428 var _mainFun_v2_2 = mainFun2_2;
  429 + var _oSchedule_v2_2 = oSchedule_v2_2;
429 430
430 // 加载延迟200毫秒显示mobal 431 // 加载延迟200毫秒显示mobal
431 setTimeout(function(){$('#paramadd_mobal').modal({show : true,backdrop: 'static', keyboard: false});},200); 432 setTimeout(function(){$('#paramadd_mobal').modal({show : true,backdrop: 'static', keyboard: false});},200);
@@ -867,7 +868,7 @@ @@ -867,7 +868,7 @@
867 var _paramObj = _mainFun.getFactory().createParameterObj(map, dataMap); 868 var _paramObj = _mainFun.getFactory().createParameterObj(map, dataMap);
868 869
869 if (!_paramObj.isTwoWayStop()) { // 主站停站使用v2_2版本 870 if (!_paramObj.isTwoWayStop()) { // 主站停站使用v2_2版本
870 - map.clzs = InternalScheduleObj_v2_2.calcuClzx(_paramObj); 871 + map.clzs = _oSchedule_v2_2.calcuClzx(_paramObj);
871 } else { 872 } else {
872 map.clzs = _paramObj.calcuClzx(); 873 map.clzs = _paramObj.calcuClzx();
873 } 874 }
@@ -890,7 +891,7 @@ @@ -890,7 +891,7 @@
890 'fcjx': {'gffcjx': Math.round(parmObj.calcuPeakZzsj()/parmObj.calcuClzx()) , 891 'fcjx': {'gffcjx': Math.round(parmObj.calcuPeakZzsj()/parmObj.calcuClzx()) ,
891 'dgfcjx': Math.round(parmObj.calcuTroughZzsj()/parmObj.calcuClzx()), 892 'dgfcjx': Math.round(parmObj.calcuTroughZzsj()/parmObj.calcuClzx()),
892 'dgmaxfcjx' : parseInt(map.dgmaxfcjx)}, 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