org.jgrapht.alg.vertexcover.BarYehudaEvenTwoApproxVCImpl Maven / Gradle / Ivy
The newest version!
/*
* (C) Copyright 2016-2023, by Joris Kinable and Contributors.
*
* JGraphT : a free Java graph-theory library
*
* See the CONTRIBUTORS.md file distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the
* GNU Lesser General Public License v2.1 or later
* which is available at
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
*
* SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
*/
package org.jgrapht.alg.vertexcover;
import org.jgrapht.*;
import org.jgrapht.alg.interfaces.*;
import org.jgrapht.graph.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
/**
* Implementation of the 2-opt algorithm for a minimum weighted vertex cover by R. Bar-Yehuda and S.
* Even. A linear time approximation algorithm for the weighted vertex cover problem. J. of
* Algorithms 2:198-203, 1981. The solution is guaranteed to be within $2$ times the optimum
* solution. An easier-to-read version of this algorithm can be found here: https://www.cs.umd.edu/class/spring2011/cmsc651/vc.pdf
*
* Note: this class supports pseudo-graphs Runtime: $O(|E|)$ This is a fast algorithm, guaranteed to
* give a $2$-approximation. A solution of higher quality (same approximation ratio) at the
* expensive of a higher runtime can be obtained using {@link BarYehudaEvenTwoApproxVCImpl}.
*
*
* TODO: Remove the UndirectedSubgraph dependency! Querying vertex degrees on these graphs is
* actually slow! This does affect the runtime complexity. Better would be to just work on a clone
* of the original graph!
*
* @param the graph vertex type
* @param the graph edge type
*
* @author Joris Kinable
*/
public class BarYehudaEvenTwoApproxVCImpl
implements VertexCoverAlgorithm
{
private final Graph graph;
private final Map vertexWeightMap;
/**
* Constructs a new BarYehudaEvenTwoApproxVCImpl instance where all vertices have uniform
* weights.
*
* @param graph input graph
*/
public BarYehudaEvenTwoApproxVCImpl(Graph graph)
{
this.graph = GraphTests.requireUndirected(graph);
this.vertexWeightMap = graph
.vertexSet().stream().collect(Collectors.toMap(Function.identity(), vertex -> 1.0));
}
/**
* Constructs a new BarYehudaEvenTwoApproxVCImpl instance
*
* @param graph input graph
* @param vertexWeightMap mapping of vertex weights
*/
public BarYehudaEvenTwoApproxVCImpl(Graph graph, Map vertexWeightMap)
{
this.graph = GraphTests.requireUndirected(graph);
this.vertexWeightMap = Objects.requireNonNull(vertexWeightMap);
}
@Override
public VertexCover getVertexCover()
{
Set cover = new LinkedHashSet<>();
double weight = 0;
Graph copy = new AsSubgraph<>(graph, null, null);
Map w = new HashMap<>();
for (V v : graph.vertexSet())
w.put(v, vertexWeightMap.get(v));
// Main loop
Set edgeSet = copy.edgeSet();
while (!edgeSet.isEmpty()) {
// Pick arbitrary edge
E e = edgeSet.iterator().next();
V p = copy.getEdgeSource(e);
V q = copy.getEdgeTarget(e);
if (w.get(p) <= w.get(q)) {
w.put(q, w.get(q) - w.get(p));
cover.add(p);
weight += vertexWeightMap.get(p);
copy.removeVertex(p);
} else {
w.put(p, w.get(p) - w.get(q));
cover.add(q);
weight += vertexWeightMap.get(q);
copy.removeVertex(q);
}
}
return new VertexCoverAlgorithm.VertexCoverImpl<>(cover, weight);
}
}