[WT] [Архив] [Поиск] Главная Управление
[Совместно с Ычаном]

[Назад]
Ответ в нить
Имя
Animapcha image [@] [?]
Тема   ( ответ в 6142)
Сообщение flower
Файл 
Пароль  (для удаления файлов и сообщений)
Параметры   
  • Прежде чем постить, ознакомьтесь с правилами.
  • Поддерживаемые типы файлов: 7Z, BZ, BZ2, GIF, GZ, JPG, MO, MP3, OGG, PDF, PNG, PSD, RAR, SVG, SWF, TXT, XCF, ZIP
  • Максимально допустимый размер файлов: 10000 кБ.
  • Изображения, размер которых превышает 200 на 200 пикселей, будут уменьшены.
  • Ныне 1271 unique user posts. Посмотреть каталог
  • Радио:

Файл: 132774731419.jpg-(44.52KB, 450x299, 123421421.jpg)
6142 No. 6142 watch    
Есть один вопрос по питону- он простой, кажется, и я не студентота. Я тут пытаюсь немного кодить, сам для своих личных целей, и решаю одну задачку связанную с матрицей. Во время исполнения программы, цикл вида:
for i in range(1, n):
for j in range(1, m):
...

проходит все ячейки матрицы, поочередно. И вот может такое случится, несколько раз во время исполнения, что в какой то момент текущая строка матрицы (та, которую мы в данный момент проходим, то есть i-ая) должна быть пройдена заново. Т.е. мы идем по пятой, например, строчке, доходим до шестого столбца, значение соответствующего элемента переключает какой- то флаг и мы должны опять переместится на первый элемент пятой строки и проходим её заново.
Это возможно? В книжке "Г. Россум, Ф.Л.Дж. Дрейк: Язык программирования Python" прямо написано, что изменять итерируемую переменную в теле такого цикла нельзя. Что же, это невозможно?

Вообще, если что я тред удалю, но было бы здорово, если бы это стал пион- тред. Выложу свою поделку, когда закончу.
Развернуть все изображения
>> No. 6143    
Надо делать c while-ом, ящитаю.
Никогда не кодил на питоне*
while (i>n){
for (j=0;j>mj++){
..
if(flag==1) break;
}
if (flag!=1) i++;
}
Как-то так, надеюсь алгоритм понятен.
>> No. 6144    
>>6142
Ну если нельзя, городи велосипед с while, в чём проблемы?
>> No. 6148    
Переменную менять можно, но она будет опять переназначена, в начале следующего цикла for.

Для твоего примера:
for i in матрица:
 while flag:
  for j in i:
   #будет проходить строку i, пока flag

Если же тебе нужен случайный доступ к элементам матрицы, то скорее всего придётся городить велосипед из while (зависит от сложности алгоритма выбора следующей строки).
>> No. 6149    
>>6142

чаво бы не сделать
i =0
while (i<max)
{
j=0;
while (j<max)
{
делаем тут обработку.
если что, меняем i на нужное значение.
}
i=i+1;
}
Такое на летающем цирке проканывает?
>> No. 6157    
Спасибо всем за быстрые советы, честно говоря я как то не подумал о while. В итоге сделал всё таки как >>6149 предложил. Сейчас запощу что вышло- а вышло, по моему совсем неплохо.
>> No. 6159    
http://pastebin.com/bUhYu1za

Так вот, это генератор латинских квадратов 9х9, короче говоря судоку. Захотелось написать его, потому что во время чтения книжки, которую упоминал в ОП посте мне в голову пришла идея, которая быстро оформилась в алгоритм генерирования судоку, который, как мне казалось, должен был заполнять все ячейки с первого раза, т.е. ровно за 81 итерацию.
Если бегло подумать о задаче судоку, то первое, что приходит на ум, это просто случайно вносить числа поочередно во все ячейки матрицы и каждый раз проверять, не стоит ли это число в соответствующей вертикали/горизонтали/блоке (области 3х3). И если стоит, выбрать число заново. И так каждый раз. Пока не заполнится вся матрица.
Как- то не очень.
Короче говоря, я вот что придумал.
У нас есть мешочек с шариками от 1 до 9. Мешаем, вытягиваем шарик, записываем число в первую ячейку матрицы. Затем берем три таких же как вытянутый шарика и добавляем в три дополнительных мешочка - один отвечает за соответствующую горизонталь (для первого элемента она первая) другой- вертикаль (то же первая) и третий за соответствующий блок. Затем сдвигаемся на одну ячейку вправо и проверяем соответствующие ей мешочки... Оба на, а мешочка то только два- отвечающий за первую горизонталь и за первый блок! И число в них одно и то же! Мы шарим в нём рукой и достаем шарики которые в нем есть (для второго элемента шарик только один). Смотрим, что это за шарик, убираем его обратно в мешочек и достаем из нашего главного мешочка точно такой же. Теперь в главном мешочке только 8 шариков и мы можем смело тянуть один из них наугад и он совершенно точно не совпадет с тем, который мы вытянули в первой ячейке! После того, как мы его вытянули, мы, естественно, кладем шарики с той же цифрой в мешочек первой горизонтали, мешочек второй вертикали и мешочек первого блока (представьте, что мы пронумеровали блоки 3 на 3 как на пикрелейтеде). Вносим число в ячейку, добавляем шарики в мешочке из которого тянем. Затем сдвигаемся ещё на одну ячейку вправо и проводим ту же операцию. И так для каждого элемента в матрице. Что у нас получается?
К концу матрицы, у нас будет куча почти полностью забитых мешочков, а в мешочке из которого мы наугад тянем шарики будет очень мало этих самых шариков. Но каждый раз мы будем вытягивать только такое число, которое можно поставить в текущую ячейку, в том смысле, что оно не будет повторять чисел по вертикали, горизонтали и в текущем блоке. Потому что перед тем как тянуть, мы просто убрали все уже записанные в вертикали, горизонтали и блок шарики из мешка.
Извините, за стену текста, но когда мне это пришло в голову, мне показалось, что это очень удачно и я мыслил именно таким образом- мешочки, шарики.
>> No. 6160    
Файл: 132785189787.gif-(55.56KB, 357x311, Untitled.gif)
6160
>>6159
Ну так вот. Когда я все это накалякал, оказалось, что ничего не работает. Просто потому, что через пару заполненных строчек, в мешочке, из которого мы тянем шарики, не остается этих шариков. Очень жаль, но такой непростой математический объект нельзя создать таким простым алгоритмом. Поэтому пришлось добавить очень грубый блок кода, который, в случае, если в мешочке нет шариков, стирает всю текущую строку и заполняет её заново. И надеется, что на этот раз все получится. И так действительно и получается- со второго раза практически всегда заполняется правильно. Можете попробовать закомментить участок кода с 91 строки по 100ую и увидите как это происходит. Можно добавить в этот участок счетчик и вывести его, чтоб увидеть, сколько строчек с первого раза не заполнились. Для матрицы 9х9, т.е. классического судоку, такая ситуация встречается обычно два- три раза, так что приходится пройти некоторые строчки дважды. В принципе, это ничего, но не очень хорошо.
Кто может придумать алгоритм, в котором подобное будет не нужно?
>> No. 6161    
>>6160
Вот ещё что- я теперь попробую написать псевдографический интерфейс и поправить код для матрицы nxn. Должно получится.
>> No. 6167    
Пустую матрицу удобнее создавать так:
self.matrix=[['']⚹cols]⚹rows

if List == [] пишется как if not List.
if List.count(ListHor[i][n]) > 0 это if ListHor[i][n] in List:

list(range(1, 10)) - range и так возвращает list.
для for n in range, лучше юзать xrange (быстрее, занимает меньше памяти).

flag нигде не используется?

> если в текущей горизонтали уже есть какие то числа, то
> вычитаем их из List (в котором просто числа 1..9)
для этих целей хорошо подходят коллекции
List=set(range(1,10))
List.difference_update( ..всё что ты хочешь удалить.. )

http://docs.python.org/library/stdtypes.html#set

и вместо словарей можно юзать вложенные списки
ListHor=ListVer=ListBlock=[[]]*10
>> No. 6169    
>>6167
>if List == [] пишется как if not List.
>if List.count(ListHor[i][n]) > 0 это if ListHor[i][n] in List:
>list(range(1, 10)) - range и так возвращает list.
Не знал. Последнюю конструкцию в таком виде в книжке увидел.
>List=set(range(1,10))
>List.difference_update( ..всё что ты хочешь удалить.. )
>http://docs.python.org/library/stdtypes.html#set
А вот это просто круто!
>и вместо словарей можно юзать вложенные списки
А разве будет особая разница?

Кстати я тут провел небольшое статистическое исследование и оказалось что примерно 10% матриц не генерируются по такому алгоритму вообще. Как бы иногда получается такая строка, что как в ней цифры не переставляй, все равно не получится то, что надо. Это вообще облом. Думаю над другими способами.
>> No. 6170    
>>6167
> Пустую матрицу удобнее создавать так:
> self.matrix=[['']⚹cols]⚹rows
на самом деле - self.matrix=map(list,[['']⚹cols]⚹rows)
self-fix

>>6169
> А разве будет особая разница?
В функциональности почти - нет, в производительности да.
И не совсем понятна их функция, почему нельзя читать, уже использованные значения, сразу из матрицы?

http://pastebin.com/nxhWnSW3
>> No. 6183    
>>6170
>почему нельзя читать, уже использованные значения, сразу из матрицы
Ну да, можно. Ну мало ли, может я буду это не в одну матрицу, а в несколько? Но вообще да, экономней наверно будет.
А вообще я думаю над другим способом, чтоб от рандома не зависело. Пока ничего не вышло.
[Назад]


Удалить сообщение []
Пароль  
[Mod]