Last active
February 12, 2016 23:05
-
-
Save saka1029/54ced0d6f73128dfa577 to your computer and use it in GitHub Desktop.
Dependency Algorithm - find a minimum set of packages to install
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package stackoverflow.dependency; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
public class Dependency { | |
public static class Node { | |
final String name; | |
final List<String> and = new ArrayList<>(); | |
final List<String> or = new ArrayList<>(); | |
Node(String name) { | |
this.name = name; | |
} | |
public Node and(String... and) { | |
for (String e : and) | |
this.and.add(e); | |
return this; | |
} | |
public Node or(String... or) { | |
for (String e : or) | |
this.or.add(e); | |
return this; | |
} | |
@Override | |
public String toString() { | |
return name + " and" + and + " or" + or; | |
} | |
} | |
final Map<String, Node> map = new HashMap<>(); | |
public Node node(String name) { | |
Node node = map.get(name); | |
if (node == null) | |
map.put(name, node = new Node(name)); | |
return node; | |
} | |
@Override | |
public String toString() { | |
StringBuilder sb = new StringBuilder(); | |
for (Node e : map.values()) | |
sb.append(e).append("\n"); | |
return sb.toString(); | |
} | |
public Node get(String name) { | |
return map.get(name); | |
} | |
static void expand(List<List<String>> targetOr, int index, List<String> set, List<Set<String>> expanded) { | |
int size = targetOr.size(); | |
if (index >= size) | |
expanded.add(new HashSet<>(set)); | |
else | |
for (String s : targetOr.get(index)) { | |
set.add(s); | |
expand(targetOr, index + 1, set, expanded); | |
set.remove(set.size() - 1); | |
} | |
} | |
public List<String> dependents(String start) { | |
List<String> targetAnd = new ArrayList<>(); | |
List<List<String>> targetOr = new ArrayList<>(); | |
List<String> result = new ArrayList<>(); | |
targetAnd.add(start); | |
while (!targetAnd.isEmpty()) { | |
System.out.println("target=AND" + targetAnd + " OR" + targetOr + ", result=" + result); | |
String single = targetAnd.remove(0); | |
Node singleNode = get(single); | |
result.add(single); | |
for (Iterator<List<String>> i = targetOr.iterator(); i.hasNext(); ) | |
if (i.next().contains(single)) | |
i.remove(); | |
System.out.println("target=AND" + targetAnd + " OR" + targetOr + ", result=" + result); | |
targetAnd.addAll(singleNode.and); | |
if (singleNode.or.size() > 0) | |
targetOr.add(singleNode.or); | |
} | |
if (!targetOr.isEmpty()) { | |
List<Set<String>> expanded = new ArrayList<>(); | |
expand(targetOr, 0, new ArrayList<>(), expanded); | |
System.out.println("expanded=OR" + expanded); | |
int min = Integer.MAX_VALUE; | |
Set<String> minSet = null; | |
for (Set<String> set : expanded) | |
if (set.size() < min) { | |
min = set.size(); | |
minSet = set; | |
} | |
result.addAll(minSet); | |
} | |
return result; | |
} | |
public static void main(String[] args) { | |
Dependency d = new Dependency(); | |
d.node("X").and("A").or("E", "C"); | |
d.node("E").and("B").or("Y", "Z"); | |
d.node("A").and("E").or("H", "Y"); | |
d.node("C").or("A", "K"); | |
d.node("Z"); | |
d.node("B"); | |
d.node("H"); | |
d.node("K"); | |
System.out.println(d); | |
List<String> result = d.dependents("X"); | |
System.out.println(result); | |
// A and[E] or[H, Y] | |
// B and[] or[] | |
// C and[] or[A, K] | |
// E and[B] or[Y, Z] | |
// X and[A] or[E, C] | |
// H and[] or[] | |
// Z and[] or[] | |
// K and[] or[] | |
// | |
// target=AND[X] OR[], result=[] | |
// target=AND[] OR[], result=[X] | |
// target=AND[A] OR[[E, C]], result=[X] | |
// target=AND[] OR[[E, C]], result=[X, A] | |
// target=AND[E] OR[[E, C], [H, Y]], result=[X, A] | |
// target=AND[] OR[[H, Y]], result=[X, A, E] | |
// target=AND[B] OR[[H, Y], [Y, Z]], result=[X, A, E] | |
// target=AND[] OR[[H, Y], [Y, Z]], result=[X, A, E, B] | |
// expanded=OR[[H, Y], [H, Z], [Y], [Y, Z]] | |
// [X, A, E, B, Y] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment