@softsky/utils 2.7.0 → 2.7.2
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.
- package/README.md +14 -3
- package/dist/arrays.d.ts +2 -0
- package/dist/arrays.js +11 -0
- package/dist/control.d.ts +4 -0
- package/dist/control.js +18 -0
- package/dist/graphs.d.ts +5 -10
- package/dist/graphs.js +55 -15
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -84,6 +84,9 @@ Only deletes last encountered.
|
|
|
84
84
|
|
|
85
85
|
Returns index of deleted value.
|
|
86
86
|
|
|
87
|
+
---
|
|
88
|
+
__function__ `reverse` - Reverse part of array
|
|
89
|
+
|
|
87
90
|
---
|
|
88
91
|
|
|
89
92
|
|
|
@@ -201,6 +204,12 @@ semaphore.run(()=>{
|
|
|
201
204
|
---
|
|
202
205
|
__async function__ `withTimeout` - Add timeout to a promise
|
|
203
206
|
|
|
207
|
+
---
|
|
208
|
+
__function__ `promisify` - Promisify a function with callback
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
__function__ `promisifyEventSource` - Create a promise out of EventSource
|
|
212
|
+
|
|
204
213
|
---
|
|
205
214
|
|
|
206
215
|
|
|
@@ -295,14 +304,16 @@ You can use `unfoldPathfindingResult()` to get array of nodes.
|
|
|
295
304
|
__function__ `knapsack` - Knapsack find best way to get maximum value in limited capacity
|
|
296
305
|
|
|
297
306
|
---
|
|
298
|
-
__function__ `
|
|
307
|
+
__function__ `hamiltonianCycle` - Find min path between points. You need to supply 2-dim array
|
|
299
308
|
where first index is a point and second index is a distance from this point to another.
|
|
300
309
|
Put infinity if where are no path. Returns cycle (start and end at the same point)
|
|
301
310
|
Original: https://github.com/qntm/held-karp
|
|
302
311
|
|
|
303
312
|
---
|
|
304
|
-
__function__ `
|
|
305
|
-
|
|
313
|
+
__function__ `traverseByNearestNeighbor` - Traverse all points by nearest neighbor. Should be able to go from any point to any other point.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
__function__ `twoOpt` - 2-opt improvement
|
|
306
317
|
|
|
307
318
|
---
|
|
308
319
|
|
package/dist/arrays.d.ts
CHANGED
|
@@ -48,3 +48,5 @@ export declare function removeFromArray<T>(array: T[], value: T): number;
|
|
|
48
48
|
* Returns index of deleted value.
|
|
49
49
|
*/
|
|
50
50
|
export declare function removeLastFromArray<T>(array: T[], value: T): number;
|
|
51
|
+
/** Reverse part of array */
|
|
52
|
+
export declare function reverse<T>(array: T[], start: number, end: number): T[];
|
package/dist/arrays.js
CHANGED
|
@@ -133,3 +133,14 @@ export function removeLastFromArray(array, value) {
|
|
|
133
133
|
array.splice(index, 1);
|
|
134
134
|
return index;
|
|
135
135
|
}
|
|
136
|
+
/** Reverse part of array */
|
|
137
|
+
export function reverse(array, start, end) {
|
|
138
|
+
array = [...array];
|
|
139
|
+
const n = ((end - start + 1) / 2) | 0;
|
|
140
|
+
for (let index = 0; index < n; index++) {
|
|
141
|
+
const temporary = array[start + index];
|
|
142
|
+
array[start + index] = array[end - index];
|
|
143
|
+
array[end - index] = temporary;
|
|
144
|
+
}
|
|
145
|
+
return array;
|
|
146
|
+
}
|
package/dist/control.d.ts
CHANGED
|
@@ -123,4 +123,8 @@ export declare class Semaphore {
|
|
|
123
123
|
}
|
|
124
124
|
/** Add timeout to a promise */
|
|
125
125
|
export declare function withTimeout<T>(run: () => Promise<T>, ms: number): Promise<T>;
|
|
126
|
+
/** Promisify a function with callback */
|
|
127
|
+
export declare function promisify<A extends any[], R extends any[]>(handler: (...handlerArguments: [...A, (...results: R) => void]) => void): (...handlerArguments: A) => Promise<R extends [infer U] ? U : R>;
|
|
128
|
+
/** Create a promise out of EventSource */
|
|
129
|
+
export declare function promisifyEventSource<T = unknown>(target: EventSource, resolveEvents: string[], rejectEvents?: string[]): Promise<T>;
|
|
126
130
|
export {};
|
package/dist/control.js
CHANGED
|
@@ -288,3 +288,21 @@ export class Semaphore {
|
|
|
288
288
|
export async function withTimeout(run, ms) {
|
|
289
289
|
return Promise.race([run(), timeout(ms)]);
|
|
290
290
|
}
|
|
291
|
+
/** Promisify a function with callback */
|
|
292
|
+
export function promisify(handler) {
|
|
293
|
+
return (...handlerArguments) => new Promise((resolve) => {
|
|
294
|
+
handler(...handlerArguments, (...results) => {
|
|
295
|
+
resolve(results.length > 1 ? results : results[0]);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
/** Create a promise out of EventSource */
|
|
300
|
+
export function promisifyEventSource(target, resolveEvents, rejectEvents = ['error']) {
|
|
301
|
+
return new Promise((resolve, reject) => {
|
|
302
|
+
for (let index = 0; index < resolveEvents.length; index++)
|
|
303
|
+
// @ts-ignore
|
|
304
|
+
target.addEventListener(resolveEvents[index], resolve);
|
|
305
|
+
for (let index = 0; index < rejectEvents.length; index++)
|
|
306
|
+
target.addEventListener(rejectEvents[index], reject);
|
|
307
|
+
});
|
|
308
|
+
}
|
package/dist/graphs.d.ts
CHANGED
|
@@ -70,15 +70,10 @@ export declare function knapsack(weights: number[], values: number[], capacity:
|
|
|
70
70
|
* Put infinity if where are no path. Returns cycle (start and end at the same point)
|
|
71
71
|
* Original: https://github.com/qntm/held-karp
|
|
72
72
|
*/
|
|
73
|
-
export declare function
|
|
74
|
-
distance: number;
|
|
75
|
-
path: number[];
|
|
76
|
-
};
|
|
73
|
+
export declare function hamiltonianCycle(distribution: number[][]): number[];
|
|
77
74
|
/**
|
|
78
|
-
*
|
|
79
|
-
* Returns path without cycle
|
|
75
|
+
* Traverse all points by nearest neighbor. Should be able to go from any point to any other point.
|
|
80
76
|
*/
|
|
81
|
-
export declare function
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
};
|
|
77
|
+
export declare function traverseByNearestNeighbor(distribution: number[][]): number[];
|
|
78
|
+
/** 2-opt improvement */
|
|
79
|
+
export declare function twoOpt(tour: number[], distribution: number[][]): number[];
|
package/dist/graphs.js
CHANGED
|
@@ -137,10 +137,10 @@ export function knapsack(weights, values, capacity) {
|
|
|
137
137
|
* Put infinity if where are no path. Returns cycle (start and end at the same point)
|
|
138
138
|
* Original: https://github.com/qntm/held-karp
|
|
139
139
|
*/
|
|
140
|
-
export function
|
|
140
|
+
export function hamiltonianCycle(distribution) {
|
|
141
141
|
const n = distribution.length;
|
|
142
142
|
if (n === 1)
|
|
143
|
-
return
|
|
143
|
+
return [0, 0];
|
|
144
144
|
const all = (1 << (n - 1)) - 1;
|
|
145
145
|
const length = new Float64Array((1 << (n - 1)) * (n - 1));
|
|
146
146
|
const previous = new Uint8Array((1 << (n - 1)) * (n - 1));
|
|
@@ -198,20 +198,60 @@ export function tspHeldKarp(distribution) {
|
|
|
198
198
|
S = S2;
|
|
199
199
|
}
|
|
200
200
|
const index = cycle.indexOf(0);
|
|
201
|
-
return
|
|
202
|
-
distance: cycle.reduce((accumulator, u, index_, cycle) => accumulator +
|
|
203
|
-
distribution[u][cycle[index_ + 1 in cycle ? index_ + 1 : 0]], 0),
|
|
204
|
-
path: [...cycle.slice(index), ...cycle.slice(0, index), 0],
|
|
205
|
-
};
|
|
201
|
+
return [...cycle.slice(index), ...cycle.slice(0, index), 0];
|
|
206
202
|
}
|
|
207
203
|
/**
|
|
208
|
-
*
|
|
209
|
-
* Returns path without cycle
|
|
204
|
+
* Traverse all points by nearest neighbor. Should be able to go from any point to any other point.
|
|
210
205
|
*/
|
|
211
|
-
export function
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
206
|
+
export function traverseByNearestNeighbor(distribution) {
|
|
207
|
+
const n = distribution.length;
|
|
208
|
+
const toVisit = new Array(n).fill(true);
|
|
209
|
+
const path = [0];
|
|
210
|
+
let last = 0;
|
|
211
|
+
toVisit[0] = false;
|
|
212
|
+
for (let index = 1; index < n; index++) {
|
|
213
|
+
let nearest = -1;
|
|
214
|
+
let nearestDistribution = Infinity;
|
|
215
|
+
for (let index = 0; index < n; index++) {
|
|
216
|
+
if (toVisit[index] && distribution[last][index] < nearestDistribution) {
|
|
217
|
+
nearest = index;
|
|
218
|
+
nearestDistribution = distribution[last][index];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
path.push(nearest);
|
|
222
|
+
last = nearest;
|
|
223
|
+
toVisit[nearest] = false;
|
|
224
|
+
}
|
|
225
|
+
return path;
|
|
226
|
+
}
|
|
227
|
+
/** 2-opt improvement */
|
|
228
|
+
export function twoOpt(tour, distribution) {
|
|
229
|
+
let improved = true;
|
|
230
|
+
const nStart = tour.length - 2;
|
|
231
|
+
const nEnd = tour.length - 1;
|
|
232
|
+
while (improved) {
|
|
233
|
+
improved = false;
|
|
234
|
+
for (let start = 1; start < nStart; start++) {
|
|
235
|
+
for (let end = start + 1; end < nEnd; end++) {
|
|
236
|
+
const t0 = distribution[tour[start - 1]];
|
|
237
|
+
const t1 = tour[start];
|
|
238
|
+
const tk1 = tour[end];
|
|
239
|
+
const tk2 = tour[end + 1];
|
|
240
|
+
if (t0[tk1] +
|
|
241
|
+
distribution[t1][tk2] -
|
|
242
|
+
t0[t1] -
|
|
243
|
+
distribution[tk1][tk2] <
|
|
244
|
+
-1e-9) {
|
|
245
|
+
const n = ((end - start + 1) / 2) | 0;
|
|
246
|
+
for (let index = 0; index < n; index++) {
|
|
247
|
+
const temporary = tour[start + index];
|
|
248
|
+
tour[start + index] = tour[end - index];
|
|
249
|
+
tour[end - index] = temporary;
|
|
250
|
+
}
|
|
251
|
+
improved = true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return tour;
|
|
217
257
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softsky/utils",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "JavaScript/TypeScript utilities",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"homepage": "https://github.com/SoundOfTheSky/utils#readme",
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@softsky/configs": "^1.3.4",
|
|
24
|
-
"@types/bun": "^1.2.
|
|
24
|
+
"@types/bun": "^1.2.21"
|
|
25
25
|
},
|
|
26
26
|
"files": ["dist/**/*"]
|
|
27
27
|
}
|