Skip to content

Commit 901b3b9

Browse files
committed
Minor integration changes.
1 parent 90fc31b commit 901b3b9

File tree

9 files changed

+662
-553
lines changed

9 files changed

+662
-553
lines changed

nbproject/project.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dist.jlink.output=${dist.jlink.dir}/jlibgraph
3737
endorsed.classpath=
3838
excludes=
3939
file.reference.slf4j-api-1.7.9.jar=lib/slf4j-api-1.7.9.jar
40+
file.reference.slf4j-simple-1.7.9.jar=lib\\slf4j-simple-1.7.9.jar
4041
includes=**
4142
jar.compress=false
4243
javac.classpath=\
@@ -53,7 +54,8 @@ javac.source=1.8
5354
javac.target=1.8
5455
javac.test.classpath=\
5556
${javac.classpath}:\
56-
${build.classes.dir}
57+
${build.classes.dir}:\
58+
${file.reference.slf4j-simple-1.7.9.jar}
5759
javac.test.modulepath=\
5860
${javac.modulepath}
5961
javac.test.processorpath=\
Lines changed: 190 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,190 @@
1-
/*
2-
* Copyright (C) 2022 Ananda.
3-
*
4-
* This library is free software; you can redistribute it and/or
5-
* modify it under the terms of the GNU Lesser General Public
6-
* License as published by the Free Software Foundation; either
7-
* version 2.1 of the License, or (at your option) any later version.
8-
*
9-
* This library is distributed in the hope that it will be useful,
10-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12-
* Lesser General Public License for more details.
13-
*
14-
* You should have received a copy of the GNU Lesser General Public
15-
* License along with this library; if not, write to the Free Software
16-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17-
* MA 02110-1301 USA
18-
*/
19-
package cu.edu.cujae.graphy.algorithms;
20-
21-
import cu.edu.cujae.graphy.core.Edge;
22-
import cu.edu.cujae.graphy.core.Graph;
23-
import cu.edu.cujae.graphy.core.Weight;
24-
import cu.edu.cujae.graphy.core.WeightedGraph;
25-
import cu.edu.cujae.graphy.core.iterators.GraphIterator;
26-
import cu.edu.cujae.graphy.core.utility.GraphBuilders;
27-
import java.util.Iterator;
28-
import java.util.LinkedList;
29-
import java.util.TreeSet;
30-
31-
/**
32-
* Un árbol de expansión significa que todos los vértices deben estar conectados.
33-
* Por lo tanto, los dos subconjuntos disjuntos de vértices deben estar conectados
34-
* con el borde de peso mínimo para convertirlo en un árbol de expansión mínimo (MST).<p>
35-
* El <b>algoritmo de Boruvka</b> es considerado voraz y utilizado para encontrar
36-
* el <b>árbol recubridor mínimo</b> en un grafo ponderado, en el que todos sus
37-
* arcos poseen distinto peso. Fue publicado por primera vez en 1926, por
38-
* <i>Otakar Boruvka</i> como método eficiente para construir la red eléctrica
39-
* de Moravia. También es conocido como <i>algoritmo de Sollin</i>.
40-
* <p>Su complejidad temporal es <code>O(E log(V))</code>, donde E es el número de
41-
* arcos y V el número de vértices del grafo.
42-
* <p>Existen algoritmos similares para la obtención de árboles de expansión mínimo,
43-
* como es el caso del <i>algoritmo de Kruskal</i> y el <i>algoritmo de Prim</i>.
44-
*
45-
* @author Ananda
46-
* @param <T>
47-
*/
48-
public class BoruvkaMinimalTree<T> extends AbstractAlgorithm<WeightedGraph<T>> {
49-
private final WeightedGraph<T> graph;
50-
51-
public BoruvkaMinimalTree(Graph<T> graph){
52-
super(GraphBuilders.makeSimpleWeightedGraph(false));
53-
54-
if (!graph.isWeighted()){
55-
throw new IllegalArgumentException("Attempted to apply Boruvka algorithm to an unweighted graph.");
56-
}
57-
if (graph.isDirected()){
58-
throw new IllegalArgumentException("Attempted to apply Boruvka algorithm to a directed graph.");
59-
}
60-
this.graph = (WeightedGraph<T>) graph;
61-
}
62-
63-
@Override
64-
public Algorithm<WeightedGraph<T>> apply(){
65-
//asumiendo que el grafo es conexo.
66-
GraphIterator<T> iter = graph.randomIterator();
67-
WeightedGraph<T> mst = null;
68-
//Paso 1: Inicializar vértices como componentes individuales.
69-
LinkedList<Component> listOfComponents = new LinkedList<>();
70-
while(iter.hasNext()){
71-
iter.next();
72-
listOfComponents.add(new Component(iter.getLabel(), graph));
73-
}
74-
//Paso 2: mientras existan componentes, encontrar la arista de menor peso y agregarla al MST.
75-
while(!listOfComponents.isEmpty()){
76-
Component current = listOfComponents.poll();
77-
int lesserWeight = current.getLesserWeightVertex();
78-
79-
}
80-
81-
//Paso 3: devolver MST.
82-
return this;
83-
}
84-
85-
//clase creada con el objetivo de manejar más fácilmente los componentes.
86-
//sería muy parecido a un set de vértices.
87-
private final class Component extends TreeSet<Integer>{
88-
public Component(int u, WeightedGraph<T> graph){
89-
super();
90-
add(u);
91-
}
92-
//método para obtener el menor peso.
93-
private int getLesserWeightVertex(){
94-
int result = -1;
95-
int lesser = Integer.MAX_VALUE;
96-
Iterator<Integer> setIterator = this.iterator();
97-
GraphIterator<T> iter = graph.randomIterator();
98-
while(setIterator.hasNext()){
99-
int current = setIterator.next();
100-
iter.next(current);
101-
Weight<Integer> weight = null;
102-
103-
for(Edge departing : iter.getEdgesDepartingSelf()){
104-
weight = (Weight<Integer>) departing.getWeight();
105-
if(weight.getValue() < lesser){
106-
lesser = weight.getValue();
107-
result = departing.getFinalNode().getLabel();
108-
}
109-
}
110-
111-
for(Edge arriving : iter.getEdgesArrivingSelf()){
112-
weight = (Weight<Integer>) arriving.getWeight();
113-
if(weight.getValue() < lesser){
114-
lesser = weight.getValue();
115-
result = arriving.getFinalNode().getLabel();
116-
}
117-
}
118-
}
119-
120-
return result;
121-
}
122-
}
123-
}
1+
/*
2+
* Copyright (C) 2022 Ananda.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17+
* MA 02110-1301 USA
18+
*/
19+
package cu.edu.cujae.graphy.algorithms;
20+
21+
import cu.edu.cujae.graphy.core.Edge;
22+
import cu.edu.cujae.graphy.core.Weight;
23+
import cu.edu.cujae.graphy.core.WeightedGraph;
24+
import cu.edu.cujae.graphy.core.iterators.GraphIterator;
25+
import cu.edu.cujae.graphy.core.utility.GraphBuilders;
26+
import java.util.ArrayList;
27+
import java.util.TreeSet;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
/**
32+
* Un árbol de expansión significa que todos los vértices deben estar conectados.Por lo tanto, los dos subconjuntos
33+
* disjuntos de vértices deben estar conectados
34+
* con el borde de peso mínimo para convertirlo en un árbol de expansión mínimo (MST)
35+
* .<p>
36+
* El <b>algoritmo de Boruvka</b> es considerado voraz y utilizado para encontrar
37+
* el <b>árbol recubridor mínimo</b> en un grafo ponderado, en el que todos sus
38+
* arcos poseen distinto peso. Fue publicado por primera vez en 1926, por
39+
* <i>Otakar Boruvka</i> como método eficiente para construir la red eléctrica
40+
* de Moravia. También es conocido como <i>algoritmo de Sollin</i>.
41+
* <p>
42+
* Su complejidad temporal es <code>O(E log(V))</code>, donde E es el número de
43+
* arcos y V el número de vértices del grafo.
44+
* <p>
45+
* Existen algoritmos similares para la obtención de árboles de expansión mínimo,
46+
* como es el caso del <i>algoritmo de Kruskal</i> y el <i>algoritmo de Prim</i>.
47+
*
48+
* @see PrimMinimalTree
49+
* @see KruskalMinimumSpanningTree
50+
*
51+
* @author Ananda
52+
*/
53+
public class BoruvkaMinimalTree extends AbstractAlgorithm<WeightedGraph<?>>
54+
{
55+
56+
private static final Logger LOGGER = LoggerFactory.getLogger(BoruvkaMinimalTree.class);
57+
58+
/**
59+
* Represents a disjoint set of vertices.
60+
*/
61+
@SuppressWarnings ("serial")
62+
private final static class Component extends TreeSet<Integer>
63+
{
64+
65+
public static Component makeSingleton(WeightedGraph<?> graph, int u)
66+
{
67+
Component singleton = new Component(graph);
68+
singleton.add(u);
69+
return singleton;
70+
}
71+
72+
private final WeightedGraph<?> graph;
73+
74+
public Component(WeightedGraph<?> graph)
75+
{
76+
this.graph = graph;
77+
}
78+
79+
public boolean union(Component component)
80+
{
81+
return addAll(component);
82+
}
83+
84+
public Edge getLesserWeightEdge()
85+
{
86+
Edge result = null;
87+
float lesser = Float.MAX_VALUE;
88+
89+
GraphIterator<?> i = graph.randomIterator();
90+
for (int v : this)
91+
{
92+
i.next(v);
93+
94+
for (Edge e : i.getEdgesDepartingSelf())
95+
{
96+
if (isInternal(e) == false)
97+
{
98+
@SuppressWarnings ("unchecked")
99+
Weight<Number> weight = (Weight<Number>) e.getWeight();
100+
101+
if (weight.getValue().floatValue() < lesser)
102+
{
103+
result = e;
104+
lesser = weight.getValue().floatValue();
105+
}
106+
}
107+
}
108+
}
109+
110+
return result;
111+
}
112+
113+
private boolean isInternal(Edge edge)
114+
{
115+
return contains(edge.getStartNode().getLabel()) && contains(edge.getFinalNode().getLabel());
116+
}
117+
}
118+
119+
private final WeightedGraph<?> graph;
120+
121+
public BoruvkaMinimalTree(WeightedGraph<?> graph)
122+
{
123+
super(GraphBuilders.makeSimpleWeightedGraph(false));
124+
if (!graph.isWeighted())
125+
{
126+
throw new IllegalArgumentException("Attempted to apply Boruvka algorithm to an unweighted graph.");
127+
}
128+
if (graph.isDirected())
129+
{
130+
throw new IllegalArgumentException("Attempted to apply Boruvka algorithm to a directed graph.");
131+
}
132+
133+
this.graph = graph;
134+
}
135+
136+
@Override
137+
public Algorithm<WeightedGraph<?>> apply()
138+
{
139+
//asumiendo que el grafo es conexo.
140+
WeightedGraph<?> mst = getResult();
141+
142+
// List of components
143+
ArrayList<Component> components = new ArrayList<>(graph.size() * (2 / 3));
144+
145+
// Initialize all the components to a singleton
146+
for (int v : graph.getLabels())
147+
{
148+
components.add(Component.makeSingleton(graph, v));
149+
}
150+
151+
LOGGER.debug("{}", components);
152+
153+
while (components.size() > 1)
154+
{
155+
LOGGER.info("{}", components);
156+
157+
for (int i = 0; i < components.size(); ++i)
158+
{
159+
Component connectableComponent = null;
160+
Component currentComponent = components.get(i);
161+
Edge cheapest = currentComponent.getLesserWeightEdge();
162+
163+
// Find to what component does the edge belongs to
164+
for (Component c : components)
165+
{
166+
int connectionPoint = cheapest.getFinalNode().getLabel();
167+
if (c.equals(currentComponent) == false && c.contains(connectionPoint))
168+
{
169+
connectableComponent = c;
170+
break;
171+
}
172+
}
173+
174+
if (connectableComponent == null)
175+
{
176+
throw new IllegalStateException("Unable to find connection for " + cheapest);
177+
}
178+
179+
// Merge the components & remove the second from the list
180+
currentComponent.union(connectableComponent);
181+
components.remove(connectableComponent);
182+
183+
}
184+
}
185+
186+
//Paso 3: devolver MST.
187+
return this;
188+
}
189+
190+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy