This repository has been archived by the owner on Jan 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
constraints.cpp
144 lines (117 loc) · 4.22 KB
/
constraints.cpp
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "constraints.hpp"
/**
Constraint object constructor that loads constraint file input and sets a network object pointer.
Requires the names of the user cost file, assignment model file, initial flow file, and a network object pointer.
If the initial flow file can be successfuly read, this becomes the initial flow vector. If not, we default to the zero flow vector.
*/
Constraint::Constraint(string us_file_name, string assignment_file_name, string flow_file_name, Network * net_in)
{
Net = net_in;
stop_size = Net->stop_nodes.size();
sol_pair.first.resize(Net->core_arcs.size(), 0.0);
// Attempt to read flow file
cout << "Attempting to read initial flows..." << endl;
ifstream fl_file;
fl_file.open(flow_file_name);
if (fl_file.is_open())
{
string line, piece; // whole line and line element being read
getline(fl_file, line); // skip comment line
while (fl_file.eof() == false)
{
// Get whole line as a string stream
getline(fl_file, line);
if (line.size() == 0)
// Break for blank line at file end
break;
stringstream stream(line);
// Go through each piece of the line
getline(stream, piece, '\t'); // ID
int id = stoi(piece);
if (id >= sol_pair.first.size())
break;
getline(stream, piece, '\t'); // Flow
sol_pair.first[id] = stod(piece);
}
fl_file.close();
cout << "Successfully read flows!" << endl;
}
else
cout << "Flow file failed to open. Defaulting to zero initial flow." << endl;
// Initialize assignment model object
Assignment = new NonlinearAssignment(assignment_file_name, flow_file_name, net_in);
// Read constraint data
cout << "Reading user cost data..." << endl;
ifstream us_file;
us_file.open(us_file_name);
if (us_file.is_open())
{
string line, piece; // whole line and line element being read
getline(us_file, line); // skip comment line
int count = 0;
while (us_file.eof() == false)
{
count++;
// Get whole line as a string stream
getline(us_file, line);
if (line.size() == 0)
// Break for blank line at file end
break;
stringstream stream(line);
// Go through each piece of the line
getline(stream, piece, '\t'); // Label
getline(stream, piece, '\t'); // Value
string value = piece;
// Expected data
if (count == 1)
initial_user_cost = stod(value);
if (count == 2)
uc_percent_increase = stod(value);
if (count == 4)
riding_weight = stod(value);
if (count == 5)
walking_weight = stod(value);
if (count == 6)
waiting_weight = stod(value);
}
us_file.close();
}
else
cout << "User cost file failed to open." << endl;
cout << "User cost data read!" << endl << endl;
}
/**
Evaluates the constraint functions for a given solution.
Requires a solution vector.
Returns a pair whose first element is the feasibility result (1 for feasible, 0 for infeasible) and whose second element is a vector of constraint function elements, ordered in the same way as the solution log file.
All of the constraint functions are evaluated using either the solution vector directly, or using the flow vector produced by the assignment model.
*/
pair<int, vector<double>> Constraint::calculate(vector<int> &sol)
{
// Feed solution to assignment model to calculate flow vector
sol_pair = Assignment->calculate(sol, sol_pair);
// Calculate user cost components
vector<double> ucc = user_cost_components();
// Calculate total user cost and compare to the bound to determine feasibility
double total_user_cost = riding_weight*ucc[0] + walking_weight*ucc[1] + waiting_weight*ucc[2];
int feas = 1;
if (total_user_cost > (1 + uc_percent_increase)*initial_user_cost)
feas = 0;
return make_pair(feas, ucc);
}
/**
Converts user flow vector and waiting time scalar into a vector of the user cost components.
Returns a vector of the user cost components, in the order of the solution log columns.
*/
vector<double> Constraint::user_cost_components()
{
vector<double> uc(3, 0);
uc[2] = sol_pair.second;
// In-vehicle riding time
for (int i = 0; i < Net->line_arcs.size(); i++)
uc[0] += sol_pair.first[Net->line_arcs[i]->id] * Net->line_arcs[i]->cost;
// Walking time
for (int i = 0; i < Net->walking_arcs.size(); i++)
uc[1] += sol_pair.first[Net->walking_arcs[i]->id] * Net->walking_arcs[i]->cost;
return uc;
}