如何编写程序来解决多个问题?

时间:2011-01-30 21:34:37

标签: java math

1到7之间的数字是否相等? A =,B =,C =,D =,E =,F =,G =

鉴于:

  1. A!=ㅤ2
  2. A + B = F
  3. C - D = G
  4. D + E = 2F
  5. E + G = F
  6. 规则是:

    • 所有变量(A,B,C,D,E,F,G)等于1到7之间的整数值
    • 没有变量(A,B,C,D,E,F,G)彼此相等,即将使用所有七个值,不重复使用整数

6 个答案:

答案 0 :(得分:5)

Mathematica中:

 Reduce[ a != 2 && f == a + b && g == c - d && f == (d + e)/2 && f == e + g && 
        First[And @@@ {0 < # < 8 & /@ {a, b, c, d, e, f, g}}], 
        {a, b, c, d, e, f, g}, Integers]  

解决方案:

(a == 1 && b == 1 && c == 4 && d == 3 && e == 1 && f == 2 && g == 1) || 
(a == 1 && b == 2 && c == 5 && d == 4 && e == 2 && f == 3 && g == 1) || 
(a == 1 && b == 2 && c == 7 && d == 5 && e == 1 && f == 3 && g == 2) || 
(a == 1 && b == 3 && c == 6 && d == 5 && e == 3 && f == 4 && g == 1) || 
(a == 1 && b == 4 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) || 
(a == 3 && b == 1 && c == 6 && d == 5 && e == 3 && f == 4 && g == 1) ||
(a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) || 
(a == 4 && b == 1 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) 

因此,具有七种不同值的唯一解决方案是:

 (a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) 

修改

如果你想直接从Mathematica得到答案,还需要做更多的工作,因为“所有价值观都不同”的条件通常很难写下来。这是:

k = {a, b, c, d, e, f, g}; 
Reduce[
  a != 2 && f == a + b && g == c - d && f == (d + e)/2 && f == e + g && 
  First[And @@@ {0 < # < 8 & /@ k}] && 
  Times@(Sequence @@ (Subsets[k, {2}] /. {x_, y_} -> (x - y))) != 0, k, Integers]

结果

 (a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) 

答案 1 :(得分:2)

有一个7!安排数字的方法并不多 - 使用蛮力,而且可能足够快。即使您不想生成排列,也可以使用7个嵌套for循环,它将是7 ^ 7次迭代。您可以在第一个for循环中检查A!=2,将F移至第三级,然后在级别3检查A+B=F,在级别5检查D+E=2F。这将减少迭代次数。

对于家庭作业或面试来说,这不是一个合适的答案 - 但如果你只是需要答案,你就可以通过蛮力更快地完成它。

答案 2 :(得分:2)

您需要在java代码中以适当的方式定义规则并进行{1,2,3,4,5,6,7}的所有有效排列并检查,哪些排列符合此规则。我已经在这里做了另一个排列问题:How to write an "all these numbers are different" condition in Java?

根据您的规则,代码可能如下所示:

import java.util.Arrays;

class Graph26 {
    private static final int A = 0;
    private static final int B = 1;
    private static final int C = 2;
    private static final int D = 3;
    private static final int E = 4;
    private static final int F = 5;
    private static final int G = 6;

    private final static boolean rule1(final int[] n) {
        return n[A] != 2;
    }

    private final static boolean rule2(final int[] n) {
        return n[A] + n[B]  == n[F];
    }

    private final static boolean rule3(final int[] n) {
        return n[C] - n[D]  == n[G];
    }

    private final static boolean rule4(final int[] n) {
        return n[D] + n[E] == 2*n[F];
    }

    private final static boolean rule5(final int[] n) {
        return n[E] + n[G]  == n[F];
    }


    private final static boolean isValid(final int[] nodes) {
        return rule1(nodes) && rule2(nodes) && rule3(nodes) && rule4(nodes)
                && rule5(nodes);
    }

    class Permutation {
        private final int[] o;
        private boolean perms = true;

        public boolean hasPerms() {
            return perms;
        }

        Permutation(final int[] obj) {
            o = obj.clone();
        }

        private int[] nextPerm() {
            int temp;
            int j = o.length - 2;
            while (o[j] > o[j + 1]) {
            j--;
            if (j < 0) {
            perms = false;
            break;
            }
            }
            if (perms) {
            int k = o.length - 1;
            while (o[j] > o[k]) {
            k--;
            }
            temp = o[k];
            o[k] = o[j];
            o[j] = temp;
            int r = o.length - 1;
            int s = j + 1;
            while (r > s) {
            temp = o[s];
            o[s] = o[r];
            o[r] = temp;
            r--;
            s++;
            }
            }
            return o.clone();
        }
    }

    public static void main(final String[] args) {
        int[] nodes = new int[] { 1, 2, 3, 4, 5, 6, 7};
        final Graph26 graph = new Graph26();
        final Permutation p = graph.new Permutation(nodes);
        int i = 0;
        while (p.hasPerms()) {
        if (isValid(nodes)) {
        System.out.println(Arrays.toString(nodes));
        }
        i++;
        nodes = p.nextPerm();
        }
        System.out.println(i);
    }
}

这将定义关于问题中定义的规则的规则1..5,并对{1,2,3,4,5,6,7}的所有!7 = 5040排列进行检查。您可以在此处查看此操作:https://ideone.com/wwxG0

导致(A,B,C,D,E,F,G): [3, 2, 7, 6, 4, 5, 1]

答案 3 :(得分:1)

最简单的方法是拥有7个嵌套循环:

for(int a = 1; a < 8 ; a++) {
  for(int b = 1; b < 8; b++) {
    same for c, d, e, f, g
    ....
    see if all conditions hold, and if yes, print out all values.
  }
}

请记住,所有变量都有不同的值。

答案 4 :(得分:0)

最好选择一个线性编程库来完成繁重的工作。尝试:

http://www.gnu.org/software/glpk/

答案 5 :(得分:0)

要获得一个好的解决方案,您应该在Apache Commons Math库中解决方程式系统。 对于一个简单的解决方案,蛮力完成了这项工作我看起来像这样:

public class Test {

    private static Value A = new Value("A");
    private static Value B = new Value("B");
    private static Value C = new Value("C");
    private static Value D = new Value("D");
    private static Value E = new Value("E");
    private static Value F = new Value("F");
    private static Value G = new Value("G");

    private static List<Value> VALUES = new ArrayList<Value>(Arrays.asList(
            A,B,C,D,E,F,G
    ));

    private static Rule RESULT = new CombinedRule(
            new Rule(){
                public boolean isValid() {
                    return A.getValue() != 2;
                };
            },
            new Rule(){
                public boolean isValid() {
                    return A.getValue() + B.getValue() == F.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return C.getValue() - D.getValue() == G.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return D.getValue() + E.getValue() == 2 * F.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return E.getValue() + G.getValue() == F.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return A.getValue() != B.getValue()
                        && A.getValue() != C.getValue()
                        && A.getValue() != D.getValue()
                        && A.getValue() != E.getValue()
                        && A.getValue() != F.getValue()
                        && A.getValue() != G.getValue()
                        && B.getValue() != C.getValue()
                        && B.getValue() != D.getValue()
                        && B.getValue() != E.getValue()
                        && B.getValue() != F.getValue()
                        && B.getValue() != G.getValue()
                        && C.getValue() != D.getValue()
                        && C.getValue() != E.getValue()
                        && C.getValue() != F.getValue()
                        && C.getValue() != G.getValue()
                        && D.getValue() != E.getValue()
                        && D.getValue() != F.getValue()
                        && D.getValue() != G.getValue()
                        && E.getValue() != F.getValue()
                        && E.getValue() != G.getValue()
                        && F.getValue() != G.getValue();
                }
            }

    );

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        iterateOn(0);
        System.out.println(System.currentTimeMillis()-start+" millis.");
    }

    private static void iterateOn(int valueNo){
        if(valueNo < VALUES.size()){
            Value v = VALUES.get(valueNo);
            for(int value = 1; value < 8; value++){
                v.setValue(value);
                if(RESULT.isValid()) System.out.println(VALUES);
                iterateOn(valueNo+1);
            }
        }
    }

}

为了提高性能,您可以使用所有可能值的列表,并简单地置换它。 这将循环总量从大约960000减少到大约13000,但是引入了一些列表创建成本。这是代码更改:

public static void main(String[] args) {
    List<Integer> possibleValues = new ArrayList<Integer>();
    for(int value = 1; value < 8; value++){
        possibleValues.add(Integer.valueOf(value));
    }
    long start = System.currentTimeMillis();
    iterateOn(0, possibleValues);
    System.out.println((System.currentTimeMillis()-start)+" millis.");
}

private static void iterateOn(int valueIndex, List<Integer> possibleValues){
    Value v = VALUES.get(valueIndex);
    for(int i = 0; i < possibleValues.size(); i++){
        Integer currentValue = possibleValues.get(i);
        v.setValue(currentValue);
        if(RESULT.isValid()) System.out.println(VALUES);
        if(possibleValues.size() > 1){
            List<Integer> remainingValues = new ArrayList<Integer>(possibleValues);
            remainingValues.remove(currentValue);
            iterateOn(valueIndex+1, remainingValues);
        }
    }
}