justin7891's picture
Update app.py
94696b0 verified
import streamlit as st
from pyvis.network import Network
import networkx as nx
import random
import streamlit.components.v1 as components
st.title('ํŒŒํŠธ๋„ˆ ๋งค์นญ ํ”„๋กœ๊ทธ๋žจ')
st.write('์ด๋ฆ„์„ ํ•œ ์ค„์— ํ•˜๋‚˜์”ฉ ์ž…๋ ฅํ•˜์„ธ์š”.')
names_input = st.text_area('์ด๋ฆ„ ๋ชฉ๋ก', height=200)
if st.button('ํŒŒํŠธ๋„ˆ ๋งค์นญํ•˜๊ธฐ'):
names = [name.strip() for name in names_input.strip().split('\n') if name.strip()]
if len(names) < 2:
st.error('๋งค์นญํ•  ์ด๋ฆ„์ด 2๊ฐœ ์ด์ƒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.')
else:
random.shuffle(names)
mid = len(names) // 2
group_A = names[:mid]
group_B = names[mid:]
# ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ
G = nx.Graph()
G.add_nodes_from(group_A, bipartite=0)
G.add_nodes_from(group_B, bipartite=1)
# ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ๊ฐ„์„  ์ถ”๊ฐ€
for a in group_A:
for b in group_B:
G.add_edge(a, b)
# ๋งค์นญ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‹คํ–‰ (์ตœ๋Œ€ ๋งค์นญ)
mate = nx.algorithms.bipartite.maximum_matching(G, top_nodes=group_A)
# ๋งค์นญ ๊ฒฐ๊ณผ๋งŒ์œผ๋กœ ์ƒˆ๋กœ์šด ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ
matching_edges = [(u, v) for u, v in mate.items() if u in group_A]
# pyvis ๋„คํŠธ์›Œํฌ ์ƒ์„ฑ
net = Network(height='600px', width='100%', bgcolor='#222222', font_color='white')
# ๋…ธ๋“œ ์ถ”๊ฐ€
for node in G.nodes():
net.add_node(node, label=node, title=node)
# ๋งค์นญ๋œ ๊ฐ„์„ ์€ ๊ฐ•์กฐํ•˜์—ฌ ์ถ”๊ฐ€
for edge in matching_edges:
net.add_edge(edge[0], edge[1], color='red', width=3)
# ๋„คํŠธ์›Œํฌ ์„ค์ •
net.toggle_physics(True)
# HTML ์ฝ”๋“œ ์ƒ์„ฑ
net_html = net.generate_html()
# Streamlit์— ํ‘œ์‹œ
components.html(net_html, height=600)
# ๋งค์นญ ๊ฒฐ๊ณผ ์ถœ๋ ฅ
st.subheader('๋งค์นญ ๊ฒฐ๊ณผ:')
for u, v in matching_edges:
st.write(f'{u} - {v}')
unmatched = set(names) - set(mate.keys()) - set(mate.values())
if unmatched:
st.write('๋งค์นญ๋˜์ง€ ์•Š์€ ์‚ฌ๋žŒ:')
for name in unmatched:
st.write(name)