Door placement

This commit is contained in:
2023-09-21 19:29:34 -07:00
parent 01e316d979
commit 354a114e1c
10 changed files with 239 additions and 19 deletions

View File

@ -0,0 +1,33 @@
import 'package:dartterm/algorithms/union_find.dart';
class Edge<T> {
final int src, dst;
final T value;
final double score; // higher score is better
const Edge(this.src, this.dst, this.value, this.score);
}
List<Edge<T>> kruskal<T>(int nRegions, List<Edge<T>> srcEdges) {
var edges = List.from(srcEdges); // copy so we can mutate it
edges.sort((e0, e1) => -e0.score.compareTo(e1.score));
List<Edge<T>> spanningEdges = [];
var connected = UnionFind(nRegions);
for (var i = 0; i < edges.length; i++) {
var edge = edges[i];
if (connected.find(edge.src) == connected.find(edge.dst)) {
continue;
}
spanningEdges.add(edge);
connected.union(edge.src, edge.dst);
// break early if we run out of regions
nRegions -= 1;
if (nRegions == 1) {
break;
}
}
return spanningEdges;
}

View File

@ -26,7 +26,8 @@ class Region {
}
}
List<Region> regionalize(geo.Rect rect, bool Function(int, int) isAccessible) {
(List<Region>, Map<(int, int), int>) regionalize(
geo.Rect rect, bool Function(int, int) isAccessible) {
int nextRegion = 0;
Map<(int, int), int> regions = {};
@ -62,7 +63,7 @@ List<Region> regionalize(geo.Rect rect, bool Function(int, int) isAccessible) {
}
}
}
return _toExplicit(regions, nextRegion);
return (_toExplicit(regions, nextRegion), regions);
}
List<Region> _toExplicit(Map<(int, int), int> pointRegions, int nRegions) {

View File

@ -0,0 +1,78 @@
// Copyright (c) 2012, scribeGriff (Richard Griffith)
// https://github.com/scribeGriff/graphlab
// All rights reserved. Please see the LICENSE.md file.
//
// Converted to modern Dart by Pyrex Panjakar.
/// A disjoint sets ADT implemented with a Union-Find data structure.
///
/// Performs union-by-rank and path compression. Elements are represented
/// by ints, numbered from zero.
///
/// Each disjoint set has one element designated as its root.
/// Negative values indicate the element is the root of a set. The absolute
/// value of a negative value is the number of elements in the set.
/// Positive values are an index to where the root was last known to be.
/// If the set has been unioned with another, the last known root will point
/// to a more recent root.
///
/// var a = new UnionFind(myGraph.length);
///
/// var u = a.find(myGraph[i][0]);
/// var v = a.find(myGraph[i][1]);
/// a.union(u, v);
///
/// Reference: Direct port of Mark Allen Weiss' UnionFind.java
class UnionFind {
late final List<int> array;
/// Construct a disjoint sets object.
///
/// numElements is the initial number of elements--also the initial
/// number of disjoint sets, since every element is initially in its
/// own set.
UnionFind(int numElements) {
// The array is zero based but the vertices are 1 based,
// so we extend the array by 1 element to account for this.
array = [for (var i = 0; i < numElements; i++) -1];
}
/// union() unites two disjoint sets into a single set. A union-by-rank
/// heuristic is used to choose the new root.
///
/// a is an element in the first set.
/// b is an element in the first set.
void union(int a, int b) {
int rootA = find(a);
int rootB = find(b);
if (rootA == rootB) return;
if (array[rootB] < array[rootA]) {
// root_b has more elements, so leave it as the root.
// first, indicate that the set represented by root_b has grown.
array[rootB] += array[rootA];
// Then, point the root of set a at set b.
array[rootA] = rootB;
} else {
array[rootA] += array[rootB];
array[rootB] = rootA;
}
}
/// find() finds the (int) name of the set containing a given element.
/// Performs path compression along the way.
///
/// x is the element sought.
/// returns the set containing x.
int find(int x) {
if (array[x] < 0) {
return x; // x is the root of the tree; return it
} else {
// Find out who the root is; compress path by making the root
// x's parent.
array[x] = find(array[x]);
return array[x]; // Return the root
}
}
}