Solving the minimum cut problem for undirected graphs
research.google
research.google
The process repeats until all but two vertices have been merged; the smallest cut found in each iteration, by sum of weights of edges that need to be severed to separate the last vertex from the rest of the graph, induces a min-cut for the entire graph; since vertices have been merged together you will need to map from edges incident to the merged vertex back to edges incident to all vertices "contained" in that merged vertex.
The advantage of implementing maximum adjacency search is that it can also be used to traverse and count components of the resulting cut graph to verify it has indeed been partitioned in two.
Something like that anyway. It's been a little while.
[0] https://adventofcode.com/2023/day/25
[1] https://www.cs.dartmouth.edu/~ac/Teach/CS105-Winter05/Handou...
cutset = nx.minimum_edge_cut(G)
for e in cutset:
G.remove_edge(*e)
size1, size2 = map(len, nx.connected_components(G))
answer = size1 * size2At least it spit out the right answer after a while.
Here's another obvious solution:
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_edges(G, pos)
nx.draw_networkx_labels(G, pos, font_size=10, font_color="white")
plt.show()
Thankfully it was my fastest solution (after day 1). After 25 days, I wasn't in the mood of spending hours post-xmas dinner solving convoluted riddles.https://cseweb.ucsd.edu/classes/sp11/cse202-a/lecture8-final...
Max-Flow runs on directed graphs. These are undirected graphs.
I picked two random vertices and found the shortest path between them 3 times, cutting each vertex after each iteration. If after doing that I couldn't find a path between the two vertices then I had successfully partitioned the graph in two. Otherwise that meant I picked two vertices in the same partition and I reset the graph and randomly picked a different vertex.
Ended up being very quick to run, and easy to implement.
"Fiedler vector"[1] - Algebraic connectivity (without networkx): https://www.reddit.com/r/adventofcode/comments/18qbsxs/comme...
I also used networkx during the contest to solve and visualize[2] but it was good to learn the Linear Algebra approach also afterwards from the Reddit solution thread.
[1] https://en.wikipedia.org/wiki/Algebraic_connectivity?useskin... [2] https://github.com/vismit2000/compCode-II/blob/master/Advent...
I think the point is: there are different sites intended for different devices, and you should get the one that matches yours (with a reasonable way to override it, of course).
obviously it should do the same in the other direction
For that reason I wouldn't call it amazing though it is an interesting algorithm.
Is there any link to how the algorithm actually works, rather than why? (i.e. can I see some code somewhere).
I read the article, and skimmed the paper, but didn't immediately see it.
ok, I went back and reskimmed the paper, turns out "algorithm A1" is in the appendices, I guess that's it? I haven't dug into it much yet. Can anyone confirm? (And can anyone link to an equivalent written in an actual programming language, which I'd find easier to parse)
Maximum cut at one point was an important concept in IIT which is a somewhat debunked but still interesting theory of consciousness
Really not bad for "just guess".
Specifically, there are algorithms that guarantee to solve every min-cut problem instance in time polynomial in the size of the problem (CS theorists call such algorithms "efficient"), while max-cut is an NP-complete problem. All NP-complete problems are "as hard as each other", and while no one has yet proven that they all take exponential time to solve, the brightest minds in CS have been searching for a faster algorithm for 40 years without success so far. Most people take that lack of progress as evidence that these problems really are hard.
The most famous NP-complete problem is probably the Travelling Salesman Problem. Another interesting one (because it seems like it "shouldn't be that hard") is Partition: Given a set of integers, can you partition them into two halves with equal sum?
You sample edges, and it's supposed to always happen to include the relevant min cut edges? How?
Unless you're asking about the randomized graph sparsification of Benzur and Karger, in which case the output is correct with high probability [0], but like with many randomized algorithms, is not guaranteed to be correct.
The random sampling technique of Benzur and Karger approximately preserves the total weights of all cuts in the graph, up to certain error bounds (with high probability). That is, if you draw a particular cut through the graph, the original version might have 100 edges crossing the cut, and the sparse graph might have 3 edges crossing the cut with a total weight of 102. Since all cut sizes are approximately preserved, you can get an approximate answer to the min cut in the original graph by solving the same problem on the sparse graph.
The deterministic, exact approach is a lot more complicated. In this case, we're not trying to preserve all cut weights, just the weights of minimum cuts. If you imagine a graph that consists of some dense "clusters" connected by other sparse "bottlenecks", then a minimum cut must go through the bottlenecks while avoiding the clusters.
So hand-waving the details, if you could exactly partition the graph into dense clusters, you could just collapse each cluster into a single vertex, and then easily solve the min-cut problem on the graph of clusters instead of the original graph. This partitioning is hard to do exactly. But if you start by doing it approximately, then you can bound the number of "adjustments" that need to be made in order to make the partitioning work.