Dataset:
P1: Lion, Snow, Chair
P2: Min: 0, Max: 28
P3: Min: 34, Max is 39.
将上面的数据集(P1,P2,P3)作为“我的程序” 作为一系列数组列表进行馈送。据此,它连续输出序列的不同变化,包括来自每个部分(P1,P2,P3)的一个元素,直到生成所有可能的排列。 (生成的P2和P3可以是各自的最小值和最大值之间的任意数字。)
这些序列的示例:
[Lion, 2, 37]
[Lion, 3, 34]
[Lion, 3, 35]
[Chair, 15, 35]
[Chair, 15, 36]
[Chair, 15, 37]
[Snow, 25, 36]
[Snow, 25, 37]
[Snow, 26, 34]
如何?
例如
尽管我愿意为每个条件静态地编码一系列条件语句,但是由于这些步骤是从可以更改的文件中读取的,因此这种方法不适用。
代码:
static ArrayList<ArrayList<String>> dataset = new ArrayList<ArrayList<String>>();
static ArrayList<ArrayList<String>> rows = new ArrayList<ArrayList<String>>();
static ArrayList<String> NegativePredictions = new ArrayList<String>();
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
init();
for (ArrayList<String> curArrayList : dataset) {
ArrayList<String> currentRule = new ArrayList<String>();
if (curArrayList.size() > 2) {
currentRule = curArrayList;
} else {
currentRule = new ArrayList<String>(
fillArrayList(Integer.parseInt(curArrayList.get(0)), Integer.parseInt(curArrayList.get(1))));
}
rows.add(currentRule);
}
getCombinations(rows).forEach(System.out::println);
}
public static void init() throws IOException {
ArrayList<String> P1 = new ArrayList<String>(Arrays.asList("Lion", "Snow", "Chair"));
ArrayList<String> P2 = new ArrayList<String>(Arrays.asList("0", "28"));
ArrayList<String> P3 = new ArrayList<String>(Arrays.asList("34", "37"));
dataset = new ArrayList<ArrayList<String>>(Arrays.asList(P1, P2, P3));
NegativePredictions = new ArrayList<String>(Files.readAllLines(Paths.get("Predict.txt")));
}
public static ArrayList<String> fillArrayList(Integer start, Integer end) {
ArrayList<String> returnedList = new ArrayList<String>();
for (int i = start; i <= end; i++) {
returnedList.add(String.valueOf(i));
}
return returnedList;
}
@SuppressWarnings("unchecked")
public static <T> List<List<T>> getCombinations(Collection<? extends Iterable<T>> valueSetCollection) {
Iterable<T>[] valueSets = new Iterable[valueSetCollection.size()];
Iterator<T>[] valueIters = new Iterator[valueSetCollection.size()];
T[] values = (T[]) new Object[valueSetCollection.size()];
int i = 0;
for (Iterable<T> valueSet : valueSetCollection) {
valueSets[i] = valueSet; // Copy to array for fast index lookup
valueIters[i] = valueSet.iterator();
values[i] = valueIters[i].next(); // Fail if a wordSet is empty
i++;
}
List<List<T>> combinations = new ArrayList<>();
NEXT_COMBO: for (;;) {
combinations.add(Arrays.asList(values.clone()));
for (i = values.length - 1; i >= 0; i--) {
if (valueIters[i].hasNext()) {
values[i] = valueIters[i].next();
continue NEXT_COMBO;
}
valueIters[i] = valueSets[i].iterator();
values[i] = valueIters[i].next();
}
return combinations;
}
}
}
您会推荐什么?
答案 0 :(得分:0)
您可以将Predicate
函数传递给getCombinations
方法以过滤或接受某些组合:
/** Returns true if this combination is accepted, false if it should be filtered. */
public static boolean myFilter(Object[] combo) {
// Object arrays and casting is gross
if (combo.length != 3) {
return false;
}
try {
String p1 = (String) combo[0];
// Why are they strings?
Integer p2 = Integer.valueOf((String) combo[1]);
Integer p3 = Integer.valueOf((String) combo[2]);
return !("Lion".equals(p1) && (13 > p2) && (35 >= p3))
&& !("Lion".equals(p1) && (13 > p2) && (37 <= p3))
&& !("Chair".equals(p1) && (7 > p2) && (34 == p3));
} catch (Exception e) {
// invalid combination, filter it
return false;
}
}
@SuppressWarnings("unchecked")
public static <T> List<List<T>> getCombinations(
Collection<? extends Iterable<T>> valueSetCollection,
Predicate<Object[]> filter) {
Iterable<T>[] valueSets = new Iterable[valueSetCollection.size()];
Iterator<T>[] valueIters = new Iterator[valueSetCollection.size()];
T[] values = (T[]) new Object[valueSetCollection.size()];
int i = 0;
for (Iterable<T> valueSet : valueSetCollection) {
valueSets[i] = valueSet; // Copy to array for fast index lookup
valueIters[i] = valueSet.iterator();
values[i] = valueIters[i].next(); // Fail if a wordSet is empty
i++;
}
List<List<T>> combinations = new ArrayList<>();
NEXT_COMBO: for (;;) {
T[] v = values.clone();
if (filter.test(v)) {
combinations.add(Arrays.asList(v));
} else {
System.out.println("rejected " + Arrays.asList(v));
}
for (i = values.length - 1; i >= 0; i--) {
if (valueIters[i].hasNext()) {
values[i] = valueIters[i].next();
continue NEXT_COMBO;
}
valueIters[i] = valueSets[i].iterator();
values[i] = valueIters[i].next();
}
return combinations;
}
}
public static void main(String[] args){
// ...
getCombinations(rows, MyClass::myFilter).forEach(System.out::println);
System.out.println("##############################");
// accept all
getCombinations(rows, o -> true).forEach(System.out::println);
}
此外,与传递列表列表相比,使数据容器类像这样更好:
public class MyCombination {
private final String s;
private final int i1;
private final int i2;
public MyCombination(String s, int i1, int i2){
this.s = s;
this.i1 = i1;
this.i2 = i2;
}
}
答案 1 :(得分:0)
考虑对规则进行编码,其中一组规则确定是否包括或排除特定的候选排列。例如,定义规则的接口:
public interface ExclusionRule<X> {
public boolean isExcluded(X x);
}
还有一些实现方法,这些实现方法知道如何与String或Integer进行比较:
public class ExcludeIfEqualStringRule implements ExclusionRule<String> {
private final String exclusion;
public ExcludeIfEqualStringRule(String exclusion) {
this.exclusion = exclusion;
}
@Override
public boolean isExcluded(String x) {
return x.equals(exclusion);
}
}
public abstract class AbstractExcludeIntegerRule implements ExclusionRule<Integer> {
private final int threshold;
private final ExclusionRule<Integer> or;
public AbstractExcludeIntegerRule(int threshold, ExclusionRule<Integer> or) {
this.threshold = threshold;
this.or = or;
}
@Override
public final boolean isExcluded(Integer x) {
if (or != null) {
return or.isExcluded(x) || doComparison(x, threshold);
}
return doComparison(x, threshold);
}
protected abstract boolean doComparison(int x, int threshold);
}
public class ExcludeIfGreaterThanIntegerRule extends AbstractExcludeIntegerRule {
public ExcludeIfGreaterThanIntegerRule(int threshold, ExclusionRule<Integer> or) {
super(threshold, or);
}
public ExcludeIfGreaterThanIntegerRule(int threshold) {
this(threshold, null);
}
@Override
protected boolean doComparison(int x, int threshold) {
return x > threshold;
}
}
public class ExcludeIfLessThanIntegerRule extends AbstractExcludeIntegerRule {
public ExcludeIfLessThanIntegerRule(int threshold, ExclusionRule<Integer> or) {
super(threshold, or);
}
public ExcludeIfLessThanIntegerRule(int threshold) {
this(threshold, null);
}
@Override
protected boolean doComparison(int x, int threshold) {
return x < threshold;
}
}
public class ExcludeIfEqualIntegerRule extends AbstractExcludeIntegerRule {
public ExcludeIfEqualIntegerRule(int threshold, ExclusionRule<Integer> or) {
super(threshold, or);
}
public ExcludeIfEqualIntegerRule(int threshold) {
this(threshold, null);
}
@Override
protected boolean doComparison(int x, int threshold) {
return x == threshold;
}
}
伴随另一个类,该类定义用于评估任何候选排列的规则集:
public class ExclusionEvaluator<T, U, V> {
private final ExclusionRule<T> tRule;
private final ExclusionRule<U> uRule;
private final ExclusionRule<V> vRule;
public ExclusionEvaluator(ExclusionRule<T> tRule, ExclusionRule<U> uRule, ExclusionRule<V> vRule) {
this.tRule = tRule;
this.uRule = uRule;
this.vRule = vRule;
}
public boolean isExcluded(T t, U u, V v) {
return tRule.isExcluded(t) && uRule.isExcluded(u) && vRule.isExcluded(v);
}
}
将这三个列表作为单独的对象,可以将其封装在另一个提供getCombinations()
方法的类中:
public class PermutationProvider<T, U, V> {
private final List<T> tItems;
private final List<U> uItems;
private final List<V> vItems;
private final List<ExclusionEvaluator<T, U, V>> exclusionEvaluators;
public PermutationProvider(List<T> tItems, List<U> uItems, List<V> vItems, List<ExclusionEvaluator<T, U, V>> exclusionEvaluators) {
this.tItems = tItems;
this.uItems = uItems;
this.vItems = vItems;
this.exclusionEvaluators = exclusionEvaluators;
}
public List<Permutation<T, U, V>> getCombinations() {
List<Permutation<T, U, V>> combinations = new ArrayList<>();
for (T tElement : tItems) {
for (U uElement : uItems) {
for (V vElement : vItems) {
Permutation<T, U, V> p = new Permutation<>(tElement, uElement, vElement);
if (isExcluded(tElement, uElement, vElement)) {
System.out.println(p + " IS EXCLUDED");
} else {
combinations.add(p);
}
}
}
}
return combinations;
}
private boolean isExcluded(T tElement, U uElement, V vElement) {
for (ExclusionEvaluator<T, U, V> exclusionEvaluator : exclusionEvaluators) {
if (exclusionEvaluator.isExcluded(tElement, uElement, vElement)) {
return true;
}
}
return false;
}
}
和用于保存排列的结果类:
public class Permutation<T, U, V> {
private final T t;
private final U u;
private final V v;
public Permutation(T t, U u, V v) {
this.t = t;
this.u = u;
this.v = v;
}
public String toString() {
return t.toString() + " " + u.toString() + " " + v.toString();
}
}
连同驱动程序类一起构建列表,排除规则并获得可接受的排列:
public class PermuteWithExclusionsApp {
public static void main(String[] args) {
new PermuteWithExclusionsApp().permute();
}
private void permute() {
List<String> p1 = Arrays.asList("Lion", "Chair", "Snow");
List<Integer> p2 = new ArrayList<>();
for (int i = 0; i <= 28; i++) {
p2.add(i);
}
List<Integer> p3 = new ArrayList<>();
for (int i = 34; i <= 39; i++) {
p3.add(i);
}
// read from a file or some other source
List<String> compoundExclusionRules = Arrays.asList("P1 = Lion && P2 > 23 && P3 <= 35", "P1 = Lion && P2 < 13 && P3 >= 37", "P1 = Chair && P2 < 7 && P3 = 34");
ExclusionRuleFactory<String> stringRuleFactory = new StringExclusionRuleFactory();
ExclusionRuleFactory<Integer> integerRuleFactory = new IntegerExclusionRuleFactory();
ExclusionEvaluatorFactory<String, Integer, Integer> evaluatorFactory = new ExclusionEvaluatorFactory<>(stringRuleFactory, integerRuleFactory, integerRuleFactory);
List<ExclusionEvaluator<String, Integer, Integer>> evaluators = new ArrayList<>();
for (String compoundExclusionRule : compoundExclusionRules) {
evaluators.add(evaluatorFactory.create(compoundExclusionRule));
}
// List<ExclusionEvaluator<String, Integer, Integer>> evaluators = new ArrayList<>();
// evaluators.add(getExclusionRul1());
// evaluators.add(getExclusionRul2());
// evaluators.add(getExclusionRul3());
PermutationProvider<String, Integer, Integer> provider = new PermutationProvider<>(p1, p2, p3, evaluators);
List<Permutation<String, Integer, Integer>> permuations = provider.getCombinations();
for (Permutation<String, Integer, Integer> p : permuations) {
System.out.println(p);
}
}
// private ExclusionEvaluator<String, Integer, Integer> getExclusionRul3() {
// ExclusionRule<String> p1Rule = new ExcludeIfEqualStringRule("Chair");
// ExclusionRule<Integer> p2Rule = new ExcludeIfLessThanIntegerRule(7);
// ExclusionRule<Integer> p3Rule = new ExcludeIfEqualIntegerRule(34);
// return new ExclusionEvaluator<String, Integer, Integer>(p1Rule, p2Rule, p3Rule);
// }
//
// private ExclusionEvaluator<String, Integer, Integer> getExclusionRul2() {
// ExclusionRule<String> p1Rule = new ExcludeIfEqualStringRule("Lion");
// ExclusionRule<Integer> p2Rule = new ExcludeIfLessThanIntegerRule(13);
// ExclusionRule<Integer> p3Rule = new ExcludeIfGreaterThanIntegerRule(37, new ExcludeIfEqualIntegerRule(37));
// return new ExclusionEvaluator<String, Integer, Integer>(p1Rule, p2Rule, p3Rule);
// }
//
// private ExclusionEvaluator<String, Integer, Integer> getExclusionRul1() {
// ExclusionRule<String> p1Rule = new ExcludeIfEqualStringRule("Lion");
// ExclusionRule<Integer> p2Rule = new ExcludeIfGreaterThanIntegerRule(23);
// ExclusionRule<Integer> p3Rule = new ExcludeIfLessThanIntegerRule(35, new ExcludeIfEqualIntegerRule(35));
// return new ExclusionEvaluator<String, Integer, Integer>(p1Rule, p2Rule, p3Rule);
// }
这是一个工厂示例,用于分析排除规则(例如,如果将规则定义为文本)。
public interface ExclusionRuleFactory<Z> {
public ExclusionRule<Z> create(String operator, String operand);
}
public class StringExclusionRuleFactory implements ExclusionRuleFactory<String> {
@Override
public ExclusionRule<String> create(String operator, String operand) {
return new ExcludeIfEqualStringRule(operand);
}
}
public class IntegerExclusionRuleFactory implements ExclusionRuleFactory<Integer> {
@Override
public ExclusionRule<Integer> create(String operator, String operand) {
int threshold = Integer.parseInt(operand);
switch (operator) {
case "=":
return new ExcludeIfEqualIntegerRule(threshold);
case ">":
return new ExcludeIfGreaterThanIntegerRule(threshold);
case "<":
return new ExcludeIfLessThanIntegerRule(threshold);
case ">=":
return new ExcludeIfGreaterThanIntegerRule(threshold, new ExcludeIfEqualIntegerRule(threshold));
case "<=":
return new ExcludeIfLessThanIntegerRule(threshold, new ExcludeIfEqualIntegerRule(threshold));
}
throw new IllegalArgumentException("Unsupported operator " + operator);
}
}
public class ExclusionEvaluatorFactory<T, U, V> {
private final ExclusionRuleFactory<T> p1RuleFactory;
private final ExclusionRuleFactory<U> p2RuleFactory;
private final ExclusionRuleFactory<V> p3RuleFactory;
public ExclusionEvaluatorFactory(ExclusionRuleFactory<T> p1RuleFactory, ExclusionRuleFactory<U> p2RuleFactory, ExclusionRuleFactory<V> p3RuleFactory) {
this.p1RuleFactory = p1RuleFactory;
this.p2RuleFactory = p2RuleFactory;
this.p3RuleFactory = p3RuleFactory;
}
public ExclusionEvaluator<T, U, V> create(String compoundExclusionRule) {
ExclusionRule<T> p1Rule = null;
ExclusionRule<U> p2Rule = null;
ExclusionRule<V> p3Rule = null;
String[] exclusionSubRules = compoundExclusionRule.split("&&");
for (int sr = 0; sr < exclusionSubRules.length; sr++) {
String[] ruleParts = exclusionSubRules[sr].trim().split(" ");
String whichRule = ruleParts[0].trim();
String operator = ruleParts[1].trim();
String operand = ruleParts[2].trim();
switch (whichRule) {
case "P1":
p1Rule = p1RuleFactory.create(operator, operand);
break;
case "P2":
p2Rule = p2RuleFactory.create(operator, operand);
break;
case "P3":
p3Rule = p3RuleFactory.create(operator, operand);
break;
}
}
return new ExclusionEvaluator<T, U, V>(p1Rule, p2Rule, p3Rule);
}
}