Skip to content

Commit 79291c2

Browse files
authored
Merge pull request #6 from EMACC99/dev
Bipartite matchings
2 parents fcc5625 + fd3f64b commit 79291c2

File tree

5 files changed

+126
-9
lines changed

5 files changed

+126
-9
lines changed

algorithms/apareamientos.hpp

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#pragma once
2+
3+
#include <list>
4+
5+
#include "../includes/globals.hpp"
6+
#include "../includes/edge.hpp"
7+
#include "../includes/node.hpp"
8+
#include "componentes_conexas.hpp" // de aqui sacamos get vecinos
9+
10+
11+
std::vector<int> apareamientos_iniciales(){
12+
// lo mas facil de hacer, pues es agarrar un nodo y juntarlo con su vecino, revisando que no esten apareados anteriormente
13+
14+
std::vector<int> matches(vertices.size(), -1);
15+
for (auto &n : vertices){
16+
for (auto &h : get_vecinos(n)){
17+
if (matches[h] == -1 && matches[n.id] == -1){
18+
matches[h] = n.id;
19+
matches[n.id] = h;
20+
break;
21+
}
22+
}
23+
}
24+
return matches;
25+
}
26+
27+
28+
std::vector<int> bfs(const node &root, std::vector<int> &matches){
29+
std::vector <int> caminito_bfs;
30+
std::vector<bool> visited(vertices.size(), false);
31+
std::vector<int> queue;
32+
33+
visited[root.id] = true;
34+
35+
queue.push_back(root.id);
36+
while(!queue.empty()){
37+
int s = queue.front();
38+
caminito_bfs.push_back(s);
39+
queue.pop_back();
40+
for (auto &v : get_vecinos(vertices[s])){
41+
if (!visited[v] && matches[v] == -1)
42+
queue.push_back(v);
43+
}
44+
}
45+
// std::vector<int> matches(vertices.size(), 0);
46+
47+
// ahora necesito ver quien esta matcheado con quien
48+
// para eso, tengo dos opciones, generar un vector de aristas y decir que tienen match, mas facil, o
49+
// generar un vector de nodos que digan que esos dos estan mathcheados
50+
for (int i = 1; i < caminito_bfs.size(); i += 2){
51+
matches[caminito_bfs[i - 1]] = matches[caminito_bfs[i]];
52+
matches[caminito_bfs[i]] = matches[caminito_bfs[i - 1]];
53+
}
54+
55+
return matches;
56+
}
57+
58+
59+
node get_first_not_matched_node(std::vector<int> &matches){
60+
node not_matched;
61+
not_matched.id = -2; // if the id is -2 there no more matchings
62+
for (int i = 0; i < matches.size(); ++i){
63+
if (matches[i] == -1){
64+
not_matched = vertices[i];
65+
break;
66+
}
67+
}
68+
69+
return not_matched;
70+
}
71+
72+
std::vector<int> apareamientos(){
73+
// primero, tenemos que hacer los apareamientos iniciales
74+
std::vector<int> inital_matches = apareamientos_iniciales();
75+
std::vector<bool> visited(vertices.size(), false);
76+
77+
//ahora tenemos que sacar el nuevo camino de aumento con bfs
78+
// lo que le tenemos que pasar es un nodo que no este en initial_matches
79+
80+
node first_not_matches = get_first_not_matched_node(inital_matches);
81+
82+
if (first_not_matches.id == -2)
83+
return inital_matches;
84+
85+
std::vector<int> matches = bfs(first_not_matches, inital_matches);
86+
87+
while (matches != inital_matches){
88+
inital_matches = matches;
89+
node first_not_matches = get_first_not_matched_node(inital_matches);
90+
matches = bfs(first_not_matches, inital_matches);
91+
}
92+
93+
return matches;
94+
}

automated_setup.sh

100644100755
File mode changed.

includes/event_handler_class.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,18 @@ void event_handler::select_algorithms(const sf::Event &event, sf::RenderWindow &
115115
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Num8) || sf::Keyboard::isKeyPressed(sf::Keyboard::Numpad8)){ //TODO rewirite function for diffent types of LCA
116116
std::vector<int> parents = call_get_parents();
117117
if (!parents.empty()){
118-
node lca = call_lca_lite(parents);
118+
node lca = call_lca(parents);
119119
std::cout << "El LCA es " << lca.id << std::endl;
120120
make_sprite_red(sprites[lca.id]);
121121
}
122122
else
123123
std::cout << "Hay, un ciclo, no es arbol" << std::endl;
124124
}
125+
126+
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num9) || sf::Keyboard::isKeyPressed(sf::Keyboard::Numpad9)){
127+
std::vector<edge> matches = call_bipartite_matching();
128+
create_lineas_coloreadas(matches);
129+
}
125130
}
126131
/**
127132
* @brief handles the interactivity for the visualizer

includes/functions.hpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "../algorithms/prim3.hpp"
1212
#include "../algorithms/componentes_conexas.hpp"
1313
#include "../algorithms/LCA.hpp"
14+
#include "../algorithms/apareamientos.hpp"
1415

1516
#define MAX_WEIGHT 25;
1617
//fuciones de ayuda para dibujar y ser interactivos
@@ -127,7 +128,7 @@ void assign_random_weights_to_edge(){
127128
* @param mst Prim or Kruskal
128129
* @param color sf::Color
129130
*/
130-
void create_lineas_coloreadas(const std::vector<edge> &mst, const sf::Color &color ){ //move to visualizer
131+
void create_lineas_coloreadas(const std::vector<edge> &mst, const sf::Color &color = sf::Color::Red){ //move to visualizer
131132

132133
for (auto &elem: mst){
133134
lineas_coloreadas.push_back(sf::Vertex(sprites[elem.nodes[0]].getPosition()));
@@ -283,7 +284,7 @@ std::vector<int> call_get_parents(){
283284
return get_parents(vertices[root_index]);
284285
}
285286

286-
node call_lca_lite(const std::vector<int> &padres){
287+
node call_lca(const std::vector<int> &padres){
287288
int v_id,u_id;
288289
std::cout << "Id del primer nodo: ";
289290
std::cin >> v_id;
@@ -295,6 +296,23 @@ node call_lca_lite(const std::vector<int> &padres){
295296
return factor_deconposition(padres, u, v);
296297
}
297298

299+
std::vector<edge> call_bipartite_matching(){
300+
std::vector<int> matches = apareamientos();
301+
std::vector<edge> bipartite_edges;
302+
303+
int size = matches.size()/2;
304+
for (int i = 0; i < size; ++i){
305+
edge a;
306+
std::vector<int> nodes;
307+
nodes.push_back(i);
308+
nodes.push_back(matches[i]);
309+
a.nodes = nodes;
310+
a.colored = true;
311+
bipartite_edges.push_back(a);
312+
}
313+
return bipartite_edges;
314+
}
315+
298316
//dar parametros para el visualizador para dibujar cosas en lugares random
299317
/**
300318
* @brief displays the components in random positions on the canvas

makefile

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CC=g++
2-
CFLAGS=-c -Wall -Wpedantic -Wextra -Wno-sign-compare -std=c++17 -Ofast
2+
CFLAGS=-c -Wall -Wpedantic -Wextra -Wno-sign-compare -Wno-maybe-uninitialized -std=c++17 -Ofast
33
LDFLAGS=
44
LIBFLAGS=-lsfml-graphics -lsfml-window -lsfml-system
55
SOURCES=main.cpp
@@ -18,8 +18,8 @@ $(EXECUTABLE): $(OBJECTS)
1818
clean:
1919
rm *.o $(EXECUTABLE)
2020

21-
install:
22-
#install -s $(EXECUTABLE) $(BINDIR)
23-
sudo cp -u $(EXECUTABLE) $(BINDIR)
24-
uninstall:
25-
sudo rm $(BINDIR)/$(EXECUTABLE)
21+
# install:
22+
# #install -s $(EXECUTABLE) $(BINDIR)
23+
# sudo cp -u $(EXECUTABLE) $(BINDIR)
24+
# uninstall:
25+
# sudo rm $(BINDIR)/$(EXECUTABLE)

0 commit comments

Comments
 (0)