Describe Algorithm that Decides Whether There are Exactly 2 Different MSTs - graph-algorithm

Let G = (V, E) be a weighted, connected and undirected graph. Describe an efficient algorithm that decides whether there are exactly 2 different MSTs in G.
The previous question which I already solved was a lot easier:
Describe an efficient algorithm that decides whether there is exactly one MST in G.
This is how I solved the latter question:
We run Kruskal algorithm and then color the edges of the new MST in blue and the rest of the edges in red.
Then I used another simple algorithm that we've seen (that uses Kruskal) that find a MST in a graph that contains a maximum number of red edges - which means that it's a MST in the graph G regardless of the edges' color, and every other MST cannot contain more red edges then the MST the algorithm finds.
Now there is exactly one MST iff the algorithm found the same MST (that contains all the blue edges).
The other question here seems a lot more complicated. I've tried using the algorithm described above and also tried to use various other tricks but neither has worked.
By the way, I've heard that there is an algorithm that counts the number of different MSTs in a graph, but it really is an overkill - and I was asked to provide a simple algorithm.
I would appreciate any help,
Thanks

I might be underthinking it but your approach seems needlessly complicated. To determine if there were 2 different MSTs I would start by running Kruskal to get the first MST. Then you just run it again and see if you could avoid taking an edge from the first MST.
In each step of Kruskal, you add the cheapest edge that connects 2 previously unconnected components. So you have to sort the edges by weight and run through them, adding them to the MST if they connect 2 unconnected components. When there are multiple MSTs you will reach a point where you get to choose between 2 edges of the same weight that both connect the same components.
When you have run Kruskal once, you know which edges are in your MST. If you run it a second time, you will again sort the edges by weight and add the cheapest edges (that connect 2 unconnected components) to your graph. However, if you get the choice to add 2 edges that connect the same components then you can take the edge you didn't take the first time. The end result will then be a different MST (does not contain the one edge) but a valid MST as you operated entirely according the rules of Kruskal.
You basically just do Kruskal but change your tie breaker for edges with the same weight. Iterate the procedure to find even more different MSTs. If you want to know if there're only 2 MST's you should try and find a third MST.

Related

Can I use Breadth-First-Search on weighted graphs if I modify it?

I am having a discussion with a friend if the following will work:
We recently learned in a lecture about Breadth-First-Search. I know that it is a special case of Dijkstra where each edge weight is set to one. Assume now we are given a graph where the edges have integer weights of more than one. Then I would modify this graph by introducing additional vertices and connecting them by edges with weight one, e.g. assume we have an edge of weight 3 connecting the vertices u and v, then I would introduce dummy-vertices d1, d2, remove the edge connecting u and v and instead add edges {u, d1}, {d1, d2}, {d2,v} of weight one.
If I modify my whole graph this way and then apply breadth-first search starting from one of the original vertices, wouldn't this work as well?
Thank you very much in advance!
Since BFS is guaranteed to return an optimal path on unweighted graphs, and you've created the unweighted equivalent of your original graph, you'll be guaranteed to get the shortest path.
What you lose by doing this over Dijkstra's algorithm is runtime optimality. Now the runtime of your algorithm is dependent on the edge weights, whereas Dijkstra's is only dependent on the number of edges.
This sort of thought experiment is a great way to understand how Dijkstra's algorithm works (eg. how would you modify your algorithm to not require creating a new graph? Or not take 100 steps for an edge with weight 100?). In fact this is probably how Dijkstra discovered the algorithm to begin with.

Reinforcement learning with hard constraints

The environment is a directed graph that consists of nodes which have their own "goodness"(marked green) and edges that have prices(marked red). In this environment exists Price(P) constraint. The goal is to accumulate the most "goodness" points from nodes, as possible while making a circle(for example 0-->6-->5-->0) and not exceeding price constraint..
I managed to implement Q-Learning algorithm when there are no constraints, but I don't fully understand how to add Hard Constrains, while approximating Q-Function.
For instance, starting point is 0. Price limit is 13. Taking path 0-->1-->2-->3-->4-->5-->0 wouldn't be a valid choice for Agent, because at node 5 price(13) limit was reached, therefore, Agent should be punished for violating constraints. However, taking path 0-->6-->5-->0 would be a correct choice for the Agent and therefore, he should be rewarded. What I do not understand, how to tell Agent that sometimes going from 5 to 0 is perfect choice and sometimes it is not applicable, because some constraints where violated. I tried to give huge penalty if price constraint was violated and ended episode immediately, but that didn't seem to workout.
My question(s):
How to add hard constraints to RL algorithms like Q-Learning?
Is Q-Learning a valid choice for that kind of problem?
Should other algorithms be chosen like Monte Carlo Tree Search
instead of Q-Learning.
I assume it is a very common problem in real world scenarios, but I couldn't find any examples about that.

choose cluster in hierarchical clustering

How can i choose a cluster if a point is at the same distance with two different points?
Here, X1 is at the same distance to X2 and X3. Can I directly make a cluster of X1/X2/X3 or just go one by one as X1/X2 and then X1/X2/X3?
In general you should always follow the rule of merging two if you want to have all the typical properties of the hierarchical clustering (like uniform meaning of each "slice through" - if you start merging many steps into one, you will have "unbalanced" structure, thus the height of the clustering tree will have different meanings in multiple places). Furthermore, it actually only makes sense for min linkage, if you use avg linkage or other, more complex rules, then it is not even true then after merging two points, the third one will be the next now to add (it might even end up in a different cluster). However, in general, clustering of this type (greedy) is just a heuristic, with some particular properties. Thus alternating it a bit gives you yet another clustering with some properties. Saying which one is "correct" is impossible - they are both wrong to some extent, what matters is your exact usage later on.

What parameters can I play with using mcl?

I am clustering undirected graphs using mcl. To do so, I have choose a threshold under which nodes are connected, a similarity measure for each edge and the inflation parameter to tune the granularity of my graph. I have been playing around with these parameters, but so far, the clusters I have seem to be too large (I did visualizations that suggest that the largest clusters should be cut into 2 or more clusters). Therefore, I was wondering what are the other parameters I can play with to improve my clustering (I am currently working with the scheme parameter of mcl to see whether increasing the accuracy would help, but if there are other 'more specific' parameters that could help to get smaller clusters for instance, please let me know)?
There are really mainly two things to consider. The first and most important is outside mcl (http://micans.org/mcl/) itself, namely how the network is constructed. I've written about it elsewhere, but I'll repeat it here because it is important.
If you have a weighted similarity, choose an edge-weight (similarity) cutoff
such that the topology of the network becomes informative; i.e. too many edges
or too few edges yield little discriminative information in the
absence/presence structure of edges. Choose it such that no edges connect
things you consider very dissimilar, and that edges connect things you consider
somewhat similar to quite similar. In the case of mcl, the dynamic range in
edge weight between 'a bit similar' and 'very similar' should be, as a rule of
a thumb, one order of magnitude, i.e. two-fold or five-fold or ten-fold, as
opposed to varying from 0.9 to 1.0. Of course, it is possible to give simple
networks to mcl and it will just utilise the absence/presence of edges. Make sure
the network does not become very dense - a very rough rule of thumb could be to aim
for a total number of edges that is in the order of V * sqrt(V) if the number of nodes (vertcies) is V, that is, each node has, on average, in the order of sqrt(V) neighbours.
The above, network construction, is really crucial, and it is advisable
to try different approaches. Now, given a network,
there is really only one mcl parameter to vary: the inflation parameter (the -I option).
A good set of values to test with is 1.4, 2, 3, 4, 6.
In summary, if you are exploring, try different ways of network construction,
using your knowledge of the data to make the network a meaningful representation,
and combine this with trying different mcl inflation values.

Determining groups in a hierarchical cluster

I have an algorithm that can group data into a hierarchical cluster tree. The algorithm is the one described in Toby Seagram's Programming Collective Intelligence. The tree output is a binary tree with a "distance" value at each node, that tells you how far apart the two child nodes are.
I can then display this as a Dendrogram and it makes it fairly easy for a human spot which values are grouped together. However I'm having difficult coming up with an algorithm that automatically decides what the groups should be. I'd like to be able to determine automatically:
The number of group
Which points should be placed in each group
Is there a standard algorithm for this?
I think there is no default way to do this. Simple 'manual' methods would be to either:
specify the number of clusters you want/expect
set a threshold for the maximum distance between two nodes; any nodes with a larger distance belong to another cluster
There are some automatic methods to determine the number of clusters. R has the Dynamic Tree Cut package which automatically deals with this problem, also pvclust could be used. Here are two more methods described to deal with this problem, Salvador (2002) and Daniels (2006).
I have found out that the Calinski-Harabasz index (also known as Variance Ratio Criterion) works well with dendrograms produced by hierarchical clustering. You can find more information (and a comparative study) in this paper.

Resources