-
Notifications
You must be signed in to change notification settings - Fork 0
/
russell.cpp
85 lines (70 loc) · 2.48 KB
/
russell.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
#ifndef RUSSELL
#define RUSSELL
#include "bfs_generator.cpp"
#include <cassert>
#include <climits>
typedef pair<int, int> coordinates;
typedef pair<coordinates, int> node;
const node faultyNode = {{-1, -1}, INT_MAX};
class Russell : public BFS_Generator {
public:
void generate_bfs(TransportationMatrix m) {
vector<vector<int>> w =
vector<vector<int>>(m.height, vector<int>(m.width, 0));
vector<int> &v = m.v;
vector<int> &u = m.u;
// Set highest costs for each row
for (int row = 0; row < m.height; row++) {
int largestRowCost = -1;
for (int col = 0; col < m.width; col++)
largestRowCost =
m.c(row, col) > largestRowCost ? m.c(row, col) : largestRowCost;
u[row] = largestRowCost;
}
// Set highest costs for each column
for (int col = 0; col < m.width; col++) {
int largestColCost = -1;
for (int row = 0; row < m.height; row++)
largestColCost =
m.c(row, col) > largestColCost ? m.c(row, col) : largestColCost;
v[col] = largestColCost;
}
// Repeat untill only one untouched cell remains
do {
// Calculate deltas
for (int i = 0; i < m.height; i++)
for (int j = 0; j < m.width; j++)
if (!m.isCrossedOutCell(i, j))
w[i][j] = m.c(i, j) - (u[i] + v[j]);
// Find cell with the greatest negative value
node gnv = faultyNode;
for (int i = 0; i < m.height; i++)
for (int j = 0; j < m.width; j++)
if (!m.isCrossedOutCell(i, j))
if (w[i][j] < gnv.second && w[i][j] < 0)
gnv = {{i, j}, w[i][j]};
if (gnv == faultyNode)
break;
// Allocate as many goods as possilble from supply or demand
int &supply = m.supply[gnv.first.first];
int &demand = m.demand[gnv.first.second];
int maxToAllocate = supply < demand ? supply : demand;
m(gnv.first.first, gnv.first.second).allocated = maxToAllocate;
supply -= maxToAllocate;
demand -= maxToAllocate;
// Crossout spent supply row or demand column
if (supply == 0)
m.crossOutRow(gnv.first.first);
else
m.crossOutColumn(gnv.first.second);
} while (m.crossedOutColumns.size() - 1 != m.width &&
m.crossedOutRows.size() - 1 != m.height);
cout << m << endl;
for (int i = 0; i < m.height; i++) {
for (int j = 0; j < m.width; j++) {
cout << "x" << i + 1 << j + 1 << ": " << m(i, j).allocated << endl;
}
}
}
};
#endif // !RUSSELL