carbon225 commited on
Commit
e9caa70
·
1 Parent(s): 16a0de1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -0
app.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import graphviz
3
+ import random
4
+ import gurobipy as gp
5
+ from gurobipy import GRB
6
+
7
+
8
+ def generate_random_graph(V: int, density: float) -> tuple[int, list[tuple[int, int]]]:
9
+ E = [(u, v) for u in range(V - 1) for v in range(u + 1, V)]
10
+ random.shuffle(E)
11
+ E = E[:int(density * V * (V - 1) / 2)]
12
+ return V, E
13
+
14
+
15
+ def solve_matching(V: int, E: list[tuple[int, int]]) -> list[tuple[int, int]]:
16
+ m = gp.Model()
17
+ x = m.addVars(E, vtype=GRB.BINARY)
18
+
19
+ m.setObjective(x.sum(), GRB.MAXIMIZE)
20
+ m.addConstrs(x.sum(u, '*') + x.sum('*', u) <= 1 for u in range(V))
21
+
22
+ m.optimize()
23
+
24
+ matching = []
25
+ for e in E:
26
+ if x[e].x > 0.5:
27
+ matching.append(e)
28
+
29
+ return matching
30
+
31
+
32
+ def main():
33
+ V = st.number_input('Number of vertices', min_value=1, value=10)
34
+ density = st.slider('Density', min_value=0.0, max_value=1.0, value=0.5)
35
+ st.button('Generate')
36
+
37
+ V, E = generate_random_graph(V, density)
38
+
39
+ if len(E) > 40:
40
+ st.warning('Too many edges to display')
41
+ return
42
+
43
+ M = set(solve_matching(V, E))
44
+
45
+ if len(M) == V // 2:
46
+ st.success('Perfect matching found')
47
+ else:
48
+ st.metric('Matching size', len(M))
49
+
50
+ G = graphviz.Graph()
51
+ for u, v in E:
52
+ if (u, v) in M:
53
+ G.edge(str(u), str(v), color='red')
54
+ else:
55
+ G.edge(str(u), str(v), color='gray', style='dashed')
56
+
57
+ st.graphviz_chart(G)
58
+
59
+
60
+ if __name__ == '__main__':
61
+ main()