3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
|
1 | |
Покрытие множеств19.01.2010, 18:22. Показов 8011. Ответов 37
Метки нет Все метки)
(
Добрый день, новичок на этом форуме =)
нуждаюсь в помощи с задачей на покрытия множеств. Дано множество ![]() нужно двумя алгоритмами (полного и граничного переборов) вычислить полные покрытия и "лишние" покрытия. как можно наиболее оптимально осуществить полный и граничный перебор? ведь это 2^n вариантов.. Думал еще над способом с битными масками, но нигде не нашел ничего подобного. Буду очень благодарен за помощь. Добавлено через 35 минут я прошелся по разделу и понял, что может быть я не туда запостил? ![]() если да, то пусть модераторы перенесут тему в раздел "С\С++", а то вроде не совсем "начинающая" задачка. благодарю
0
|
|
19.01.2010, 18:22 | |
Ответы с готовыми решениями:
37
Минимальное реберное покрытие графа Найти покрытие полным перебором Определить, существует ли покрытие C' из C мощности не более K Покрытие шахматной доски ходом коня |
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
|
19.01.2010, 22:08 [ТС] | 3 |
извините, забыл указать, что последний столбец - цена множества. после нахождения покрытий также можно находить самое дешевое.
0
|
1177 / 987 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
|
||||||
20.01.2010, 11:25 | 4 | |||||
Перебор почти полный (отбрасываются остатнии множества, когда все покрыто). Если N>=32, тогда надо находить другое представление множеств. 1) Как массива long и сделать маленькие фунциклюшки работы с битами для массива (присвоение i-того бита, проверка i-того бита, сравнение двух массивов и т.д.) 2) Как строки символов равных 1 или 0. Легче для программирования, но неэкономно по памяти (в 8 раз)
1
|
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
|
20.01.2010, 15:30 [ТС] | 5 |
спасибо! я именно пример этого способа и искал)
буду признателен если подробнее поможете разобраться ![]() U |= (1L<<i); это битовый сдвиг влево на позицию "i" с доставкой "1" бита в конец? таким образом у нас будет выходить тоесть Я так понял, что этот кусочек не есть кодом программы пока что без осмысления этих вещей не могу пройтись далее по коду. =)
0
|
![]() 3685 / 962 / 114
Регистрация: 10.01.2010
Сообщений: 2,550
|
|
20.01.2010, 15:39 | 6 |
1011 0011 0000 1110 // A[i]
& 0000 0000 0000 1000 // == //0000 0000 0000 0001 << 3 // 1L << 3 Результат: 1&1 = 1 1011 0011 0000 1110 // A[i] & 0000 0000 0001 0000 // == //0000 0000 0000 0001 << 4 // 1L << 4 Результат: 0&1 = 0 На самом деле & пробегает по всем битам, однако т.к. остальные биты нулевые в нашем 1L то результат тоже будет нулевым для других бит. Вроде так =))
1
|
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
|
20.01.2010, 15:49 [ТС] | 7 |
insideone, спасибо, это понял)
осталось понять формат массива A[n]
0
|
1177 / 987 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
|
|
21.01.2010, 12:31 | 8 |
U |= (1L<<j) - Да это так.
В U получается столько единиц, какова мощность всего множества (A[j] & (1L<<j)) == 1 - Простите, ошибочка моя Правильно (A[j]&(1L<<j)) != 0 Или ((A[j]>>j) & 1) == 1 Для твоего примера A = 10100010 B = 101001010 .... Рекомендация. Осторожнее с битовыми операциями! В C приоритеты не очень логично проставлены На всякий случай заключайте их в скобки У == приоритет больше, чем у && Но если скобок не жалеть - все будет хорошо
0
|
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
||||||
21.01.2010, 16:49 [ТС] | 9 | |||||
я правильно понял как должны задаться множества?
0
|
1177 / 987 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
|
|
22.01.2010, 10:58 | 10 |
Вроде, все правильно.
Только этот кусочек мы то с тобой понимаем, а транслятор может и не понять Код
long A[7] = { 0xA2, 0x14A, 0x63, 0x124, 0x51, 0xD, 0xb5 }; (Мог ошибиться в циферках)
0
|
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
|
22.01.2010, 16:06 [ТС] | 11 |
да, только 3ий елемент 0х33.
тестирую вот программу. выводит: ![]()
0
|
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
||||||
22.01.2010, 18:32 [ТС] | 13 | |||||
извините) я думал, что запостил)
0
|
1177 / 987 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
|
||||||
23.01.2010, 00:08 | 14 | |||||
Основная ошибка - было перепутано N и n
Окромя того я все делал на чистом С, а он, дурачок, не понимает объявлений переменных внутри функции, только в начале понимает С++ и вся его мощь тут не нужны. Так что переставил кой чего
Если что-то будет не так - вставляй отладочные печати непонятных переменных Если печатей этих будет слишком много: перенаправь стандартный вывод: ...exe >файл ЗЫ. 1. Какова причина замена русских слов латиницей? Ты здесь не один такой - так очень многие делают. Т.е. причина какая-то есть. Мне интересно - какая. 2. Пожалуйста! (и всем, кому сможешь, передай) Старайтесь делать грамотно отступы. Чтобы операторы одного блока (между { ... } ) начинались друг под другом Мучительно разбираться в проге с отступами в стиле шаляй-валяй. Ты и сам когда-нибудь это поймешь. Когда я вижу в коде этот раскардаш, как правило, тут же тему пропускаю. Тебе повезло - задачка любопытная, и я нашел в ней новый ход.
0
|
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
|
23.01.2010, 00:31 [ТС] | 15 |
1. Borland C под Dos понимает русские слова только под утилитой keyrus =)
2. *позор* я понимаю это и сам часто одногрупникам обьясняю, но в таких программах, где мало кода частенько забываю об этом) да, очень благодарен за то, что взялись помочь ![]() сейчас буду проверять. Добавлено через 7 минут вот первое же покрытие выдало : A B C D, неправильное. но второе A B D E правильное. третим повторило A B C D 4 - A B C F, тоже правильное 5 - опять повторило A B C D 6 - A B E F, правильное ну вот пока видно, что только на A B C D проштрафилось..
0
|
1177 / 987 / 83
Регистрация: 29.10.2009
Сообщений: 1,385
|
||||||
23.01.2010, 12:07 | 16 | |||||
В тех местах, где есть подозрения... Добавлено через 8 часов 53 минуты Все конечно, не очень хорошо. Очень много повторов, и это естесственно для этого алгоритма. Как их убрать? Первое, что приходит в голову - запоминать сделанные покрытия и сравнивать, не перекрывает ли текущее X его. (Критерий того, что B есть подмножество множества A : ((A^B)^A)==0 ) Но это требует неизвестно сколько памяти... Наверное, есть другой способ, через рекурсию, дайте немного подумать... Добавлено через 21 минуту Ошибся в критерии Надо ( ((A^B) & (|A)) == 0) ^ - исключающее ИЛИ |A - НЕ A Добавлено через 1 час 42 минуты Удалось таки сделать приличную прогу. И без повторов и с отбрасыванием ненужного
Код
A B C D s=8.000000 A B C F s=8.000000 A B C G s=9.000000 A B D E s=7.000000 A B D F G s=11.000000 A B D G s=9.000000 A B E F s=7.000000 A B E G s=8.000000 A B F G s=9.000000 A B G s=7.000000 A C D E F s=8.000000 A D E F s=6.000000 B C D G s=10.000000 B C F G s=10.000000 B C G s=8.000000 B D E G s=9.000000 B D F G s=10.000000 B D G s=8.000000 B E F G s=9.000000 B E G s=7.000000 B F G s=8.000000 B G s=6.000000 C D E F G s=10.000000
1
|
3 / 3 / 1
Регистрация: 19.01.2010
Сообщений: 26
|
|
23.01.2010, 17:47 [ТС] | 17 |
оо, вообще супер. правда выходит так, что оно все-таки делает повторы.
я имею ввиду с множествами, которые входят в предыдущие. B G входит в A B E G ну наверно с этим ничего не поделать, так что спасибо и за это ![]()
0
|
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 6
|
|
23.01.2010, 18:29 | 18 |
прошу прощения пост вышел совершенно случайно и был удален
0
|
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 6
|
|
23.01.2010, 18:53 | 20 |
0
|
23.01.2010, 18:53 | |
Помогаю со студенческими работами здесь
20
Доказать равенство множеств с помощью основных законов алгебры множеств Поменять местами значения множеств a и b без использования дополнительных множеств
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |