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]

怎么用?
为了实现这一点,我使用了带有P1的getCombinations函数,
P2和P3作为参数。准备P2和P3阵列列表
使用,我使用fillArrayList函数,该函数从
最小到最大填充,然后返回相关的arraylist。
我所面临的问题是,我对如何限制排列的输出感到困惑(迷茫),这种排列可能导致如下的“坏结果”:
例如
P1=Lion&&P2>23&&P3p1=lion&&p2=37,结果不好。
P1=椅子&&P2尽管我很乐意为每个语句静态地编码一系列条件语句,但由于这些步骤是从可以更改的文件中读取的,因此这种方法不适用。
代码:
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;
        }
    }
}

你推荐什么?

最佳答案

考虑对规则进行编码,其中一组规则确定是否包含或排除该特定候选置换。例如,定义规则的接口:

    public interface ExclusionRule<X> {
        public boolean isExcluded(X x);
    }

以及一些知道如何与字符串或整数进行比较的实现:
    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);
        }
    }

关于java - 如何限制排列的生成? (在Java中),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53121972/

10-13 09:12