Можете ли вы упростить этот алгоритм? - PullRequest
25 голосов
/ 19 декабря 2008

Один для математиков. Это произошло в офисе, и мы хотим посмотреть, кто может предложить более оптимизированную версию.

(((a+p) <= b) && (a == 0 || a > 1) && (b >= p)) && 
    ((b - (a + p) == 0) || (b - (a + p) > 1))

Редактировать : все данные являются положительными целыми числами

Редактировать : лучше == рефакторинг для простоты

Ответы [ 27 ]

0 голосов
/ 19 декабря 2008

Я добавил это как комментарий к ответу nickf, но подумал, что предложу его как ответ сам по себе. Хорошие ответы кажутся его вариацией, в том числе и моей. Но так как мы не зависим от компилятора для оптимизации (если бы был OP, мы бы даже не делали этого), тогда сокращение этого значения от 3 AND до следующего означает, что будут значения, где только 2 из 3 частей нужно будет оценить. И если это делается в скрипте, это будет иметь значение в отличие от скомпилированного кода.

(a != 1) && ((b > (a + p + 1)) || (b == (a + p))))

Основываясь на комментарии, я собираюсь добавить это по сравнению с версией AND:

Полагаю, это зависит от того, превышает ли ваш реальный набор данных результатов более 50 процентов входных наборов. Чем чаще ввод правдив, тем лучше будет мой вариант. Таким образом, с этим уравнением похоже, что стиль AND будет лучше (по крайней мере, для моего набора входных данных 0-500).

0 голосов
/ 19 декабря 2008

Ну

((b - (a + p) == 0) || (b - (a + p) > 1))

Would be better writen as:
(b - (a + p) >= 0)  

Applying this to the whole string you get:

((a+p) <= b) && (a > 1) && (b >= p)) && (b - (a + p) >= 0) 


(a + p) <= b is the same thing as b - (a + p) >= 0

Так что вы можете избавиться от этого ухода:

((a+p) <= b) && (a > 1) && (b >= p)) 
0 голосов
/ 19 декабря 2008

Ладно, я надеюсь, что здесь училась математике, но если я прав, то это немного упрощается. Конечно, в конце это не выглядит одинаково, но основная логика должна быть такой же.

// Initial equation
(((a + p) <= b) && (a == 0 || a > 1) && (b >= p)) && ((b - (a + p) == 0) || (b - (a + p) > 1))

// ((a + p) <= b) iif a = 0 && p = b; therefore, b = p and a = 0 for this to work
(b == p) && ((b - (a + p) == 0) || (b - (a + p) > 1))

// Simplification, assuming that b = p and a = 0
(b == p) && (a == 0)

Однако, если мы действуем в предположении, что ноль не является ни положительным, ни отрицательным , то это означает, что любое значение для данного уравнения будет больше или равно единице. Это, в свою очередь, означает, что уравнение будет всегда оценивать как ложное из-за того, что следующее:

(a == 0 || a > 1)

Будет иметь значение true, только когда a> = 2; однако, если верно также следующее:

(b >= p)

Тогда это означает, что p по крайней мере равно b, таким образом:

((a + p) <= b)

Подстановкой становится:

((2 + b) <= b)

Что явно не может быть оценено как истина.

0 голосов
/ 05 февраля 2009

Я чувствую (a! = 1) && (a + p <= b) && (a + p! = B - 1) немного более ясно. Другой вариант: </p>

int t = b-p; (a! = 1 && a <= t && a! = t-1) </p>

Обычно значение a равно 0, t или лежит между 2 и t-2 включительно.

0 голосов
/ 19 декабря 2008
(((a+p) <= b) && (a == 0 || a > 1) && (b >= p)) && ((b - (a + p) == 0) || (b - (a + p) > 1))

, поскольку a> = 0 (натуральные числа), термин (a == 0 || a> 1) всегда истинен

если ((a + p) <= b), то (b> = p) истинно, когда a, b, p>> = 0

поэтому ((a + p) <= b) && (a == 0 || a> 1) && (b> = p)) && ((b - (a + p) == 0) уменьшается до

b>=(a+p)

(b - (a + p) == 0) || (b - (a + p)> 1) эквивалентно b> = (a + p)

, следовательно, все уравнение сводится к

**b>= (a+p)**
0 голосов
/ 29 августа 2011

a! = 1 && ((b == a + p) || (b - p> a + 1))

0 голосов
/ 19 декабря 2008

Первая итерация:

bool bool1 = ((a+p) <= b) && (a == 0 || a > 1) && (b >= p);
bool bool2 = (b - (a + p) == 0) || (b - (a + p) > 1);

return bool1 && bool2;

Вторая итерация:

int value1 = b - (a + p);
bool bool1 = (value1 >= 0) && (a == 0 || a > 1) && (b >= p);
bool bool2 = (value1 == 0) || (value1 > 1);

return bool1 && bool2;

Третья итерация (все положительные)

int value1 = b - (a + p);
bool bool1 = (value1 >= 0) && (a != 1) && (b >= p);
bool bool2 = (value1 == 0) || (value1 > 1);

return bool1 && bool2;

4-я итерация (все положительные)

int value2 = b - p;
int value1 = value2 - a;
bool bool1 = (value1 >= 0) && (a != 1) && (b - p >= 0);
bool bool2 = (value1 == 0) || (value1 > 1);

return bool1 && bool2;

5-я итерация:

int value2 = b - p;
int value1 = value2 - a;
bool bool1 = (value1 >= 0) && (a != 1) && (value2 >= 0);
bool bool2 = (value1 == 0) || (value1 > 1);

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