Как мне написать программу для решения нескольких вопросов? - PullRequest
1 голос
/ 31 января 2011

Какое число от 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

Правила:

  • Все переменные (A, B, C, D, E, F, G) равны целочисленным значениям от 1 до 7
  • Ни одна из переменных (A, B, C, D, E, F, G) равны друг другу, т.е. будут использоваться все семь значений, без повторного использования целых чисел

Ответы [ 6 ]

5 голосов
/ 31 января 2011

In 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) 
2 голосов
/ 31 января 2011

Вы должны определить правила соответствующим образом в коде Java и сделать все допустимые перестановки {1,2,3,4,5,6,7} и проверить, какие перестановки соответствуют этим правилам. Я сделал это уже здесь для другого вопроса перестановки: Как написать условие "все эти числа разные" в 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);
    }
}

Это определит rules1..5 относительно правил, определенных в вопросе, и выполнит проверку всех! 7 = 5040 перестановок {1,2,3,4,5,6,7}. Вы можете увидеть это в действии здесь: https://ideone.com/wwxG0

, что приводит к (A, B, C, D, E, F, G): [3, 2, 7, 6, 4, 5, 1]

2 голосов
/ 31 января 2011

Там 7!способы расстановки чисел, которых не так много, используют грубую силу, и, вероятно, это будет достаточно быстро.Даже если вы не хотите генерировать перестановки, вы можете использовать 7 вложенных циклов, и это будет 7 ^ 7 итераций.Вы можете проверить A!=2 вначале для цикла, переместить F на третий уровень, и вы можете проверить A+B=F на уровне 3, D+E=2F на уровне 5. Это сократит итерации.

Неподходящий ответ для домашней работы или интервью - но если вам просто нужен ответ, вы получите его быстрее, используя грубую силу.

1 голос
/ 31 января 2011

Самый простой подход состоит в том, чтобы иметь 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.
  }
}

Помните, что это условие, что все переменные имеют разные значения.

0 голосов
/ 31 января 2011

Для хорошего решения вам следует обратиться в библиотеку 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);
        }
    }
}
0 голосов
/ 31 января 2011

Лучше всего выбрать библиотеку линейного программирования для тяжелой работы.Попробуйте:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...