您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么實現一個高效的啟發式算法”,在日常操作中,相信很多人在怎么實現一個高效的啟發式算法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么實現一個高效的啟發式算法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
其實無論是TSP或者是VRP,計算鄰居解的cost值都是非常簡便的。只需要用原解的值減去舊的邊再加上新的邊即可。不明白的小伙伴請回去好好看看上一期的內容哦。但是多了時間窗以后,難度又上升了一個量級。
時間窗為什么難呢,因為節點的先后順序是時間窗密切相關,并且前面的節點會影響到后面的節點。在經典的VRPTW中,規定了車輛早到必須等待,不允許晚到(如果晚到,該解不可行)。對于任意一個客戶 ,其時間窗為 ,假如車輛到達該節點的時間點為 ,那么該節點的開始服務時間 為:
因為早到必須等待,因此需要取兩者中最大的。客戶
的服務時間為 ,那么車輛離開客戶 的時間點為大家看,
是不是決定了車輛到達下一個客戶的時間點呢?假如 之后的一個客戶是 ,車輛行駛邊<i,j>所需要的時間為 ,則車輛到達客戶 的時間點為:好了現在原理講完了。下面講講鄰居解怎樣計算。
我就拿之前的圖過來了,關于路徑cost的計算我就不再多講了,這里講講時間窗的更新,因為在VRPTW的問題中,目標值一般是路徑cost和時間窗違背的總和。假如解
的時間窗違背總量為 ,顯然當 時, 為可行解。那么如何計算 呢?發生變化的路徑為
和 ,要評估鄰居解 的時間窗,當然了看過上一期的小伙伴肯定不會整個解再重新計算一遍。可以單獨把新的 和 拎出來,然后計算路徑的,再用解的減去路徑的即可。由于時間窗層層關聯的這種特性,對于快速計算
和 還是有一定的難度,這種難度尤其是提現在編碼的實現上,因為要維護大量的中間變量,因此大部分同學的選擇就是將兩條路徑重新計算,省時省力。畢竟有時候選擇比努力重要得多。不過小編當然不能退縮,因此今天就來講講鄰居解的時間窗如何去除計算冗余。
首先我們來看移除一個客戶的情景,
移除了客戶11和客戶17之間的一個客戶之后形成的 如下:客戶節點變動只會影響該節點之后的節點時間窗,因此對于前半截路段0->15->12->11是不需要重新計算的。現在問題來了:對于后半段17->7->0上的所有節點需要重新全部更新嗎?
答案是不一定需要。只需要更新后面有可能發生改變的節點即可。那么對于節點
而言,在原先的路徑中,車輛到達該節點的時間點為 ,如果 ,其中 為節點 的開始時間窗。那么在新的路徑中,該節點以及該節點以后的節點都不需要進行更新了。至于為什么,因為早到需要等待,如果在原先的路徑中,車輛早到了,那么車輛的服務時間開始時間會重置到客戶的開始時間窗,在移除一個客戶后,那么車輛在新的路徑中肯定會比之前的更早到達。總之,新路徑中該客戶處的開始服務時間就是客戶的開始時間窗,與原路徑保持一致,該客戶以及后面所有的都無需更新了。
再來看看插入一個客戶
的場景:客戶19之前的肯定不用管了。更新需要從該客戶起,更新車輛到達客戶19的時間,然后是客戶2,一直到末尾。這里也和上面的一樣,有一個臨界條件的,達到該條件后就可以跳出更新。對于節點
而言,在新的(注意和上面的區別)的路徑中,車輛到達該節點的時間點為 ,如果 ,其中 為節點 的開始時間窗。那么在新的路徑中,該節點以及該節點以后的節點都不需要進行更新了。因為早到需要等待,如果在原先的路徑中,車輛早到了,那么車輛的服務時間開始時間會重置到客戶的開始時間窗,在插入一個客戶后,那么車輛在新的路徑中肯定會比之前的更晚到達,如果新路徑中車輛到達客戶的時間點仍然小于等于客戶的開始時間窗,那么該客戶以及后面所有的都無需更新了。
當然了,還是得放一下代碼,因為咱們是實干派,不吹牛皮不煲雞湯。對于時間窗,每個客戶節點還是需要維護一些中間變量的,難點就在于如何正確無誤的維護這些中間變量。寫去冗余的啟發式難就難在調試……
首先是插入一個節點的代碼:
/**
* This function simulate the insertion of the customer in the given route on the given position.
* Computes the new cost and return it.
* It is an optimized version of the evaluate route. Calculates only for the customers affected
* by the insertion. Starts from the given position and could finish before reaching the end of
* the list if there is no modification in the arrive time at the customers.
* Does not alter the route or the customer
* @param route
* @param customer
* @param position
* @return
*/
private Cost evaluateInsertRoute(Route route, Customer customer, int position) {
Cost varCost = new Cost(route.getCost());
double arriveCustomer = 0;
double arriveNextCustomer = 0;
double waitingTimeCustomer = 0;
double waitingTimeNextCustomer = 0;
double twViolCustomer = 0;
double twViolNextCustomer = 0;
// if route is empty insert: depot - customer - depot
if(route.isEmpty()) {
varCost.initialize();
// arrive time at the customer
arriveCustomer = route.getDepot().getStartTw()
+ instance.getTravelTime(route.getDepotNr(), customer.getNumber());
// waiting time for the customer if any
waitingTimeCustomer = Math.max(0, customer.getStartTw() - arriveCustomer);
// time window violation of the customer if any
twViolCustomer = Math.max(0, arriveCustomer - customer.getEndTw());
// arrive time at the depot
arriveNextCustomer = Math.max(customer.getStartTw(), arriveCustomer)
+ customer.getServiceDuration()
+ instance.getTravelTime(customer.getNumber(), route.getDepotNr());
// time window violation of the depot if any
twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw());
//variation of the travel time
varCost.travelTime = instance.getTravelTime(route.getDepotNr(), customer.getNumber())
+ instance.getTravelTime(customer.getNumber(), route.getDepotNr());
// variation of the capacity
varCost.load = customer.getCapacity();
// route service time
varCost.serviceTime = customer.getServiceDuration();
//variation of the waiting time
varCost.waitingTime = waitingTimeCustomer;
// variation of the time windows violation
varCost.twViol = twViolCustomer + twViolNextCustomer;
}else{
// insertion at the end of the list: customer before - customer - depot
if(position == route.getCustomersLength()){
Customer customerBefore = route.getCustomer(position - 1);
arriveCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime())
+ customerBefore.getServiceDuration()
+ instance.getTravelTime(customerBefore.getNumber(), customer.getNumber());
// waiting time for the customer if any
waitingTimeCustomer = Math.max(0, customer.getStartTw() - arriveCustomer);
// time window violation of the customer if any
twViolCustomer = Math.max(0, arriveCustomer - customer.getEndTw());
// arrive time at the depot
arriveNextCustomer = Math.max(customer.getStartTw(), arriveCustomer)
+ customer.getServiceDuration()
+ instance.getTravelTime(customer.getNumber(), route.getDepotNr());
// time window violation of the depot if any
twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(customerBefore.getNumber(), route.getDepotNr())
+ instance.getTravelTime(customerBefore.getNumber(), customer.getNumber())
+ instance.getTravelTime(customer.getNumber(), route.getDepotNr());
// variation of the capacity
varCost.load += customer.getCapacity();
// route service time
varCost.serviceTime += customer.getServiceDuration();
//variation of the waiting time
varCost.waitingTime += waitingTimeCustomer;
// variation of the time windows violation
varCost.twViol += - varCost.depotTwViol + twViolCustomer + twViolNextCustomer;
}else {
double variation = 0;
Customer customerAfter = route.getCustomer(position);
// insertion on the first position: depot - customer - customer after
if(position == 0){
// time before arrive at the customer
arriveCustomer = route.getDepot().getStartTw()
+ instance.getTravelTime(route.getDepotNr(), customer.getNumber());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(route.getDepotNr(), customerAfter.getNumber())
+ instance.getTravelTime(route.getDepotNr(), customer.getNumber())
+ instance.getTravelTime(customer.getNumber(), customerAfter.getNumber());
// insertion in the middle of the list: customer before - customer - customer after
}else {
Customer customerBefore = route.getCustomer(position - 1);
// time before arrive at the customer
arriveCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime())
+ customerBefore.getServiceDuration()
+ instance.getTravelTime(customerBefore.getNumber(), customer.getNumber());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(customerBefore.getNumber(), customerAfter.getNumber())
+ instance.getTravelTime(customerBefore.getNumber(), customer.getNumber())
+ instance.getTravelTime(customer.getNumber(), customerAfter.getNumber());
} // end if else beginning or middle
// this code runs when inserting at the beginning or in the middle
// waiting time for the customer if any
waitingTimeCustomer = Math.max(0, customer.getStartTw() - arriveCustomer);
// time window violation of the customer if any
twViolCustomer = Math.max(0, arriveCustomer - customer.getEndTw());
// before arrive time at the customer after
arriveNextCustomer = Math.max(customer.getStartTw(), arriveCustomer)
+ customer.getServiceDuration()
+ instance.getTravelTime(customer.getNumber(), customerAfter.getNumber());
// waiting time for the customer after if any
waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer);
// time window violation of the customer after if any
twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw());
// variation of the capacity
varCost.load += customer.getCapacity();
// route service time
varCost.serviceTime += customer.getServiceDuration();
//variation of the waiting time
varCost.waitingTime += - customerAfter.getWaitingTime() + waitingTimeCustomer + waitingTimeNextCustomer;
// variation of the time windows violation
varCost.twViol += - customerAfter.getTwViol() + twViolCustomer + twViolNextCustomer;
// variation = Math.max(customerAfter.getStartTw(), arriveNextCustomer) - Math.max(customerAfter.getStartTw(), customerAfter.getArriveTime());
variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime();
variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation;
// if there is a variation update the nodes after too
int i = position + 1;
while (variation != 0 && i < route.getCustomersLength()){
customerAfter = route.getCustomer(i);
// arrive at the customer after
arriveNextCustomer = customerAfter.getArriveTime() + variation;
waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer);
twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw());
//variation of the waiting time
varCost.waitingTime += - customerAfter.getWaitingTime() + waitingTimeNextCustomer;
// variation of the time windows violation
varCost.twViol += - customerAfter.getTwViol() + twViolNextCustomer;
// variation = Math.max(customerAfter.getStartTw(), arriveNextCustomer) - Math.max(customerAfter.getStartTw(), customerAfter.getArriveTime());
variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime();
variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation;
i++;
}// end while
if(i == route.getCustomersLength() && variation != 0 ){
// update the return to the depot
arriveNextCustomer = varCost.returnToDepotTime + variation;
twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw());
// variation of the time windows violation
varCost.twViol += - varCost.depotTwViol + twViolNextCustomer;
}// end if return to depot
} // end if else of position cases
} // end if else route is empty
varCost.waitingTime = Math.abs(varCost.waitingTime) < instance.getPrecision() ? 0 : varCost.waitingTime;
varCost.twViol = Math.abs(varCost.twViol) < instance.getPrecision() ? 0 : varCost.twViol;
varCost.setLoadViol(Math.max(0, varCost.load - route.getLoadAdmited()));
varCost.setDurationViol(Math.max(0, varCost.getDuration() - route.getDurationAdmited()));
return varCost;
} // end method evaluate insert route
/**
* This function simulate the deletion of a customer in the given route on the given position.
* Computes the new cost and return it.
* It is an optimized version of the evaluate route. Calculates only for the customers affected
* by the deletion. Starts from the given position and could finish before reaching the end of
* the list if there is no modification in the arrive time at the customers.
* Does not alter the route.
* @param route
* @param position
* @return
*/
private Cost evaluateDeleteRoute(Route route, Customer customer, int position) {
Cost varCost = new Cost(route.getCost());
double arriveNextCustomer = 0;
double waitingTimeNextCustomer = 0;
double twViolNextCustomer = 0;
// if route has only the customer that will be deleted
if(route.getCustomersLength() - 1 == 0) {
varCost.initialize();
}else{
// case when customer is the last one: customer before - depot
if(position == route.getCustomersLength() - 1){
Customer customerBefore = route.getCustomer(position - 1);
//arrive time at the depot
arriveNextCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime())
+ customerBefore.getServiceDuration()
+ instance.getTravelTime(customerBefore.getNumber(), route.getDepotNr());
// time window violation of the depot if any
twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(customerBefore.getNumber(), customer.getNumber())
- instance.getTravelTime(customer.getNumber(), route.getDepotNr())
+ instance.getTravelTime(customerBefore.getNumber(), route.getDepotNr());
// variation of the capacity
varCost.load -= customer.getCapacity();
// route service time
varCost.serviceTime -= customer.getServiceDuration();
//variation of the waiting time
varCost.waitingTime -= customer.getWaitingTime();
// variation of the time windows violation
varCost.twViol += - customer.getTwViol() - route.getDepotTwViol() + twViolNextCustomer;
}else{
double variation = 0;
Customer customerAfter = route.getCustomer(position + 1);
// delete on the first position
if(position == 0){
// time before arrive at customer after
arriveNextCustomer = route.getDepot().getStartTw()
+ instance.getTravelTime(route.getDepotNr(), customerAfter.getNumber());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(route.getDepotNr(), customer.getNumber())
- instance.getTravelTime(customer.getNumber(), customerAfter.getNumber())
+ instance.getTravelTime(route.getDepotNr(), customerAfter.getNumber());
// insertion in the middle of the list
}else{
Customer customerBefore = route.getCustomer(position - 1);
// time before arrive at customer after
arriveNextCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime())
+ customerBefore.getServiceDuration()
+ instance.getTravelTime(customerBefore.getNumber(), customerAfter.getNumber());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(customerBefore.getNumber(), customer.getNumber())
- instance.getTravelTime(customer.getNumber(), customerAfter.getNumber())
+ instance.getTravelTime(customerBefore.getNumber(), customerAfter.getNumber());
} // end if else beginning or middle
// this code runs when inserting at the beginning or in the middle
// waiting time for the customer after if any
waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer);
// time window violation of the customer after if any
twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw());
// variation of the capacity
varCost.load -= customer.getCapacity();
// route service time
varCost.serviceTime -= customer.getServiceDuration();
//variation of the waiting time
varCost.waitingTime += - customer.getWaitingTime() - customerAfter.getWaitingTime() + waitingTimeNextCustomer;
// variation of the time windows violation
varCost.twViol += - customer.getTwViol() - customerAfter.getTwViol() + twViolNextCustomer;
// variation = Math.max(customerAfter.getStartTw(), arriveNextCustomer) - Math.max(customerAfter.getStartTw(), customerAfter.getArriveTime());
// variation = arriveNextCustomer -customerAfter.getArriveTime();
variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime();
variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation;
// if there is a variation update the nodes after too
// the node after the customer is already updated
int i = position + 2;
while (variation != 0 && i < route.getCustomersLength()){
customerAfter = route.getCustomer(i);
// arrive at the customer after
arriveNextCustomer = customerAfter.getArriveTime() + variation;
waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer);
twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw());
//variation of the waiting time
varCost.waitingTime += -customerAfter.getWaitingTime() + waitingTimeNextCustomer;
// variation of the time windows violation
varCost.twViol += -customerAfter.getTwViol() + twViolNextCustomer;
// variation = Math.max(customerAfter.getStartTw(), arriveNextCustomer) - Math.max(customerAfter.getStartTw(), customerAfter.getArriveTime());
// variation = arriveNextCustomer -customerAfter.getArriveTime();
variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime();
variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation;
i++;
}// end while
// update depot violation too if any
if(i == route.getCustomersLength() && variation != 0 ){
// update the return to the depot
arriveNextCustomer = route.getReturnToDepotTime() + variation;
twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw());
// variation of the time windows violation
varCost.twViol += - route.getDepotTwViol() + twViolNextCustomer;
}// end if return to depot
} // end if else of position cases
} // end if else route is empty
// route.removeCustomer(position);
// be careful about precision; if there are subtraction
varCost.waitingTime = Math.abs(varCost.waitingTime) < instance.getPrecision() ? 0 : varCost.waitingTime;
varCost.twViol = Math.abs(varCost.twViol) < instance.getPrecision() ? 0 : varCost.twViol;
varCost.setLoadViol(Math.max(0, varCost.load - route.getLoadAdmited()));
varCost.setDurationViol(Math.max(0, varCost.getDuration() - route.getDurationAdmited()));
return varCost;
} // end method evaluate delete route
然后是刪除一個客戶的代碼:
/**
* This function simulate the deletion of a customer in the given route on the given position.
* Computes the new cost and return it.
* It is an optimized version of the evaluate route. Calculates only for the customers affected
* by the deletion. Starts from the given position and could finish before reaching the end of
* the list if there is no modification in the arrive time at the customers.
* Does not alter the route.
* @param route
* @param position
* @return
*/
private Cost evaluateDeleteRoute(Route route, Customer customer, int position) {
Cost varCost = new Cost(route.getCost());
double arriveNextCustomer = 0;
double waitingTimeNextCustomer = 0;
double twViolNextCustomer = 0;
// if route has only the customer that will be deleted
if(route.getCustomersLength() - 1 == 0) {
varCost.initialize();
}else{
// case when customer is the last one: customer before - depot
if(position == route.getCustomersLength() - 1){
Customer customerBefore = route.getCustomer(position - 1);
//arrive time at the depot
arriveNextCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime())
+ customerBefore.getServiceDuration()
+ instance.getTravelTime(customerBefore.getNumber(), route.getDepotNr());
// time window violation of the depot if any
twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(customerBefore.getNumber(), customer.getNumber())
- instance.getTravelTime(customer.getNumber(), route.getDepotNr())
+ instance.getTravelTime(customerBefore.getNumber(), route.getDepotNr());
// variation of the capacity
varCost.load -= customer.getCapacity();
// route service time
varCost.serviceTime -= customer.getServiceDuration();
//variation of the waiting time
varCost.waitingTime -= customer.getWaitingTime();
// variation of the time windows violation
varCost.twViol += - customer.getTwViol() - route.getDepotTwViol() + twViolNextCustomer;
}else{
double variation = 0;
Customer customerAfter = route.getCustomer(position + 1);
// delete on the first position
if(position == 0){
// time before arrive at customer after
arriveNextCustomer = route.getDepot().getStartTw()
+ instance.getTravelTime(route.getDepotNr(), customerAfter.getNumber());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(route.getDepotNr(), customer.getNumber())
- instance.getTravelTime(customer.getNumber(), customerAfter.getNumber())
+ instance.getTravelTime(route.getDepotNr(), customerAfter.getNumber());
// insertion in the middle of the list
}else{
Customer customerBefore = route.getCustomer(position - 1);
// time before arrive at customer after
arriveNextCustomer = Math.max(customerBefore.getStartTw(), customerBefore.getArriveTime())
+ customerBefore.getServiceDuration()
+ instance.getTravelTime(customerBefore.getNumber(), customerAfter.getNumber());
//variation of the travel time
varCost.travelTime += - instance.getTravelTime(customerBefore.getNumber(), customer.getNumber())
- instance.getTravelTime(customer.getNumber(), customerAfter.getNumber())
+ instance.getTravelTime(customerBefore.getNumber(), customerAfter.getNumber());
} // end if else beginning or middle
// this code runs when inserting at the beginning or in the middle
// waiting time for the customer after if any
waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer);
// time window violation of the customer after if any
twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw());
// variation of the capacity
varCost.load -= customer.getCapacity();
// route service time
varCost.serviceTime -= customer.getServiceDuration();
//variation of the waiting time
varCost.waitingTime += - customer.getWaitingTime() - customerAfter.getWaitingTime() + waitingTimeNextCustomer;
// variation of the time windows violation
varCost.twViol += - customer.getTwViol() - customerAfter.getTwViol() + twViolNextCustomer;
// variation = Math.max(customerAfter.getStartTw(), arriveNextCustomer) - Math.max(customerAfter.getStartTw(), customerAfter.getArriveTime());
// variation = arriveNextCustomer -customerAfter.getArriveTime();
variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime();
variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation;
// if there is a variation update the nodes after too
// the node after the customer is already updated
int i = position + 2;
while (variation != 0 && i < route.getCustomersLength()){
customerAfter = route.getCustomer(i);
// arrive at the customer after
arriveNextCustomer = customerAfter.getArriveTime() + variation;
waitingTimeNextCustomer = Math.max(0, customerAfter.getStartTw() - arriveNextCustomer);
twViolNextCustomer = Math.max(0, arriveNextCustomer - customerAfter.getEndTw());
//variation of the waiting time
varCost.waitingTime += -customerAfter.getWaitingTime() + waitingTimeNextCustomer;
// variation of the time windows violation
varCost.twViol += -customerAfter.getTwViol() + twViolNextCustomer;
// variation = Math.max(customerAfter.getStartTw(), arriveNextCustomer) - Math.max(customerAfter.getStartTw(), customerAfter.getArriveTime());
// variation = arriveNextCustomer -customerAfter.getArriveTime();
variation = arriveNextCustomer + waitingTimeNextCustomer - customerAfter.getArriveTime() - customerAfter.getWaitingTime();
variation = Math.abs(variation) < instance.getPrecision() ? 0 : variation;
i++;
}// end while
// update depot violation too if any
if(i == route.getCustomersLength() && variation != 0 ){
// update the return to the depot
arriveNextCustomer = route.getReturnToDepotTime() + variation;
twViolNextCustomer = Math.max(0, arriveNextCustomer - route.getDepot().getEndTw());
// variation of the time windows violation
varCost.twViol += - route.getDepotTwViol() + twViolNextCustomer;
}// end if return to depot
} // end if else of position cases
} // end if else route is empty
// route.removeCustomer(position);
// be careful about precision; if there are subtraction
varCost.waitingTime = Math.abs(varCost.waitingTime) < instance.getPrecision() ? 0 : varCost.waitingTime;
varCost.twViol = Math.abs(varCost.twViol) < instance.getPrecision() ? 0 : varCost.twViol;
varCost.setLoadViol(Math.max(0, varCost.load - route.getLoadAdmited()));
varCost.setDurationViol(Math.max(0, varCost.getDuration() - route.getDurationAdmited()));
return varCost;
} // end method evaluate delete route
到此,關于“怎么實現一個高效的啟發式算法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。