-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSeqData.h
129 lines (121 loc) · 3.58 KB
/
SeqData.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#pragma once
#include "Param.h"
/*
* Based on paper "A unified solution framework for multi-attribute vehicle routing problems"
*/
class SeqData
{
public:
//attributes:
int firstnode;//index location
int afterFiNode;// index after first node
int lastnode;//index location
int beforeLaNode;// index before last node
int cost;// will set to oo if infeasible sub-sequence
int load;
int E;//earliest time completion
int L;//latest starting time
int T;//sum of travel and service time
bool F;//check feasibility;d
Param* pr;
//constructor
SeqData() {};
SeqData(Param* _pr) {
pr = _pr;
};
~SeqData() {
};
void showSeq() {
cout << pr->listLoc[firstnode].idxClient << " " << pr->listLoc[lastnode].idxClient << "\n";
}
void showSeqLoc() {
cout << firstnode << " " << lastnode << "\n";
}
//method:
/*
* Construct sequence containing only one node
*/
void init(int idxLoc) {
firstnode = idxLoc;
afterFiNode = -1;
lastnode = idxLoc;
beforeLaNode = -1;
T = 0;// changed to service time if have
E = pr->listLoc[idxLoc].stTime;// plus service time if have.
L = pr->listLoc[idxLoc].enTime;
cost = 0;
load = pr->listLoc[idxLoc].demand;
F = true;
}
/**/
void concatOneAfter(SeqData* seq, int idxLoc) {
if (seq == NULL) init(idxLoc);
F = seq->F;
int t_12 = pr->times[seq->lastnode][idxLoc];
if (seq->E + t_12 > pr->listLoc[idxLoc].enTime) {
F = false;
}
if (seq->load + pr->listLoc[idxLoc].demand > pr->Q) {
F = false;
}
cost = min(seq->cost + pr->costs[seq->lastnode][idxLoc], int(oo));
load = seq->load + pr->listLoc[idxLoc].demand;
E = max(seq->E + t_12, pr->listLoc[idxLoc].stTime);
L = min(seq->L, pr->listLoc[idxLoc].enTime - t_12 - seq->T);
T = seq->T + t_12;
lastnode = idxLoc;
firstnode = seq->firstnode;
if (seq->afterFiNode == -1) {
afterFiNode = idxLoc;
}else afterFiNode = seq->afterFiNode;
beforeLaNode = seq->lastnode;
}
/**/
void concatOneBefore(SeqData* seq, int idxLoc) {
if (seq == NULL) init(idxLoc);
F = seq->F;
int t_12 = pr->times[idxLoc][seq->firstnode];
if (pr->listLoc[idxLoc].stTime + t_12> seq->L) {
F = false;
}
if (seq->load + pr->listLoc[idxLoc].demand > pr->Q) {
F = false;
}
cost = min(seq->cost + pr->costs[idxLoc][seq->firstnode], int(oo));
load = seq->load + pr->listLoc[idxLoc].demand;
E = max(pr->listLoc[idxLoc].stTime + t_12 + seq->T, seq->E);
L = min(pr->listLoc[idxLoc].enTime, seq->L - t_12);
T = seq->T + t_12;
firstnode = idxLoc;
lastnode = seq->lastnode;
if (seq->beforeLaNode == -1) {
beforeLaNode = idxLoc;
}else beforeLaNode = seq->beforeLaNode;
afterFiNode = seq->firstnode;
}
/**/
int evaluation(vector<SeqData*> seqs) {
if (seqs.front() == NULL)seqs.erase(seqs.begin());//remove null sequence
if (seqs.back() == NULL)seqs.pop_back();//remove null sequence
int costR = seqs[0]->cost;
int loadR = seqs[0]->load;
bool totalF = seqs[0]->F;
int totalE = seqs[0]->E;
int totalL = seqs[0]->L;
int totalT = seqs[0]->T;
int u = -1, v = -1;
for (int i = 0; i < seqs.size() - 1; ++i) {
u = seqs[i]->lastnode;
v = seqs[i + 1]->firstnode;
costR += (pr->costs[u][v] + seqs[i + 1]->cost);
loadR += seqs[i + 1]->load;
totalF = (totalF & seqs[i + 1]->F) & (totalE + pr->times[u][v] <= seqs[i + 1]->L) & (loadR <= pr->Q) & (costR < oo);
if (!totalF)return oo;// only use for checking feasible solution
totalE = max(totalE + pr->times[u][v] + seqs[i + 1]->T, seqs[i + 1]->E);
totalL = max(totalL, seqs[i + 1]->L - pr->times[u][v] - totalT);
totalT += pr->times[u][v] + seqs[i + 1]->T;
}
return costR;
}
private:
};