dancealgorithm 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dancealgorithm/__init__.py +128 -0
- dancealgorithm/__main__.py +8 -0
- dancealgorithm/assignments/DA - Campus/Solution.java +198 -0
- dancealgorithm/assignments/DA - Campus/__init__.py +34 -0
- dancealgorithm/assignments/DA - Flight/Solution.java +204 -0
- dancealgorithm/assignments/DA - Flight/__init__.py +34 -0
- dancealgorithm/assignments/DA - Smart/Solution.java +220 -0
- dancealgorithm/assignments/DA - Smart/__init__.py +34 -0
- dancealgorithm/assignments/DA.txt +29 -0
- dancealgorithm/assignments/FK - Advertisement/Solution.java +141 -0
- dancealgorithm/assignments/FK - Advertisement/__init__.py +34 -0
- dancealgorithm/assignments/FK - Electric/Solution.java +168 -0
- dancealgorithm/assignments/FK - Electric/__init__.py +34 -0
- dancealgorithm/assignments/FK - Emergency/Solution.java +159 -0
- dancealgorithm/assignments/FK - Emergency/__init__.py +34 -0
- dancealgorithm/assignments/FK.txt +26 -0
- dancealgorithm/assignments/GC - Classroom/Solution.java +87 -0
- dancealgorithm/assignments/GC - Classroom/__init__.py +34 -0
- dancealgorithm/assignments/GC - Interference/Solution.java +88 -0
- dancealgorithm/assignments/GC - Interference/__init__.py +34 -0
- dancealgorithm/assignments/GC - University/Solution.java +88 -0
- dancealgorithm/assignments/GC - University/__init__.py +34 -0
- dancealgorithm/assignments/GC.txt +25 -0
- dancealgorithm/assignments/K - Cloud/Solution.java +115 -0
- dancealgorithm/assignments/K - Cloud/__init__.py +34 -0
- dancealgorithm/assignments/K - Disaster/Solution.java +116 -0
- dancealgorithm/assignments/K - Disaster/__init__.py +34 -0
- dancealgorithm/assignments/K - Hospital/Solution.java +115 -0
- dancealgorithm/assignments/K - Hospital/__init__.py +34 -0
- dancealgorithm/assignments/K.txt +38 -0
- dancealgorithm/assignments/LC - Delivery/Solution.java +180 -0
- dancealgorithm/assignments/LC - Delivery/__init__.py +34 -0
- dancealgorithm/assignments/LC - Drilling/Solution.java +197 -0
- dancealgorithm/assignments/LC - Drilling/__init__.py +34 -0
- dancealgorithm/assignments/LC - Flight/Solution.java +180 -0
- dancealgorithm/assignments/LC - Flight/__init__.py +34 -0
- dancealgorithm/assignments/LC.txt +31 -0
- dancealgorithm/assignments/MS - Commerce/Solution.java +162 -0
- dancealgorithm/assignments/MS - Commerce/__init__.py +34 -0
- dancealgorithm/assignments/MS - Commerce/dataset.csv +16 -0
- dancealgorithm/assignments/MS - Customer/Solution.java +144 -0
- dancealgorithm/assignments/MS - Customer/__init__.py +34 -0
- dancealgorithm/assignments/MS - Customer/dataset.csv +16 -0
- dancealgorithm/assignments/MS - Library/Solution.java +162 -0
- dancealgorithm/assignments/MS - Library/__init__.py +34 -0
- dancealgorithm/assignments/MS - Library/dataset.csv +16 -0
- dancealgorithm/assignments/MS.txt +32 -0
- dancealgorithm/assignments/MSG - Emergency/Solution.java +211 -0
- dancealgorithm/assignments/MSG - Emergency/__init__.py +34 -0
- dancealgorithm/assignments/MSG - Logistics/Solution.java +189 -0
- dancealgorithm/assignments/MSG - Logistics/__init__.py +34 -0
- dancealgorithm/assignments/MSG - Skyconnect/Solution.java +204 -0
- dancealgorithm/assignments/MSG - Skyconnect/__init__.py +34 -0
- dancealgorithm/assignments/MSG.txt +28 -0
- dancealgorithm/assignments/QS - Commerce/Solution.java +147 -0
- dancealgorithm/assignments/QS - Commerce/__init__.py +34 -0
- dancealgorithm/assignments/QS - Commerce/dataset.csv +16 -0
- dancealgorithm/assignments/QS - Movie/Solution.java +148 -0
- dancealgorithm/assignments/QS - Movie/__init__.py +34 -0
- dancealgorithm/assignments/QS - Movie/dataset.csv +16 -0
- dancealgorithm/assignments/QS - Online/Solution.java +147 -0
- dancealgorithm/assignments/QS - Online/__init__.py +34 -0
- dancealgorithm/assignments/QS - Online/dataset.csv +16 -0
- dancealgorithm/assignments/QS.txt +33 -0
- dancealgorithm/assignments/__init__.py +65 -0
- dancealgorithm/cli.py +349 -0
- dancealgorithm/config.py +125 -0
- dancealgorithm/downloader.py +330 -0
- dancealgorithm-0.1.0.dist-info/METADATA +199 -0
- dancealgorithm-0.1.0.dist-info/RECORD +74 -0
- dancealgorithm-0.1.0.dist-info/WHEEL +5 -0
- dancealgorithm-0.1.0.dist-info/entry_points.txt +3 -0
- dancealgorithm-0.1.0.dist-info/licenses/LICENSE +22 -0
- dancealgorithm-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
PATH = Path(__file__).resolve().parent
|
|
7
|
+
DIR = PATH
|
|
8
|
+
JAVA_SOLUTION = PATH / "Solution.java"
|
|
9
|
+
DATASET_PATH = PATH / "dataset.csv"
|
|
10
|
+
TITLE = "LC - Delivery"
|
|
11
|
+
|
|
12
|
+
def get_code() -> str:
|
|
13
|
+
if JAVA_SOLUTION.exists():
|
|
14
|
+
return JAVA_SOLUTION.read_text(encoding="utf-8")
|
|
15
|
+
return ""
|
|
16
|
+
|
|
17
|
+
def extract(destination: Optional[str | Path] = None, overwrite: bool = True) -> Path:
|
|
18
|
+
from dancealgorithm.downloader import extract_bundled
|
|
19
|
+
from dancealgorithm.config import get_destination
|
|
20
|
+
target = Path(destination) if destination else get_destination()
|
|
21
|
+
extract_bundled(target, subject_filter=TITLE, overwrite=overwrite)
|
|
22
|
+
return target / PATH.name
|
|
23
|
+
|
|
24
|
+
def open_folder() -> None:
|
|
25
|
+
import os
|
|
26
|
+
if sys.platform == "win32":
|
|
27
|
+
os.system(f'explorer "{PATH}"')
|
|
28
|
+
|
|
29
|
+
def __getattr__(name: str):
|
|
30
|
+
if name in ("code", "java_code", "solution_code"):
|
|
31
|
+
return get_code()
|
|
32
|
+
if name in ("path", "folder", "dir"):
|
|
33
|
+
return PATH
|
|
34
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import java.util.Arrays;
|
|
2
|
+
import java.util.PriorityQueue;
|
|
3
|
+
|
|
4
|
+
// Main solution
|
|
5
|
+
public class Solution {
|
|
6
|
+
// O(n! * n^2)
|
|
7
|
+
static final double INF = 1e9;
|
|
8
|
+
|
|
9
|
+
static class Hole {
|
|
10
|
+
double x, y;
|
|
11
|
+
String label;
|
|
12
|
+
|
|
13
|
+
Hole(double x, double y, String label) {
|
|
14
|
+
this.x = x;
|
|
15
|
+
this.y = y;
|
|
16
|
+
this.label = label;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Search node
|
|
21
|
+
static class Node implements Comparable<Node> {
|
|
22
|
+
double[][] matrix;
|
|
23
|
+
int[] path;
|
|
24
|
+
int level;
|
|
25
|
+
double cost;
|
|
26
|
+
int city;
|
|
27
|
+
|
|
28
|
+
Node(double[][] mat, int[] path, int level, double cost, int city) {
|
|
29
|
+
int n = mat.length;
|
|
30
|
+
this.matrix = new double[n][n];
|
|
31
|
+
for (int i = 0; i < n; i++) {
|
|
32
|
+
System.arraycopy(mat[i], 0, this.matrix[i], 0, n);
|
|
33
|
+
}
|
|
34
|
+
this.path = Arrays.copyOf(path, path.length);
|
|
35
|
+
this.level = level;
|
|
36
|
+
this.cost = cost;
|
|
37
|
+
this.city = city;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public int compareTo(Node other) {
|
|
42
|
+
return Double.compare(this.cost, other.cost);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Matrix reduction
|
|
47
|
+
public static double reduceMatrix(double[][] mat, int n) {
|
|
48
|
+
double reduction = 0;
|
|
49
|
+
|
|
50
|
+
for (int i = 0; i < n; i++) {
|
|
51
|
+
double rmin = INF;
|
|
52
|
+
for (int j = 0; j < n; j++) {
|
|
53
|
+
if (mat[i][j] < rmin) rmin = mat[i][j];
|
|
54
|
+
}
|
|
55
|
+
if (rmin > 0 && rmin < INF) {
|
|
56
|
+
reduction += rmin;
|
|
57
|
+
for (int j = 0; j < n; j++) {
|
|
58
|
+
if (mat[i][j] < INF) mat[i][j] -= rmin;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (int j = 0; j < n; j++) {
|
|
64
|
+
double cmin = INF;
|
|
65
|
+
for (int i = 0; i < n; i++) {
|
|
66
|
+
if (mat[i][j] < cmin) cmin = mat[i][j];
|
|
67
|
+
}
|
|
68
|
+
if (cmin > 0 && cmin < INF) {
|
|
69
|
+
reduction += cmin;
|
|
70
|
+
for (int i = 0; i < n; i++) {
|
|
71
|
+
if (mat[i][j] < INF) mat[i][j] -= cmin;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return reduction;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Branch and bound TSP
|
|
80
|
+
public static void solveLCBB_TSP(double[][] costMatrix, Hole[] holes) {
|
|
81
|
+
int n = costMatrix.length;
|
|
82
|
+
|
|
83
|
+
double[][] initialMat = new double[n][n];
|
|
84
|
+
for (int i = 0; i < n; i++) {
|
|
85
|
+
System.arraycopy(costMatrix[i], 0, initialMat[i], 0, n);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
double rootCost = reduceMatrix(initialMat, n);
|
|
89
|
+
|
|
90
|
+
PriorityQueue<Node> pq = new PriorityQueue<>();
|
|
91
|
+
int[] rootPath = {0};
|
|
92
|
+
pq.add(new Node(initialMat, rootPath, 1, rootCost, 0));
|
|
93
|
+
|
|
94
|
+
double bestCost = INF;
|
|
95
|
+
int[] bestTour = null;
|
|
96
|
+
|
|
97
|
+
while (!pq.isEmpty()) {
|
|
98
|
+
Node curr = pq.poll();
|
|
99
|
+
|
|
100
|
+
if (curr.cost >= bestCost) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (curr.level == n) {
|
|
105
|
+
int lastCity = curr.city;
|
|
106
|
+
if (costMatrix[lastCity][0] < INF) {
|
|
107
|
+
double tourCost = 0;
|
|
108
|
+
for (int i = 0; i < n - 1; i++) {
|
|
109
|
+
tourCost += costMatrix[curr.path[i]][curr.path[i + 1]];
|
|
110
|
+
}
|
|
111
|
+
tourCost += costMatrix[lastCity][0];
|
|
112
|
+
|
|
113
|
+
if (tourCost < bestCost) {
|
|
114
|
+
bestCost = tourCost;
|
|
115
|
+
bestTour = new int[n + 1];
|
|
116
|
+
System.arraycopy(curr.path, 0, bestTour, 0, n);
|
|
117
|
+
bestTour[n] = 0;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
int u = curr.city;
|
|
124
|
+
|
|
125
|
+
for (int v = 0; v < n; v++) {
|
|
126
|
+
boolean visited = false;
|
|
127
|
+
for (int p : curr.path) {
|
|
128
|
+
if (p == v) { visited = true; break; }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (!visited && curr.matrix[u][v] < INF) {
|
|
132
|
+
double[][] childMat = new double[n][n];
|
|
133
|
+
for (int i = 0; i < n; i++) {
|
|
134
|
+
System.arraycopy(curr.matrix[i], 0, childMat[i], 0, n);
|
|
135
|
+
}
|
|
136
|
+
double edgeVal = curr.matrix[u][v];
|
|
137
|
+
|
|
138
|
+
for (int j = 0; j < n; j++) childMat[u][j] = INF;
|
|
139
|
+
for (int i = 0; i < n; i++) childMat[i][v] = INF;
|
|
140
|
+
if (curr.level < n - 1) {
|
|
141
|
+
childMat[v][0] = INF;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
double reduction = reduceMatrix(childMat, n);
|
|
145
|
+
double childCost = curr.cost + edgeVal + reduction;
|
|
146
|
+
|
|
147
|
+
if (childCost < bestCost) {
|
|
148
|
+
int[] childPath = Arrays.copyOf(curr.path, curr.path.length + 1);
|
|
149
|
+
childPath[childPath.length - 1] = v;
|
|
150
|
+
pq.add(new Node(childMat, childPath, curr.level + 1, childCost, v));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
System.out.printf("%nTotal Drill Head Travel Distance : %.2f mm%n", bestCost);
|
|
157
|
+
System.out.print("Optimal Drilling Toolpath Sequence : ");
|
|
158
|
+
if (bestTour != null) {
|
|
159
|
+
for (int i = 0; i <= n; i++) {
|
|
160
|
+
System.out.print(holes[bestTour[i]].label);
|
|
161
|
+
if (i < n) System.out.print(" -> ");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
System.out.println();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Driver code
|
|
168
|
+
public static void main(String args[]) {
|
|
169
|
+
System.out.println("=======================================================================");
|
|
170
|
+
System.out.println("PS 24: CircuitPro PCB CNC Drilling - LC Branch & Bound (Java)");
|
|
171
|
+
System.out.println("=======================================================================");
|
|
172
|
+
|
|
173
|
+
Hole holes[] = {
|
|
174
|
+
new Hole(0.0, 0.0, "Home (0,0)"),
|
|
175
|
+
new Hole(10.0, 45.0, "Hole-1 (10,45)"),
|
|
176
|
+
new Hole(25.0, 80.0, "Hole-2 (25,80)"),
|
|
177
|
+
new Hole(60.0, 75.0, "Hole-3 (60,75)"),
|
|
178
|
+
new Hole(85.0, 30.0, "Hole-4 (85,30)"),
|
|
179
|
+
new Hole(40.0, 10.0, "Hole-5 (40,10)")
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
int n = holes.length;
|
|
183
|
+
double costMatrix[][] = new double[n][n];
|
|
184
|
+
|
|
185
|
+
for (int i = 0; i < n; i++) {
|
|
186
|
+
for (int j = 0; j < n; j++) {
|
|
187
|
+
if (i == j) {
|
|
188
|
+
costMatrix[i][j] = INF;
|
|
189
|
+
} else {
|
|
190
|
+
costMatrix[i][j] = Math.hypot(holes[i].x - holes[j].x, holes[i].y - holes[j].y);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
solveLCBB_TSP(costMatrix, holes);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
PATH = Path(__file__).resolve().parent
|
|
7
|
+
DIR = PATH
|
|
8
|
+
JAVA_SOLUTION = PATH / "Solution.java"
|
|
9
|
+
DATASET_PATH = PATH / "dataset.csv"
|
|
10
|
+
TITLE = "LC - Drilling"
|
|
11
|
+
|
|
12
|
+
def get_code() -> str:
|
|
13
|
+
if JAVA_SOLUTION.exists():
|
|
14
|
+
return JAVA_SOLUTION.read_text(encoding="utf-8")
|
|
15
|
+
return ""
|
|
16
|
+
|
|
17
|
+
def extract(destination: Optional[str | Path] = None, overwrite: bool = True) -> Path:
|
|
18
|
+
from dancealgorithm.downloader import extract_bundled
|
|
19
|
+
from dancealgorithm.config import get_destination
|
|
20
|
+
target = Path(destination) if destination else get_destination()
|
|
21
|
+
extract_bundled(target, subject_filter=TITLE, overwrite=overwrite)
|
|
22
|
+
return target / PATH.name
|
|
23
|
+
|
|
24
|
+
def open_folder() -> None:
|
|
25
|
+
import os
|
|
26
|
+
if sys.platform == "win32":
|
|
27
|
+
os.system(f'explorer "{PATH}"')
|
|
28
|
+
|
|
29
|
+
def __getattr__(name: str):
|
|
30
|
+
if name in ("code", "java_code", "solution_code"):
|
|
31
|
+
return get_code()
|
|
32
|
+
if name in ("path", "folder", "dir"):
|
|
33
|
+
return PATH
|
|
34
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import java.util.Arrays;
|
|
2
|
+
import java.util.PriorityQueue;
|
|
3
|
+
|
|
4
|
+
// Main solution
|
|
5
|
+
public class Solution {
|
|
6
|
+
// O(n! * n^2)
|
|
7
|
+
static final double INF = 1e9;
|
|
8
|
+
|
|
9
|
+
// Search node
|
|
10
|
+
static class Node implements Comparable<Node> {
|
|
11
|
+
double[][] matrix;
|
|
12
|
+
int[] path;
|
|
13
|
+
int level;
|
|
14
|
+
double cost;
|
|
15
|
+
int city;
|
|
16
|
+
|
|
17
|
+
Node(double[][] mat, int[] path, int level, double cost, int city) {
|
|
18
|
+
int n = mat.length;
|
|
19
|
+
this.matrix = new double[n][n];
|
|
20
|
+
for (int i = 0; i < n; i++) {
|
|
21
|
+
System.arraycopy(mat[i], 0, this.matrix[i], 0, n);
|
|
22
|
+
}
|
|
23
|
+
this.path = Arrays.copyOf(path, path.length);
|
|
24
|
+
this.level = level;
|
|
25
|
+
this.cost = cost;
|
|
26
|
+
this.city = city;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
public int compareTo(Node other) {
|
|
31
|
+
return Double.compare(this.cost, other.cost);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Matrix reduction
|
|
36
|
+
public static double reduceMatrix(double[][] mat, int n) {
|
|
37
|
+
double reduction = 0;
|
|
38
|
+
|
|
39
|
+
for (int i = 0; i < n; i++) {
|
|
40
|
+
double rmin = INF;
|
|
41
|
+
for (int j = 0; j < n; j++) {
|
|
42
|
+
if (mat[i][j] < rmin) rmin = mat[i][j];
|
|
43
|
+
}
|
|
44
|
+
if (rmin > 0 && rmin < INF) {
|
|
45
|
+
reduction += rmin;
|
|
46
|
+
for (int j = 0; j < n; j++) {
|
|
47
|
+
if (mat[i][j] < INF) mat[i][j] -= rmin;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (int j = 0; j < n; j++) {
|
|
53
|
+
double cmin = INF;
|
|
54
|
+
for (int i = 0; i < n; i++) {
|
|
55
|
+
if (mat[i][j] < cmin) cmin = mat[i][j];
|
|
56
|
+
}
|
|
57
|
+
if (cmin > 0 && cmin < INF) {
|
|
58
|
+
reduction += cmin;
|
|
59
|
+
for (int i = 0; i < n; i++) {
|
|
60
|
+
if (mat[i][j] < INF) mat[i][j] -= cmin;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return reduction;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Branch and bound TSP
|
|
69
|
+
public static void solveLCBB_TSP(double[][] costMatrix, String[] airports) {
|
|
70
|
+
int n = costMatrix.length;
|
|
71
|
+
|
|
72
|
+
double[][] initialMat = new double[n][n];
|
|
73
|
+
for (int i = 0; i < n; i++) {
|
|
74
|
+
System.arraycopy(costMatrix[i], 0, initialMat[i], 0, n);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
double rootCost = reduceMatrix(initialMat, n);
|
|
78
|
+
|
|
79
|
+
PriorityQueue<Node> pq = new PriorityQueue<>();
|
|
80
|
+
int[] rootPath = {0};
|
|
81
|
+
pq.add(new Node(initialMat, rootPath, 1, rootCost, 0));
|
|
82
|
+
|
|
83
|
+
double bestCost = INF;
|
|
84
|
+
int[] bestTour = null;
|
|
85
|
+
|
|
86
|
+
while (!pq.isEmpty()) {
|
|
87
|
+
Node curr = pq.poll();
|
|
88
|
+
|
|
89
|
+
if (curr.cost >= bestCost) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (curr.level == n) {
|
|
94
|
+
int lastCity = curr.city;
|
|
95
|
+
if (costMatrix[lastCity][0] < INF) {
|
|
96
|
+
double tourCost = 0;
|
|
97
|
+
for (int i = 0; i < n - 1; i++) {
|
|
98
|
+
tourCost += costMatrix[curr.path[i]][curr.path[i + 1]];
|
|
99
|
+
}
|
|
100
|
+
tourCost += costMatrix[lastCity][0];
|
|
101
|
+
|
|
102
|
+
if (tourCost < bestCost) {
|
|
103
|
+
bestCost = tourCost;
|
|
104
|
+
bestTour = new int[n + 1];
|
|
105
|
+
System.arraycopy(curr.path, 0, bestTour, 0, n);
|
|
106
|
+
bestTour[n] = 0;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
int u = curr.city;
|
|
113
|
+
|
|
114
|
+
for (int v = 0; v < n; v++) {
|
|
115
|
+
boolean visited = false;
|
|
116
|
+
for (int p : curr.path) {
|
|
117
|
+
if (p == v) { visited = true; break; }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!visited && curr.matrix[u][v] < INF) {
|
|
121
|
+
double[][] childMat = new double[n][n];
|
|
122
|
+
for (int i = 0; i < n; i++) {
|
|
123
|
+
System.arraycopy(curr.matrix[i], 0, childMat[i], 0, n);
|
|
124
|
+
}
|
|
125
|
+
double edgeVal = curr.matrix[u][v];
|
|
126
|
+
|
|
127
|
+
for (int j = 0; j < n; j++) childMat[u][j] = INF;
|
|
128
|
+
for (int i = 0; i < n; i++) childMat[i][v] = INF;
|
|
129
|
+
if (curr.level < n - 1) {
|
|
130
|
+
childMat[v][0] = INF;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
double reduction = reduceMatrix(childMat, n);
|
|
134
|
+
double childCost = curr.cost + edgeVal + reduction;
|
|
135
|
+
|
|
136
|
+
if (childCost < bestCost) {
|
|
137
|
+
int[] childPath = Arrays.copyOf(curr.path, curr.path.length + 1);
|
|
138
|
+
childPath[childPath.length - 1] = v;
|
|
139
|
+
pq.add(new Node(childMat, childPath, curr.level + 1, childCost, v));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
System.out.printf("%nTotal Operational Aircraft Fuel & Gate Cost: Rs. %.2f (Lakhs)%n", bestCost);
|
|
146
|
+
System.out.print("Optimal Aircraft Tour Circuit : ");
|
|
147
|
+
if (bestTour != null) {
|
|
148
|
+
for (int i = 0; i <= n; i++) {
|
|
149
|
+
System.out.print(airports[bestTour[i]]);
|
|
150
|
+
if (i < n) System.out.print(" -> ");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
System.out.println();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Driver code
|
|
157
|
+
public static void main(String args[]) {
|
|
158
|
+
System.out.println("=======================================================================");
|
|
159
|
+
System.out.println("PS 23: AeroConnect Aircraft Circuit Tour - LC Branch & Bound (Java)");
|
|
160
|
+
System.out.println("=======================================================================");
|
|
161
|
+
|
|
162
|
+
String airports[] = {
|
|
163
|
+
"Delhi (DL)",
|
|
164
|
+
"Mumbai (MH)",
|
|
165
|
+
"Pune (MH)",
|
|
166
|
+
"Ahmedabad (GJ)",
|
|
167
|
+
"Bengaluru (KA)"
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
double costMatrix[][] = {
|
|
171
|
+
{INF, 12, 29, 45, 38},
|
|
172
|
+
{14, INF, 19, 36, 42},
|
|
173
|
+
{30, 21, INF, 18, 55},
|
|
174
|
+
{48, 38, 17, INF, 50},
|
|
175
|
+
{39, 40, 52, 49, INF}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
solveLCBB_TSP(costMatrix, airports);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
PATH = Path(__file__).resolve().parent
|
|
7
|
+
DIR = PATH
|
|
8
|
+
JAVA_SOLUTION = PATH / "Solution.java"
|
|
9
|
+
DATASET_PATH = PATH / "dataset.csv"
|
|
10
|
+
TITLE = "LC - Flight"
|
|
11
|
+
|
|
12
|
+
def get_code() -> str:
|
|
13
|
+
if JAVA_SOLUTION.exists():
|
|
14
|
+
return JAVA_SOLUTION.read_text(encoding="utf-8")
|
|
15
|
+
return ""
|
|
16
|
+
|
|
17
|
+
def extract(destination: Optional[str | Path] = None, overwrite: bool = True) -> Path:
|
|
18
|
+
from dancealgorithm.downloader import extract_bundled
|
|
19
|
+
from dancealgorithm.config import get_destination
|
|
20
|
+
target = Path(destination) if destination else get_destination()
|
|
21
|
+
extract_bundled(target, subject_filter=TITLE, overwrite=overwrite)
|
|
22
|
+
return target / PATH.name
|
|
23
|
+
|
|
24
|
+
def open_folder() -> None:
|
|
25
|
+
import os
|
|
26
|
+
if sys.platform == "win32":
|
|
27
|
+
os.system(f'explorer "{PATH}"')
|
|
28
|
+
|
|
29
|
+
def __getattr__(name: str):
|
|
30
|
+
if name in ("code", "java_code", "solution_code"):
|
|
31
|
+
return get_code()
|
|
32
|
+
if name in ("path", "folder", "dir"):
|
|
33
|
+
return PATH
|
|
34
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
==================================================
|
|
2
|
+
8. TSP – LEAST COST BRANCH AND BOUND
|
|
3
|
+
==================================================
|
|
4
|
+
|
|
5
|
+
ALGORITHM:
|
|
6
|
+
1. Create the cost matrix and mark unavailable edges as INF.
|
|
7
|
+
2. Perform row and column reduction.
|
|
8
|
+
3. Calculate the initial lower bound.
|
|
9
|
+
4. Insert the root node into a min-priority queue.
|
|
10
|
+
5. Remove the node with minimum cost.
|
|
11
|
+
6. Generate child nodes for unvisited cities.
|
|
12
|
+
7. Set visited row and column values to INF.
|
|
13
|
+
8. Reduce the child matrix and calculate its lower bound.
|
|
14
|
+
9. Prune nodes that cannot improve the best tour.
|
|
15
|
+
10. When all cities are visited, add the return cost.
|
|
16
|
+
11. Display the minimum-cost tour.
|
|
17
|
+
|
|
18
|
+
FORMULA:
|
|
19
|
+
Child Cost = Parent Cost + Edge Cost + Reduction
|
|
20
|
+
|
|
21
|
+
RECURRENCE:
|
|
22
|
+
No standard recurrence. Uses state-space tree search.
|
|
23
|
+
|
|
24
|
+
TIME COMPLEXITY:
|
|
25
|
+
Best Case : Depends on pruning.
|
|
26
|
+
Average Case : Input-dependent.
|
|
27
|
+
Worst Case : O(n! * n^2)
|
|
28
|
+
Space : O(n! * n^2)
|
|
29
|
+
|
|
30
|
+
IMPORTANT:
|
|
31
|
+
1. LC Branch and Bound uses a priority queue and pruning.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
|
|
2
|
+
import java.util.*;
|
|
3
|
+
import java.io.*;
|
|
4
|
+
|
|
5
|
+
public class Solution {
|
|
6
|
+
// 1. Main Function
|
|
7
|
+
// Initially created the main function as the entry point.
|
|
8
|
+
|
|
9
|
+
public static void main(String A[]) {
|
|
10
|
+
int iSize = 0;
|
|
11
|
+
|
|
12
|
+
// 7. Main Logic
|
|
13
|
+
// Read the dataset, sort transactions and display results.
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
// 7.1 Count Number of Transactions
|
|
17
|
+
|
|
18
|
+
BufferedReader bobj = new BufferedReader(new FileReader("dataset.csv"));
|
|
19
|
+
|
|
20
|
+
bobj.readLine(); // Skip header
|
|
21
|
+
|
|
22
|
+
while (bobj.readLine() != null) {
|
|
23
|
+
iSize++;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
bobj.close();
|
|
27
|
+
|
|
28
|
+
// 7.2 Create Transaction Array
|
|
29
|
+
|
|
30
|
+
Transaction Arr[] = new Transaction[iSize];
|
|
31
|
+
|
|
32
|
+
// 7.3 Read Transaction Details
|
|
33
|
+
|
|
34
|
+
bobj = new BufferedReader(new FileReader("dataset.csv"));
|
|
35
|
+
|
|
36
|
+
bobj.readLine(); // Skip header
|
|
37
|
+
|
|
38
|
+
for (int iCnt = 0; iCnt < iSize; iCnt++) {
|
|
39
|
+
String sLine = bobj.readLine();
|
|
40
|
+
String sData[] = sLine.split(",", -1);
|
|
41
|
+
|
|
42
|
+
String sID = sData[0].trim().replace("\"", "");
|
|
43
|
+
String sName = sData[1].trim().replace("\"", "");
|
|
44
|
+
String sTimestamp = sData[3].trim().replace("\"", "");
|
|
45
|
+
|
|
46
|
+
Arr[iCnt] = new Transaction(sID, sName, sTimestamp);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
bobj.close();
|
|
50
|
+
|
|
51
|
+
System.out.println("Loaded " + iSize + " transactions.");
|
|
52
|
+
|
|
53
|
+
// 7.4 Call Merge Sort
|
|
54
|
+
|
|
55
|
+
MergeSort(Arr, 0, iSize - 1);
|
|
56
|
+
|
|
57
|
+
// 7.5 Display Top 10 Transactions
|
|
58
|
+
|
|
59
|
+
System.out.println("\nTransactions Sorted by Purchase Timestamp:");
|
|
60
|
+
|
|
61
|
+
DisplayTop10(Arr);
|
|
62
|
+
} catch (Exception e) {
|
|
63
|
+
System.out.println("Error: " + e.getMessage());
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 2. Transaction Entity
|
|
68
|
+
// Stores transaction ID, description and purchase timestamp.
|
|
69
|
+
|
|
70
|
+
static class Transaction {
|
|
71
|
+
String sTransactionID;
|
|
72
|
+
String sDescription;
|
|
73
|
+
String sTimestamp;
|
|
74
|
+
|
|
75
|
+
Transaction(String sTransactionID, String sDescription, String sTimestamp) {
|
|
76
|
+
this.sTransactionID = sTransactionID;
|
|
77
|
+
this.sDescription = sDescription;
|
|
78
|
+
this.sTimestamp = sTimestamp;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 3. Merge Function
|
|
83
|
+
// Combines two sorted subarrays into one sorted array.
|
|
84
|
+
|
|
85
|
+
public static void Merge(Transaction Arr[], int iStart, int iMid, int iEnd) {
|
|
86
|
+
int iSize1 = iMid - iStart + 1;
|
|
87
|
+
int iSize2 = iEnd - iMid;
|
|
88
|
+
|
|
89
|
+
Transaction LeftArr[] = new Transaction[iSize1];
|
|
90
|
+
Transaction RightArr[] = new Transaction[iSize2];
|
|
91
|
+
|
|
92
|
+
for (int iCnt = 0; iCnt < iSize1; iCnt++) {
|
|
93
|
+
LeftArr[iCnt] = Arr[iStart + iCnt];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (int iCnt = 0; iCnt < iSize2; iCnt++) {
|
|
97
|
+
RightArr[iCnt] = Arr[iMid + 1 + iCnt];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
int i = 0;
|
|
101
|
+
int j = 0;
|
|
102
|
+
int k = iStart;
|
|
103
|
+
|
|
104
|
+
while (i < iSize1 && j < iSize2) {
|
|
105
|
+
if (LeftArr[i].sTimestamp.compareTo(RightArr[j].sTimestamp) <= 0) {
|
|
106
|
+
Arr[k] = LeftArr[i];
|
|
107
|
+
i++;
|
|
108
|
+
} else {
|
|
109
|
+
Arr[k] = RightArr[j];
|
|
110
|
+
j++;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
k++;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
while (i < iSize1) {
|
|
117
|
+
Arr[k] = LeftArr[i];
|
|
118
|
+
i++;
|
|
119
|
+
k++;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
while (j < iSize2) {
|
|
123
|
+
Arr[k] = RightArr[j];
|
|
124
|
+
j++;
|
|
125
|
+
k++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 4. Merge Sort Function
|
|
130
|
+
// Recursively divides the array and sorts transactions.
|
|
131
|
+
|
|
132
|
+
public static void MergeSort(Transaction Arr[], int iStart, int iEnd) {
|
|
133
|
+
if (iStart < iEnd) {
|
|
134
|
+
int iMid = iStart + (iEnd - iStart) / 2;
|
|
135
|
+
|
|
136
|
+
MergeSort(Arr, iStart, iMid);
|
|
137
|
+
|
|
138
|
+
MergeSort(Arr, iMid + 1, iEnd);
|
|
139
|
+
|
|
140
|
+
Merge(Arr, iStart, iMid, iEnd);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 5. Display Function
|
|
145
|
+
// Displays the first 10 transactions after sorting.
|
|
146
|
+
|
|
147
|
+
public static void DisplayTop10(Transaction Arr[]) {
|
|
148
|
+
System.out.printf("%-15s %-35s %-25s%n",
|
|
149
|
+
"TX_ID", "DESCRIPTION", "TIMESTAMP");
|
|
150
|
+
|
|
151
|
+
System.out.println("--------------------------------------------------------------------------");
|
|
152
|
+
|
|
153
|
+
int iLimit = Math.min(Arr.length, 10);
|
|
154
|
+
|
|
155
|
+
for (int iCnt = 0; iCnt < iLimit; iCnt++) {
|
|
156
|
+
System.out.printf("%-15s %-35s %-25s%n",
|
|
157
|
+
Arr[iCnt].sTransactionID,
|
|
158
|
+
Arr[iCnt].sDescription,
|
|
159
|
+
Arr[iCnt].sTimestamp);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|