/*
* Copyright 2012 Odysseus Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.odysseus.ithaka.digraph.util.fas;
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
import de.odysseus.ithaka.digraph.Digraph;
import de.odysseus.ithaka.digraph.Digraphs;
import de.odysseus.ithaka.digraph.EdgeWeights;
import de.odysseus.ithaka.digraph.WeightedDigraph;
import de.odysseus.ithaka.digraph.WeightedDigraphAdapter;
import de.odysseus.ithaka.digraph.util.fas.AbstractFeedbackArcSetProvider;
import de.odysseus.ithaka.digraph.util.fas.FeedbackArcSet;
import de.odysseus.ithaka.digraph.util.fas.FeedbackArcSetPolicy;
public class AbstractFeedbackArcSetProviderTest {
@Test
public void testMinWeightPolicy() {
final WeightedDigraph<Integer> graph = new WeightedDigraphAdapter<Integer>();
graph.put(1, 2, 3);
graph.put(2, 1, 1);
AbstractFeedbackArcSetProvider provider = new AbstractFeedbackArcSetProvider(false) {
@Override
protected <V, E> Digraph<V, E> lfas(Digraph<V, E> digraph, EdgeWeights<? super V> weights) {
Assert.assertTrue(digraph == graph);
Assert.assertTrue(weights == graph);
return digraph;
}
};
FeedbackArcSet<Integer, Integer> feedback = provider.getFeedbackArcSet(graph, graph, FeedbackArcSetPolicy.MIN_WEIGHT);
Assert.assertFalse(feedback.isExact());
Assert.assertEquals(4, feedback.getWeight());
Assert.assertTrue(Digraphs.isEquivalent(feedback, graph, true));
}
@Test
public void testMinSizePolicy() {
final WeightedDigraph<Integer> graph = new WeightedDigraphAdapter<Integer>();
graph.put(1, 2, 3);
graph.put(2, 1, 1);
AbstractFeedbackArcSetProvider provider = new AbstractFeedbackArcSetProvider(false) {
@Override
protected <V, E> Digraph<V, E> lfas(Digraph<V, E> digraph, EdgeWeights<? super V> weights) {
Assert.assertTrue(digraph == graph);
for (V source : digraph.vertices()) {
for (V target : digraph.targets(source)) {
if (Integer.valueOf(1).equals(source)) {
Assert.assertEquals(7, weights.get(source, target).intValue());
} else {
Assert.assertEquals(5, weights.get(source, target).intValue());
}
}
}
return digraph;
}
};
FeedbackArcSet<Integer, Integer> feedback = provider.getFeedbackArcSet(graph, graph, FeedbackArcSetPolicy.MIN_SIZE);
Assert.assertFalse(feedback.isExact());
Assert.assertEquals(4, feedback.getWeight());
Assert.assertTrue(Digraphs.isEquivalent(feedback, graph, true));
}
@Test
public void testDecompose() {
final WeightedDigraph<Integer> graph = new WeightedDigraphAdapter<Integer>();
graph.put(1, 2, 3);
graph.put(2, 1, 1);
AbstractFeedbackArcSetProvider provider = new AbstractFeedbackArcSetProvider(0) { // current thread
@Override
protected <V, E> Digraph<V, E> lfas(Digraph<V, E> digraph, EdgeWeights<? super V> weights) {
Assert.assertFalse(digraph == graph);
Assert.assertTrue(weights == graph);
return digraph;
}
};
FeedbackArcSet<Integer, Integer> feedback = provider.getFeedbackArcSet(graph, graph, FeedbackArcSetPolicy.MIN_WEIGHT);
Assert.assertFalse(feedback.isExact());
Assert.assertEquals(4, feedback.getWeight());
Assert.assertTrue(Digraphs.isEquivalent(feedback, graph, true));
}
@Test
public void testDecompose2() {
final WeightedDigraph<Integer> graph = new WeightedDigraphAdapter<Integer>();
graph.put(1, 2, 3);
graph.put(2, 1, 1);
graph.put(2, 3, 1);
graph.put(3, 4, 1);
graph.put(4, 3, 2);
graph.put(4, 5, 1);
final List<Thread> threads = new ArrayList<Thread>();
AbstractFeedbackArcSetProvider provider = new AbstractFeedbackArcSetProvider(2) { // two threads
@Override
protected <V, E> Digraph<V, E> lfas(Digraph<V, E> digraph, EdgeWeights<? super V> weights) {
threads.add(Thread.currentThread());
try {
Thread.sleep(30);
} catch (InterruptedException e) {
Assert.fail();
}
Assert.assertFalse(digraph == graph);
Assert.assertTrue(weights == graph);
return digraph;
}
};
FeedbackArcSet<Integer, Integer> feedback = provider.getFeedbackArcSet(graph, graph, FeedbackArcSetPolicy.MIN_WEIGHT);
Assert.assertEquals(2, threads.size());
Assert.assertNotSame(threads.get(0), threads.get(1));
Assert.assertFalse(feedback.isExact());
Assert.assertEquals(7, feedback.getWeight());
}
@Test
public void testAcyclic() {
final WeightedDigraph<Integer> graph = new WeightedDigraphAdapter<Integer>();
graph.put(1, 2, 3);
graph.put(2, 3, 1);
AbstractFeedbackArcSetProvider provider = new AbstractFeedbackArcSetProvider(0) {
@Override
public <V, E> FeedbackArcSet<V, E> mfas(Digraph<V, E> digraph, EdgeWeights<? super V> weights) {
Assert.fail();
return null;
}
@Override
protected <V, E> Digraph<V, E> lfas(Digraph<V, E> digraph, EdgeWeights<? super V> weights) {
Assert.fail();
return null;
}
};
FeedbackArcSet<Integer, Integer> feedback = provider.getFeedbackArcSet(graph, graph, FeedbackArcSetPolicy.MIN_WEIGHT);
Assert.assertTrue(feedback.isExact());
Assert.assertEquals(0, feedback.getWeight());
Assert.assertEquals(0, feedback.getVertexCount());
}
}