Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Тема- Задача выполнимости Выполнилb студентs 4его курса ФИТ ПОВТ0906- Смирнов М

Работа добавлена на сайт samzan.net:

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 25.11.2024

Министерство образования  и науки РФ

Федеральное государственное бюджетное образовательное

Учреждение высшего профессионального образования ТвГТУ

Кафедра «Программное обеспечение вычислительной техники  и автоматизированных систем »

Курсовая работа

По дисциплине: «Теория вычислительных процессов»

Тема: «Задача выполнимости»

Выполнилb студентs 4-его курса

ФИТ ПОВТ-0906: Смирнов М.Ю. Старовойтов И.В.

Проверил: Калабин А.Л.

Тверь 2013г.

Содержание

Постановка задачи…………………………………………………..………….….3

1. Точный алгоритм.………………………………….……………….…………...4

2. Приближенный алгоритм………………………….…….…………………..…8

2.1 Алгоритм WalkSAT……………………………………………………...9

2.2 Алгоритм GSAT…………………………………………………………14

Выводы…………………………………………………………………………….15

Список литературы …………………………………………………..……...........16

Постановка задачи

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

Проблема выполнимости (ВЫП или SAT) – для данной булевой формулы определить, существует ли набор, на котором она обращается в единицу. Такой набор называется выполняющим. Если она существует, то формула называется выполнимой.

Дальше проблема выполнимости будет рассматриваться только для формул специального вида: конъюнктивных нормальных форм (КНФ).

Вообще, если говорить о терминологии, то в современной литературе выделяют более широкую проблему: CSP (Constraint Satisfaction Problem) – выполнимость при ограничениях (могут ли выполняться одновременно ограничения, накладываемые на переменные). Однако, именно задача выполнимости является центральной в этой проблеме, кроме того имеет много хорошо разработанных и исследованных методов решения (достаточно общих и специализированных).

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

Современные программные реализации алгоритмов, предназначенные для решения прикладных задач и оценки эффективности алгоритмов путём сравнения с другими программами (SAT-солверы) могут определять выполнимость КНФ от 1000 переменных за несколько минут. КНФ, выполнимость которых надо определять на практике (их часто называют индустриальными: industrial) имеют специальный вид. Случайные КНФ (сгенерированные с помощью специальных программ, использующих датчики псевдослучайных чисел) имеют более сложную структуру. Для них проблема выполнимости для КНФ, в каждой скобке которых содержится не более трёх литералов (3SAT-проблема) не удаётся решить при числе переменных более 700.

1. ТочНый Алгоритм

Алгоритмы, которые выполняют полный перебор. Как правило, базируются

на DPLL-методе. Часто выделяют две основные категории полных алгоритмов:

- Алгоритмы, основанные на резолюциях.

- Алгоритмы, основанные на «переборе дерева».

Заметим, что именно доказательство невыполнимости (не всегда это доказательство эффективно представляется в аналитическом виде), которое осуществляют полные алгоритмы, имеет важное прикладное значение при автоматическом доказательстве теорем в ИИ (automated theorem proving) и верификации схем (circuit verification).

Дэвис (Davis) и Путнэм (Putnam) предложили алгоритм для решения проблемы выполнимости в 1960 году. . Однако у него имелся существенный недостаток: переполнение памяти. Модифицированная версия Дэвиса, Логемана (Logemann) и Ловелэнда (Loveland) появилась в 1962 году. В этой версии вместо резолюций использовался поиск. Этот алгоритм часто называют DLL или DPLL, а первый – DP. Подробнее о резолюциях и поиске будет сказано ниже. Заметим, что несмотря на недостатки резолюционных алгоритмов как таковых, минимальные резолюционные решения проблемы экспоненциально короче DPLL-решений.

Часто солверы, в которых реализован алгоритм DPLL, делят на две группы:

- Conflict-driven (minisat, vallst, zChaff).

- Look-ahead (kcnfs, march, OKsolver).

Отметим, что солверы, основанные на локальном поиске, показывают хорошие результаты на случайных выполнимых 3-КНФ.  Conict-driven-солверы – на индустриальных КНФ. Look-ahead-солверы – на невыполнимых КНФ.  Переборные алгоритмы, основанные на других идеях, значительно уступают этим.

Описание DPLL

1. Применить юнит-резолюцию и удалить все поглощаемые клаузы (BCP).

2. Если найдена пустая клауза, то вернуть НЕВЫПОЛНИМА.

3. Найти переменную, которая входит в КНФ только с отрицанием или без

отрицания.

4. Удалить все клаузы, в которые входит эта переменная (удаление чистых

литералов).

5. Если нет клауз, то вернуть ВЫПОЛНИМА.

6. Выбрать переменную x (она входит как с отрицанием, так и без).

7. Рекурсивно вызвать DPLL на текущей КНФ с добавленной клаузой (x).

8. Рекурсивно вызвать DPLL на текущей КНФ с добавленной клаузой (!x) .

9. Если один из рекурсивных вызовов вернул ВЫПОЛНИМА, то вернуть

ВЫПОЛНИМА.

10.Вернуть НЕВЫПОЛНИМА.

Реализация:

public static class DPLL

   {

       public static bool Solve(Expression e)

       {

           if (IsSat(e))

           {

               return true;

           }

           if (ContainEmptyDisunkt(e))

               return false;

           List<List<ILiteral>> oneLitDis = OneLitDis(e);

           foreach (var dis in oneLitDis)

           {

               e = UnitPropagade(e, dis);

           }

           Literal l = ChooseLiteral(e);

           if (l == null)

           {

               return IsSat(e);

           }

           return Solve(e.Add(l)) || Solve(e.Add(Not(l)));

       }

Тест:

В качестве примера возьмем выражение (x V y) ^ z, которое является выполнимым и выражение ( a ) ^ ( !a ), которое не выполнимо.

Результаты:

Исследование T(n)

N

DPLL

5

0,002

0

0

0,000667

10

0

0

0,0156

0,0052

15

1,48

1,43

1,41

1,44

20

31,54

31,43

31,46

31,48

25

116,132

115,84

115,68

115,88

30

>1800

>1800

>1800

1800

T(max) = 1800, при N=30.

2. ПРИБЛИЖЕННЫЙ АЛГОРИТМ.

Алгоритмы, которые осуществляют поиск выполняющего набора неполным

перебором пространства возможных решений. Как правило, используют локальный поиск (local search) для нахождения решения. Если алгоритм не находит решения, то это не означает, что его не существует. Таким образом, неполные алгоритмы могут доказать только выполнимость (и то не всегда) и не могут доказать невыполнимость. В последнее время разрабатывают также полные алгоритмы, основанные на локальном поиске (точнее: алгоритмы, доказывающие невыполнимость). Часто для этих алгоритмов исходная задача записывается в других терминах («переформулируется»). При этом основная проблема – компактная запись новой переформулированной задачи. Подобные алгоритмы пока применимы только для «очень маленьких» задач. Основное достоинство такихалгоритмов – быстрая скорость работы.

 GSAT стал первым солвером, основанном на стохастическом локальном поиске (Stochastic Local Search), который решал сложные задачи с большим числом

переменных и клауз.

Дальше появился WalkSAT предложенный МакАлесторомо, Селманомом и Каутсомом в 1997 году. Отличие от GSAT в выборе переменной. В WalkSAT рейтинг переменной равен числу клауз, которые перестанут быть выполнимы при её изменении. Если текущий набор не является искомым, выбирается невыполнимая клауза (случайно). Меняется значение одной из её переменных с

учётом рейтинга (например, если в ней есть переменная с нулевым рейтингом,

то меняется её значение).

В настоящее время существует множество модернизаций этих алгоритмов.

Основная их цель – избежать «застревания» алгоритма в локальных минимумах функционала качества решения. Его можно определить как число невыполненных клауз на данном наборе.

Основная причина – их эвристическая природа, подробное описание в литературе по смежным областям, отсутствие «универсальных подходов». Это «очень знакомые методы»: метод отжига, метод случайных блужданий, генетические алгоритмы и т.д.

Основное достоинство неполных методов – их приложение и к другим задачам, тесно связанным с SAT. Например, MAXSAT (найти набор, который выполняет максимальное число клауз в заданной КНФ). Вообще, почти все эти методы пытаются минимизировать некоторый функционал (часто даже не учитывая его структуру).

2.1  WalkSAT

Реализация:

 public static bool Solve(Expression e, int MaxTries,int MaxFlips)

       {

           for (int i = 0; i < MaxTries; i++)

           {

               SetRandomValues(e);

               for (int flip = 0; flip < MaxFlips; flip++)

               {

                   List<Literal> c = RandomUnsatClause(e);

                   Literal l = GetRandomLiteral(c);

                   if (l != null)

                   {

                       Flip(l);

                   }

                   if (IsSat(e))

                       return true;

               }

           }

           return false;

       }

 Где MaxTries – максимальное количество подграфов, MaxFlips – максимальное количество изменяемых литералов.

Тест:

В качестве примера возьмем выражение (x V y) ^ z, которое является выполнимым и выражение ( a ) ^ ( !a ), которое не выполнимо.

Результаты:

Исследование T(n).

T(с)

N

DPLL

WalkSAT

5

0,002

0

0

0,002

0

0

0,000667

0,000667

10

0

0

0,0156

0,0156

0

0

0,0052

0,0052

15

1,48

1,43

1,41

0,046

0

0

1,44

0,0156

20

31,54

31,43

31,46

0,08

0

0

31,48

0,026

25

116,132

115,84

115,68

0,06

0,047

0,036

115,88

0,048

30

>1800

>1800

>1800

0,42

0,36

0,6

1800

0,46

50

 

 

 

0,97

0,8

0,96

 

0,91

100

 

 

 

4,95

4,97

4,93

 

4,95

500

 

 

 

324

325

322

 

325

1000

 

 

 

>1800

1800

1800

 

1800

T(max) = 1800, max = 1000.

3. СРАВНЕНИЕ.

T(с)

Результат

N

DPLL

WalkSAT

DPLL

WalkSAT

5

0,002

0

0

0,002

0

0

True

True

0,000667

0,000667

10

0

0

0,0156

0,0156

0

0

True

True

0,0052

0,0052

15

1,48

1,43

1,41

0,046

0

0

True

True

1,44

0,0156

20

31,54

31,43

31,46

0,08

0

0

True

True

31,48

0,026

25

116,132

115,84

115,68

0,06

0,047

0,036

True

False

115,88

0,048

30

>1800

>1800

>1800

0,42

0,36

0,6

True

False

1800

0,46

50

 

 

 

0,97

0,8

0,96

 

False

 

0,91

100

 

 

 

4,95

4,97

4,93

 

False

 

4,95

500

 

 

 

324

325

322

 

False

 

325

1000

 

 

 

>1800

1800

1800

 

False

 

1800

По результатам тестов видно, что алгоритм DPLL выполняется за не полиномиальное время. Алгоритм WalkSAT в наилучшем случае выполнялся за линейное время, в наихудшем же случае время равно n4.

Точность решения   для разных  N

ε=100l(St - Sp)l/St

Точность решения

5

100

10

100

15

100

20

100

25

0

30

0

Время решения   для разных  N

ε=100l(Tt - Tp)l/Tt

Время решения

5

0

10

0

15

98,91667

20

99,91741

25

99,95858

30

99,97444

Скриншоты программы.

2.2 Алгоритм GSAT

Алгоритм работает на внутренних формулах. Он начинает задавать случайно подобранные значения ко всем переменным. Если значение удовлетворяет все, то алгоритм останавливается и возвращает значение. В противном случае, значение переменной изменяется, и процесс повторяется. Переменную, которую нужно изменить одним уменьшает число неудовлетворенных клаузул в новом назначении в GSAT. Если никакое назначение не было найдено правильно, то после установки количества итерирований, то алгоритм начинается снова с новым случайным значением. Алгоритм прекращается тогда, когда была найдена модель формулы или когда число рестартов превышает установленное количество (например, 10).

Реализация:

public static class GSat

   {

       public static bool Solve(Expression e, int MaxTries, int MaxFlips)

       {

           for (int i = 0; i < MaxTries; i++)

           {

               SetRandomValues(e);

               for (int flip = 0; flip < MaxFlips; flip++)

               {

                   List<Literal> c = RandomUnsatClause(e);

                   Literal l = GetLiteralGreedily(e, c);

                   if (l != null)

                   {

                       Flip(l);

                   }

                   if (IsSat(e))

                       return true;

               }

           }

           return false;

       }

       private static void Flip(Literal l)

       {

           l.Value = !l.Value;

       }

       private static List<Literal> RandomUnsatClause(Expression e)

       {

           List<List<Literal>> clauses = new List<List<Literal>>();

           foreach (var clause in e.Clauses)

           {

               bool temp = false;

               foreach (var lit in clause)

               {

                   temp = temp || (lit.Not) ? !lit.Value.Value : lit.Value.Value;

               }

               if (!temp)

                   clauses.Add(clause);

           }

           if (clauses.Count > 0)

               return clauses[(new Random()).Next(clauses.Count)];

           else

               return null;

       }

       private static void SetRandomValues(Expression e)

       {

           Random r = new Random();

           foreach (var l in e.Literals)

           {

               if (e.Literals.Where(lit => lit.Name == l.Name).Count() == 1)

                   l.Value = r.NextDouble() > 0.5;

               else

               {

                   bool value = r.NextDouble() > 0.5;

                   foreach (var literal in e.Literals.Where(lit => lit.Name == l.Name))

                   {

                       literal.Value = value;

                   }

               }

           }

       }

       private static Literal GetLiteralGreedily(Expression e, List<Literal> clause)

       {

           Dictionary<int, Literal> raitingLiteral = new Dictionary<int, Literal>();

           foreach (var literal in clause)

           {

               int currentNumberUnsatClauses = CountUnsatClauses(e);

               Flip(literal);

               int flippedNumber = CountUnsatClauses(e);

               if (flippedNumber < currentNumberUnsatClauses)

                   try

                   {

                       raitingLiteral.Add(currentNumberUnsatClauses - flippedNumber, literal);

                   }

                   catch { }

               Flip(literal);

           }

           if (raitingLiteral.Count > 0)

           {

               int maxScore = raitingLiteral.Keys.Max();

               return raitingLiteral[maxScore];

           }

           return null;

       }

       private static int CountUnsatClauses(Expression e)

       {

           List<List<Literal>> clauses = new List<List<Literal>>();

           foreach (var clause in e.Clauses)

           {

               bool temp = false;

               foreach (var lit in clause)

               {

                   temp = temp || (lit.Not) ? !lit.Value.Value : lit.Value.Value;

               }

               if (!temp)

                   clauses.Add(clause);

           }

           return clauses.Count;

       }

       private static bool IsSat(Expression e)

       {

           List<bool> temp = new List<bool>();

           temp.Add(true);

           foreach (var list in e.Clauses)

           {

               foreach (Literal l in e.Literals)

               {

                   if (l.Value == null)

                       return false;

               }

               bool result = list[0].Not ? !list[0].Value.Value : list[0].Value.Value;

               for (int i = 1; i < list.Count; i++)

               {

                   bool intermed = list[i].Not ? !list[i].Value.Value : list[i].Value.Value;

                   result = result || intermed;

               }

               temp.Add(result);

           }

           bool res = temp[0];

           for (int i = 1; i < temp.Count; i++)

               res = res && temp[i];

           return res;

       }

   }

Тест:

Для наглядного примера возьмем простое выражение (а) ^ (a), которое является выполнимым и выражение (a) ^ (!a), которое является не выполнимым.

Результаты:

Исследование T(n).

 

T(n)

N

DPLL

GSAT

5

210012

190011

170009

160009

150008

160009

190010,6667

156675,3333

10

410021

180011

220013

170010

160009

180010

270015

170009,6667

15

370022

490028

600024

220018

200012

329085

486691,3333

249705

20

990056

2380145

640380

240018

260022

300054

1336860,333

266698

25

1240071

2590171

6810389

320018

200012

429085

3546877

316371,6667

30

5150234

910123

19821134

520064

300012

723055

8627163,667

514377

50

20000000

20000000

20000000

580018

600012

880001

20000000

686677

100

40000000

40000000

40000000

620325

870138

830047

40000000

773503,3333

500

200000000

200000000

200000000

1490085

1710081

540031

200000000

1246732,333

1000

400000000

400000000

400000000

2920167

1830105

1420081

400000000

2056784,333

T(max) = 2056784,333, max = 1000.

3. СРАВНЕНИЕ.

 

T(n)

Результаты

N

DPLL

GSAT

DPLL

GSAT

5

210012

190011

170009

160009

150008

160009

True

True

190010,6667

156675,3333

10

410021

180011

220013

170010

160009

180010

True

True

270015

170009,6667

15

370022

490028

600024

220018

200012

329085

False

True

486691,3333

249705

20

990056

2380145

640380

240018

260022

300054

False

True

1336860,333

266698

25

1240071

2590171

6810389

320018

200012

429085

False

True

3546877

316371,6667

30

5150234

910123

19821134

520064

300012

723055

False

True

8627163,667

514377

50

 

 

 

580018

600012

880001

False

True

0

686677

100

 

 

 

620325

870138

830047

False

True

0

773503,3333

500

 

 

 

1490085

1710081

540031

False

True

0

1246732,333

1000

 

 

 

2920167

1830105

1420081

False

True

0

2056784,333

По результатам тестов видно, что алгоритм DPLL выполняется за не полиномиальное время. Алгоритм GSAT в наилучшем случае выполнялся за линейное время, в наихудшем же случае время равно n3.

Точность решения   для разных  N

ε=100l(St - Sp)l/St

Точность решения

5

100

10

100

15

0

20

0

25

0

30

0

50

0

100

0

500

0

1000

0

Время решения   для разных  N

ε=100l(Tt - Tp)l/Tt

Время решения

5

150000

10

170000

15

250000

20

270000

25

320000

30

520000

50

690000

100

780000

500

1250000

1000

2100000

Скриншоты программы.

Выводы

В данной курсовой работе были рассмотрены основные теоретические вопросы по задаче «Проблема выполнимости». Реализованы методы решения поставленной задачи. Приведен текст программы, позволяющей решить задачу полным методом и не полным методом, также ее программная реализация написанная на языке С#.

По результатам исследования была установлена не полиномиальная зависимость полного алгоритма и полиномиальная зависимость приближенного, а так же определенны максимально возможные числа переменных для обоих.

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

 

СПИСОК ЛИТЕРАТУРЫ

  1.  Вентцель Е.С. Исследование операций: задачи, принципы, методология. – М.: Высшая школа, 2004. – 208 с.
  2.  Исследование операций в экономике/ Под ред. Кремера Н.Ш. – М.:ЮНИТИ, 2004. – 407 с.
  3.  Конюховский П.В. Математические методы исследования операций в экономике. Краткий курс. – СПб.: Питер, 2002. – 208 с.
  4.  Просветов Г.И. Математические методы в экономике: Учебно-методическое пособие. – М.: Издательство РДЛ, 2004. – 160 с.
  5.  Орлова И.В. Экономико-математическое моделирование: Практическое пособие по решению задач. – М.: Вузовский учебник, 2004. – 144 с.
  6.  Костевич Л.С. Математическое программирование: Информационные технологии оптимальных решений. – Мн.: Новое знание, 2003. – 424 с.
  7.  Акулич И.Л. Математическое программирование в примерах и задачах. – М.: Высшая школа, 1986. – 319 с.




1. 3107 рублей Если целью использования является выбор программы с минимальными затратами то наиболее желате
2. 31122 Составители И
3. РЕФЕРАТ дисертації на здобуття наукового ступеня кандидата економічних наук Донец
4. Курсовая работа- Организационные формы бухгалтерского учета на предприятии и их совершенствование в условиях рынка
5. мертвых пальцев особенно белеют II и IV пальцы обеих рук
6. реферат дисертації на здобуття наукового ступеня кандидата технічних наук Тернопіль 199
7. Развитие агропромышленного комплекса страны
8. Понятие и содержание конституционного строя
9. Трасса Аляска-Сибирь
10. Лабораторная работа Тема 4
11. Тема- Затраты как один из объектов управленческого учета Выполнила студен
12. Однако здесь мы хотим обсудить только один из них а именно- должен ли грамматист и если должен то в каком см
13. Баобаб
14. Прогноз и оценка значимости воздействий на окружающую среду
15. Контрольная работа по дисциплине Бухгалтерский учет и анализ заочное отделение Вариант 1 Задача 1
16. Реферат на тему- Ультразвуковая диагностика в акушерстве
17. ЕКОНОМІКОПРАВОВИЙ ТЕХНІКУМ ПРИ МІЖРЕГІОНАЛЬНІЙ АКАДЕМІЇ УПРАВЛІННЯ ПЕРСОНАЛОМ
18. Проблема бытия Теория познания
19. тема 11 Prents nd Children One of the importnt problems of ll times is genertion gp
20. Антропометрические и физиологические характеристики человека