Почему больше обращений к массиву будет работать лучше? - PullRequest
4 голосов
/ 08 ноября 2019

Я беру курс на Coursera, который использует миницинк. В одном из заданий я вращал свои колеса навсегда, потому что моя модель не показывала достаточно хороших результатов в скрытом тестовом примере. Я наконец решил ее, изменив следующие типы доступа в моей модели

с

constraint sum(neg1,neg2 in party where neg1 < neg2)(joint[neg1,neg2]) >= m;

на

constraint sum(i,j in 1..u where i < j)(joint[party[i],party[j]]) >= m;

Я не знаю, чего мне не хватает, нопочему эти двое будут отличаться от других? Кажется, что они должны работать аналогично с первым, возможно, немного быстрее, но разница в производительности была драматичной. Я предполагаю, что есть какая-то оптимизация, по которой первая упускает? Или я действительно что-то упускаю, и эти строки действительно приводят к другому поведению? Мое намерение заключается в суммировании силы каждого элемента в рейде.

Разное. Подробности:

  • party - это массив перечисленных переменных
  • набор индексов стороны равен 1..real_u
  • каждый элемент в партии должен бытьуникальный за исключением фиктивной переменной.
  • решатель был Gecode
  • проверка моей модели была выполнена на сервере Coursera, поэтому я не знаю, какой уровень оптимизации использовал их компилятор.

edit:minizinc (mz) является декларативным языком, я понимаю, что «доступ к массиву» в mz не обязательно имеет прямое следствие в императивном языке. Однако для меня эти две строки означают одно и то же семантически. Поэтому я думаю, что мой вопрос звучит так: «Почему вышеприведенные строки семантически отличаются в mz?»

edit2: мне пришлось изменить рассматриваемый пример, я пытался нарушить код чести Coursera.

1 Ответ

1 голос
/ 09 ноября 2019

Разница проистекает из того, как вычисляется выражение where "a В этом случае решатель получил бы сумму за »array [int] of var opt int ", означающее, что некоторые переменные в массиве могут фактически отсутствовать. Для большинства решателей это переписывается в сумму, где каждая переменная умножается на логическую переменную, которая является истинной, если переменная присутствует. Вы можете понять, как это менее эффективно, чем обычная сумма без умножений.

...