Skip to content

Commit

Permalink
CVRP and CVRPTW Penalty functions optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
c4v4 committed Aug 27, 2021
1 parent 510d0b6 commit 04c636f
Show file tree
Hide file tree
Showing 5 changed files with 553 additions and 89 deletions.
5 changes: 5 additions & 0 deletions SRC/FreeStructures.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ void FreeStructures()
Free(cycle);
Free(G);
FreePopulation();

#ifdef CAVA_PENALTY
Free(cava_PetalsData);
Free(cava_NodeCache);
#endif
}

/*
Expand Down
154 changes: 92 additions & 62 deletions SRC/INCLUDE/LKH.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#ifdef CAVA_CUSTOM
#define CAVA_CACHE /* Cost and Forbidden function cache optimization */
#define CAVA_PENALTY
#define CAVA_PENALTY /* CVRP and CVRPTW penalty optimization */
#define CAVA_FLIP
#endif

Expand Down Expand Up @@ -85,91 +85,106 @@ MergeTourFunction MergeWithTour;

/* The Node structure is used to represent nodes (cities) of the problem */

struct Node {
int Id; /* Number of the node (1...Dimension) */
int Loc; /* Location of the node in the heap
(zero, if the node is not in the heap) */
int Rank; /* During the ascent, the priority of the node.
typedef struct _RouteData RouteData; /* Forward declaration, see the end of this file*/

struct Node
{
double Earliest, Latest;
double ServiceTime;
int Demand; /* Customer demand in a CVRP or 1-PDTSP instance */
int *C; /* A row in the cost matrix */
int DepotId; /* Equal to Id if the node is a depot; otherwize 0 */
Node *Pred, *Suc; /* Predecessor and successor node in
the two-way list of nodes */
int PredCost, SucCost; /* The costs of the neighbor edges on the current tour */
Node *FixedTo1, /* Pointers to the opposite end nodes of fixed edges. */
*FixedTo2; /* A maximum of two fixed edges can be incident to a node */
int Pi; /* Pi-value of the node */
Segment *Parent; /* Parent segment of a node when the two-level
tree representation is used */
int Id; /* Number of the node (1...Dimension) */
int Rank; /* During the ascent, the priority of the node.
Otherwise, the ordinal number of the node in
the tour */
int V; /* During the ascent the degree of the node minus 2.
int Loc; /* Location of the node in the heap
(zero, if the node is not in the heap) */

int V; /* During the ascent the degree of the node minus 2.
Otherwise, the variable is used to mark nodes */
int LastV; /* Last value of V during the ascent */
int Cost; /* "Best" cost of an edge emanating from the node */
int NextCost; /* During the ascent, the next best cost of an edge
int LastV; /* Last value of V during the ascent */
int Cost; /* "Best" cost of an edge emanating from the node */
int NextCost; /* During the ascent, the next best cost of an edge
emanating from the node */
int PredCost, /* The costs of the neighbor edges on the current tour */
SucCost;
int SavedCost;
int Pi; /* Pi-value of the node */
int BestPi; /* Currently best pi-value found during the ascent */
int Beta; /* Beta-value (used for computing alpha-values) */
int BestPi; /* Currently best pi-value found during the ascent */
int Beta; /* Beta-value (used for computing alpha-values) */
int Subproblem; /* Number of the subproblem the node is part of */
int Sons; /* Number of sons in the minimum spanning tree */
int *C; /* A row in the cost matrix */
int Special; /* Is the node a special node in Jonker and
int Sons; /* Number of sons in the minimum spanning tree */
int Special; /* Is the node a special node in Jonker and
Volgenant's mTSP to TSP transformation? */
int Demand; /* Customer demand in a CVRP or 1-PDTSP instance */
int *M_Demand; /* Table of demands in an M-PDTSP instance */
int Seq; /* Sequence number in the current tour */
int DraftLimit; /* Draft limit in a TSPDL instance */
int Load; /* Accumulated load in the current route */
int OriginalId; /* The original Id in a SDVRP or STTSPinstance */
Node *Pred, *Suc; /* Predecessor and successor node in
the two-way list of nodes */

int *M_Demand; /* Table of demands in an M-PDTSP instance */
int Seq; /* Sequence number in the current tour */
int DraftLimit; /* Draft limit in a TSPDL instance */
int Load; /* Accumulated load in the current route */
int OriginalId; /* The original Id in a SDVRP or STTSPinstance */

Node *OldPred, *OldSuc; /* Previous values of Pred and Suc */
Node *BestSuc, /* Best and next best successor node in the */
*NextBestSuc; /* currently best tour */
Node *Dad; /* Father of the node in the minimum 1-tree */
Node *Nearest; /* Nearest node (used in the greedy heuristics) */
Node *Next; /* Auxiliary pointer, usually to the next node in a list
Node *BestSuc, /* Best and next best successor node in the */
*NextBestSuc; /* currently best tour */
Node *Dad; /* Father of the node in the minimum 1-tree */
Node *Nearest; /* Nearest node (used in the greedy heuristics) */
Node *Next; /* Auxiliary pointer, usually to the next node in a list
of nodes (e.g., the list of "active" nodes) */
Node *Prev; /* Auxiliary pointer, usually to the previous node
Node *Prev; /* Auxiliary pointer, usually to the previous node
in a list of nodes */
Node *Mark; /* Visited mark */
Node *FixedTo1, /* Pointers to the opposite end nodes of fixed edges. */
*FixedTo2; /* A maximum of two fixed edges can be incident
to a node */
Node *FixedTo1Saved, /* Saved values of FixedTo1 and FixedTo2 */
*FixedTo2Saved;
Node *Head; /* Head of a segment of fixed or common edges */
Node *Tail; /* Tail of a segment of fixed or common edges */
Node *InputSuc; /* Successor in the INPUT_TOUR file */
Node *InitialSuc; /* Successor in the INITIAL_TOUR file */
Node *SubproblemPred; /* Predecessor in the SUBPROBLEM_TOUR file */
Node *SubproblemSuc; /* Successor in the SUBPROBLEM_TOUR file */
Node *SubBestPred; /* The best predecessor node in a subproblem */
Node *SubBestSuc; /* The best successor node in a subproblem */
Node *MergePred; /* Predecessor in the first MERGE_TOUR file */
Node **MergeSuc; /* Successors in the MERGE_TOUR files */
Node *Added1, *Added2; /* Pointers to the opposite end nodes
Node *Mark; /* Visited mark */
Node *FixedTo1Saved, /* Saved values of FixedTo1 and FixedTo2 */
*FixedTo2Saved;
Node *Head; /* Head of a segment of fixed or common edges */
Node *Tail; /* Tail of a segment of fixed or common edges */
Node *InputSuc; /* Successor in the INPUT_TOUR file */
Node *InitialSuc; /* Successor in the INITIAL_TOUR file */
Node *SubproblemPred; /* Predecessor in the SUBPROBLEM_TOUR file */
Node *SubproblemSuc; /* Successor in the SUBPROBLEM_TOUR file */
Node *SubBestPred; /* The best predecessor node in a subproblem */
Node *SubBestSuc; /* The best successor node in a subproblem */
Node *MergePred; /* Predecessor in the first MERGE_TOUR file */
Node **MergeSuc; /* Successors in the MERGE_TOUR files */
Node *Added1, *Added2; /* Pointers to the opposite end nodes
of added edges in a submove */
Node *Deleted1, *Deleted2; /* Pointers to the opposite end nodes
Node *Deleted1, *Deleted2; /* Pointers to the opposite end nodes
of deleted edges in a submove */
Node *SucSaved; /* Saved pointer to successor node */
Candidate *CandidateSet; /* Candidate array */
Node *SucSaved; /* Saved pointer to successor node */
Candidate *CandidateSet; /* Candidate array */
Candidate *BackboneCandidateSet; /* Backbone candidate array */
Segment *Parent; /* Parent segment of a node when the two-level
tree representation is used */

Constraint *FirstConstraint;
int *PathLength;
int **Path;
double ServiceTime;
int Pickup, Delivery;
int DepotId; /* Equal to Id if the node is a depot; otherwize 0 */
double Earliest, Latest;
int Backhaul;
int Serial;
int Color;
double X, Y, Z; /* Coordinates of the node */
double Xc, Yc, Zc; /* Converted coordinates */
char Axis; /* The axis partitioned when the node is part of a KDTree */
char OldPredExcluded, OldSucExcluded; /* Booleans used for indicating
double X, Y, Z; /* Coordinates of the node */
double Xc, Yc, Zc; /* Converted coordinates */
char Axis; /* The axis partitioned when the node is part of a KDTree */
char OldPredExcluded, OldSucExcluded; /* Booleans used for indicating
whether one (or both) of the
adjoining nodes on the old tour
has been excluded */
char Required; /* Is the node required in a STTSP? */
char Required; /* Is the node required in a STTSP? */

#ifdef CAVA_PENALTY
int PFlag; /*used to mark nodes */
RouteData* PetalId; /* Pointer to struct with current route data */
int PetalRank; /* Position of the node inside the route */
GainType prevPenalty; /* Previous Penalty value of the node, for partial iteration of routes */
GainType prevDemandSum; /* Previous Demand value of the node, for partial iteration of routes */
GainType prevCostSum; /* Previous Cost value of the node, for partial iteration of routes */
#endif
};


/* The Candidate structure is used to represent candidate edges */

Expand Down Expand Up @@ -657,4 +672,19 @@ int Forbidden(Node *Na, Node *Nb);

#endif

#ifdef CAVA_PENALTY

typedef struct _RouteData
{
int flag;
GainType OldPenalty;
GainType CandPenalty;
Node *minNode;
} RouteData;

RouteData *cava_PetalsData;
Node **cava_NodeCache;

#endif

#endif
49 changes: 26 additions & 23 deletions SRC/INCLUDE/Segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,43 +35,46 @@
* following preprocessor command line.
*/

#ifdef THREE_LEVEL_TREE
#define PRED(a)\
(Reversed == ((a)->Parent->Reversed != (a)->Parent->Parent->Reversed) ?\
(a)->Pred : (a)->Suc)
#define SUC(a)\
(Reversed == ((a)->Parent->Reversed != (a)->Parent->Parent->Reversed) ?\
(a)->Suc : (a)->Pred)
#ifdef THREE_LEVEL_TREE
#define PRED(a) \
(Reversed == ((a)->Parent->Reversed != (a)->Parent->Parent->Reversed) ? (a)->Pred : (a)->Suc)
#define SUC(a) \
(Reversed == ((a)->Parent->Reversed != (a)->Parent->Parent->Reversed) ? (a)->Suc : (a)->Pred)
#define BETWEEN(a, b, c) Between_SSL(a, b, c)
#define FLIP(a, b, c, d) Flip_SSL(a, b, c)
#endif
#ifdef TWO_LEVEL_TREE
#ifdef TWO_LEVEL_TREE
#define PRED(a) (Reversed == (a)->Parent->Reversed ? (a)->Pred : (a)->Suc)
#define SUC(a) (Reversed == (a)->Parent->Reversed ? (a)->Suc : (a)->Pred)
#define PRED_COST(a) (Reversed == (a)->Parent->Reversed ? (a)->PredCost : (a)->SucCost)
#define SUC_COST(a) (Reversed == (a)->Parent->Reversed ? (a)->SucCost : (a)->PredCost)
#define BETWEEN(a, b, c) Between_SL(a, b, c)
#define FLIP(a, b, c, d) Flip_SL(a, b, c)
#endif
#ifdef ONE_LEVEL_TREE
#ifdef ONE_LEVEL_TREE
#define PRED(a) (Reversed ? (a)->Suc : (a)->Pred)
#define SUC(a) (Reversed ? (a)->Pred : (a)->Suc)
#define PRED_COST(a) (Reversed ? (a)->SucCost : (a)->PredCost)
#define SUC_COST(a) (Reversed ? (a)->PredCost : (a)->SucCost)
#define BETWEEN(a, b, c) Between(a, b, c)
#define FLIP(a, b, c, d) Flip(a, b, c)
#endif

#define PREDD(a) ((a)->Parent ? PRED(a) :\
Reversed ? (a)->Suc : (a)->Pred)
#define SUCC(a) ((a)->Parent ? SUC(a) :\
Reversed ? (a)->Pred : (a)->Suc)
#define PREDD(a) ((a)->Parent ? PRED(a) : Reversed ? (a)->Suc : (a)->Pred)
#define SUCC(a) ((a)->Parent ? SUC(a) : Reversed ? (a)->Pred : (a)->Suc)

#define Swap1(a1,a2,a3)\
FLIP(a1,a2,a3,0)
#define Swap2(a1,a2,a3, b1,b2,b3)\
(Swap1(a1,a2,a3), Swap1(b1,b2,b3))
#define Swap3(a1,a2,a3, b1,b2,b3, c1,c2,c3)\
(Swap2(a1,a2,a3, b1,b2,b3), Swap1(c1,c2,c3))
#define Swap4(a1,a2,a3, b1,b2,b3, c1,c2,c3, d1,d2,d3)\
(Swap3(a1,a2,a3, b1,b2,b3, c1,c2,c3), Swap1(d1,d2,d3))
#define Swap5(a1,a2,a3, b1,b2,b3, c1,c2,c3, d1,d2,d3, e1,e2,e3)\
(Swap4(a1,a2,a3, b1,b2,b3, c1,c2,c3, d1,d2,d3), Swap1(e1,e2,e3))
#define SUCC_COST(a, b) ((a)->Parent ? SUC_COST(a) : Reversed ? (a)->PredCost : (a)->SucCost)
#define PREDD_COST(a, b) ((a)->Parent ? PRED_COST(a) : Reversed ? (a)->SucCost : (a)->PredCost)

#define Swap1(a1, a2, a3) \
FLIP(a1, a2, a3, 0)
#define Swap2(a1, a2, a3, b1, b2, b3) \
(Swap1(a1, a2, a3), Swap1(b1, b2, b3))
#define Swap3(a1, a2, a3, b1, b2, b3, c1, c2, c3) \
(Swap2(a1, a2, a3, b1, b2, b3), Swap1(c1, c2, c3))
#define Swap4(a1, a2, a3, b1, b2, b3, c1, c2, c3, d1, d2, d3) \
(Swap3(a1, a2, a3, b1, b2, b3, c1, c2, c3), Swap1(d1, d2, d3))
#define Swap5(a1, a2, a3, b1, b2, b3, c1, c2, c3, d1, d2, d3, e1, e2, e3) \
(Swap4(a1, a2, a3, b1, b2, b3, c1, c2, c3, d1, d2, d3), Swap1(e1, e2, e3))

#endif

0 comments on commit 04c636f

Please sign in to comment.