Недостатки и профессионалы smartGWT

Вы можете сохранить список наборов для используемых значений столбцов. Проверка новой «перетасованной» линии может быть проведена более напрямую. То же самое для групп подматриц, хотя вам нужно использовать косвенное направление (или сложный расчет индекса) для сопоставления позиций с наборами групп:

import random

def createMatrix():
    matrix  = []
    numbers = [1,2,3,4,5,6,7,8,9]
    groups  = [ [0,0,0, 1,1,1, 2,2,2] ] * 3
    groups += [ [3,3,3, 4,4,4, 5,5,5] ] * 3
    groups += [ [6,6,6, 7,7,7, 8,8,8] ] * 3
    while len(matrix) < 9:
        matrix    = []
        colSets   = [ set() for _ in range(9) ]
        groupSets = [ set() for _ in range(9) ]
        for row in range(9):
            for _ in range(133496): # try multiple permutations for row (36.79%)
                random.shuffle(numbers)
                if any( n in used for n,used in zip(numbers,colSets) ):
                    continue # column conflict
                if any( n in groupSets[g] for n,g in zip(numbers,groups[row]) ):
                    continue # sub-matrix group conflict
                matrix.append(numbers.copy())
                for n,used in zip(numbers,colSets):     used.add(n)
                for n,g    in zip(numbers,groups[row]): groupSets[g].add(n)
                break
            if len (matrix) == row: break # restart if failed to produce a row
    return matrix

sudoku = createMatrix()
for line in sudoku:
    print(line)

Если вы пытаетесь сгенерировать случайный латинский квадрат, более быстрым методом было бы рандомизировать рабочую базовую линию, а не итеративно проверять достоверность наборов случайных чисел в процессе проб / ошибок:

import random

numbers = random.sample(range(1,10),9)
cols    = random.sample(range(9),9)
rows    = random.sample(range(9),9)
matrix  = [[numbers[(r+c)%9] for c in cols] for r in rows]

for line in matrix: print(line)  

[8, 9, 1, 7, 6, 4, 5, 3, 2]
[5, 2, 9, 6, 4, 3, 1, 8, 7]
[2, 4, 6, 8, 5, 1, 7, 9, 3]
[1, 7, 2, 4, 3, 8, 9, 5, 6]
[7, 3, 4, 5, 1, 9, 6, 2, 8]
[3, 1, 5, 2, 7, 6, 8, 4, 9]
[4, 5, 8, 9, 2, 7, 3, 6, 1]
[9, 6, 7, 3, 8, 5, 2, 1, 4]
[6, 8, 3, 1, 9, 2, 4, 7, 5]

Чтобы объяснить это, лучше начать с простая матрица последовательных индексов, где каждая строка смещена на одну единицу больше, чем предыдущая строка:

matrix = [ [(r+c)%9 for c in range(9)] for r in range(9) ]

[0, 1, 2, 3, 4, 5, 6, 7, 8] # base row
[1, 2, 3, 4, 5, 6, 7, 8, 0] # offset by 1
[2, 3, 4, 5, 6, 7, 8, 0, 1] # offset by 2
[3, 4, 5, 6, 7, 8, 0, 1, 2] # ....
[4, 5, 6, 7, 8, 0, 1, 2, 3]
[5, 6, 7, 8, 0, 1, 2, 3, 4]
[6, 7, 8, 0, 1, 2, 3, 4, 5]
[7, 8, 0, 1, 2, 3, 4, 5, 6]
[8, 0, 1, 2, 3, 4, 5, 6, 7]

Как вы можете видеть, каждая строка имеет индексы от 0 до 8 (поэтому нет повторений), и каждый столбец также имеет индексы 0 до 8 без повторения из-за смещения.

Теперь, если мы создадим список чисел от 1 до 9 и перетасуем его, мы можем заменить индексы в матрице на соответствующие числа в перетасованном списке. Поскольку каждый индекс отображается на другое число, результирующая матрица не будет иметь повторений в строках или столбцах.

numbers = random.sample(range(1,10),9) # [1, 5, 9, 8, 3, 7, 6, 2, 4]
matrix  = [ [numbers[i] for i in row] for row in matrix ]

[1, 5, 9, 8, 3, 7, 6, 2, 4]
[5, 9, 8, 3, 7, 6, 2, 4, 1]
[9, 8, 3, 7, 6, 2, 4, 1, 5]
[8, 3, 7, 6, 2, 4, 1, 5, 9]
[3, 7, 6, 2, 4, 1, 5, 9, 8]
[7, 6, 2, 4, 1, 5, 9, 8, 3]
[6, 2, 4, 1, 5, 9, 8, 3, 7]
[2, 4, 1, 5, 9, 8, 3, 7, 6]
[4, 1, 5, 9, 8, 3, 7, 6, 2]

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

random.shuffle(matrix)

[5, 9, 8, 3, 7, 6, 2, 4, 1]
[9, 8, 3, 7, 6, 2, 4, 1, 5]
[1, 5, 9, 8, 3, 7, 6, 2, 4]
[7, 6, 2, 4, 1, 5, 9, 8, 3]
[2, 4, 1, 5, 9, 8, 3, 7, 6]
[6, 2, 4, 1, 5, 9, 8, 3, 7]
[4, 1, 5, 9, 8, 3, 7, 6, 2]
[8, 3, 7, 6, 2, 4, 1, 5, 9]
[3, 7, 6, 2, 4, 1, 5, 9, 8]

и столбцов:

cols   = random.sample(range(9),9) # [7, 4, 3, 0, 8, 1, 2, 5, 6]
matrix = [[matrix[r][c] for c in cols] for r in range(9)]

[4, 7, 3, 5, 1, 9, 8, 6, 2]
[1, 6, 7, 9, 5, 8, 3, 2, 4]
[2, 3, 8, 1, 4, 5, 9, 7, 6]
[8, 1, 4, 7, 3, 6, 2, 5, 9]
[7, 9, 5, 2, 6, 4, 1, 8, 3]
[3, 5, 1, 6, 7, 2, 4, 9, 8]
[6, 8, 9, 4, 2, 1, 5, 3, 7]
[5, 2, 6, 8, 9, 3, 7, 4, 1]
[9, 4, 2, 3, 8, 7, 6, 1, 5]

Решение (выше) объединяет эти входит в понимание единого списка, но использует точно такой же подход.

Используя этот подход, также возможно создать случайную доску судоку (с ограничением блока 3х3). Формула для смещений немного сложнее, и перетасовка строк и столбцов может быть выполнена только внутри и между группами блоков, но общий метод остается тем же.

from random import sample
base  = 3  # Will generate any size of random sudoku board instantly
side  = base*base
nums  = sample(range(1,side+1),side) # random numbers
board = [[nums[(base*(r%base)+r//base+c)%side] for c in range(side) ] for r in range(side)]
rowGr = sample(range(base),base) # random rows/horizontal blocks
rows  = [ r for g in rowGr for r in sample(range(g*base,(g+1)*base),base) ] 
colGr = sample(range(base),base) # random column/vertical blocks
cols  = [ c for g in colGr for c in sample(range(g*base,(g+1)*base),base) ]            
board = [[board[r][c] for c in cols] for r in rows]

for line in board:print(line)
[7, 5, 3, 6, 9, 4, 1, 2, 8]
[6, 9, 4, 1, 2, 8, 7, 5, 3]
[1, 2, 8, 7, 5, 3, 6, 9, 4]
[2, 8, 7, 5, 3, 6, 9, 4, 1]
[5, 3, 6, 9, 4, 1, 2, 8, 7]
[9, 4, 1, 2, 8, 7, 5, 3, 6]
[8, 7, 5, 3, 6, 9, 4, 1, 2]
[3, 6, 9, 4, 1, 2, 8, 7, 5]
[4, 1, 2, 8, 7, 5, 3, 6, 9]

Это производит случайное судоку 9x9 за 0,2 миллисекунды по сравнению с методом проб / ошибок, который занимает от 1 до 20 секунд (очень случайное время)

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

base  = 3
side  = base*base
board = [[(base*(r%base)+r//base+c)%side for c in range(side)] for r in range(side)]

for line in board: print(line)

[0, 1, 2, 3, 4, 5, 6, 7, 8] # base row
[3, 4, 5, 6, 7, 8, 0, 1, 2] # offset by 3
[6, 7, 8, 0, 1, 2, 3, 4, 5] # offset by 6
[1, 2, 3, 4, 5, 6, 7, 8, 0] # offset by 1
[4, 5, 6, 7, 8, 0, 1, 2, 3] # offset by 4
[7, 8, 0, 1, 2, 3, 4, 5, 6] # offset by 7
[2, 3, 4, 5, 6, 7, 8, 0, 1] # offset by 2
[5, 6, 7, 8, 0, 1, 2, 3, 4] # offset by 5
[8, 0, 1, 2, 3, 4, 5, 6, 7] # offset by 8

Остальное - просто замена индексов перемешанными числами и перемешивание столбцов и блоков строк .

27
задан skaffman 11 December 2010 в 21:31
поделиться

6 ответов

Думаю, у вас уже есть ответы, но я хотел бы добавить еще несколько комментариев, которые могут повлиять на ваше решение:

Плюсы:

  • SmartGWT - это ] самая объемная библиотека виджетов на основе LGPL GWT, которую вы только можете найти. Так что, если вам небезразлична боль, связанная с GPL, это ваша вещь
  • Комплексная витрина.
  • Действительно хорошая производительность (просто проверьте Showcase).
  • Очень активное сообщество на форумах.
  • Расширения SmartGWT - еще один важный проект. Например, он поддерживает связь на основе GWT-RPC, что невозможно только со SmartGWT (если вы не реализуете свою собственную интеграцию).
  • Ребята из SmartGWT развивают быстрые темпы. Просто посчитайте количество выпусков с момента появления проекта SmartGWT.

Минусы:

  • Помимо Showcase, Иногда мне кажется, что единственный способ выяснить, как что-то работает, - это спросить на форуме. Это приводит к расширению базы знаний. Вики-сайт сообщества был бы предпочтительнее.
  • Большое количество статических файлов, которые вы должны использовать с вашим приложением (знаменитый каталог sc), что может привести к проблемам, если ваша серверная часть находится в GAE (из-за 1000 файлов предел).
21
ответ дан 28 November 2019 в 04:52
поделиться

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

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

Является ли интеграция источников данных такой же полезной, как утверждает команда smartClient?

Данные (JSON / XML) могут предоставляться службами сервлетов, и они понимаются виджеты.

Какие методы вы используете, чтобы сделать ваше приложение smartGWT постоянным? например, как хорошо Hibernate и smartGWT взаимодействуют друг с другом?

В сервисах серверных сервлетов GWT вы можете сохранять данные в хранилище, используя любой постоянный уровень в Java. Hibernate можно использовать так же, как и обычное Java-приложение.

8
ответ дан 28 November 2019 в 04:52
поделиться
Считаете ли вы, что предоставленные виджеты хорошо интегрированы? Есть ли какой-нибудь виджет, который вам особенно не хватает?

Да. Виджеты имеют согласованный API и хорошо работают вместе.

Является ли интеграция источников данных такой же полезной, как утверждает команда smartClient?

Эта IMO - одна из их сильнейших функций. Как только вы начнете использовать их Datasource API, вы поймете, как мало кода требуется для получения полнофункционального экрана CRUD

Какие методы вы используете, чтобы сделать ваше приложение smartGWT постоянным? Например, насколько хорошо Hibernate и smartGWT взаимодействуют друг с другом?

Hibernate работает "из коробки" с версией SmartGWT EE. С версией LGPL использование Glead работает хорошо

6
ответ дан 28 November 2019 в 04:52
поделиться
  • Сталкивались ли вы с какими-либо проблемами при разработке приложения, вызванными фреймворком?

Да. Когда я объединил плагин Google Eclipse, SmartGWT, GWT 1.6.4 и Wicket, компилятор gwt выдавал плохой javascript. Под плохим javascript я подразумеваю javascrip, который не работает в webkit или firefox. Мне не удалось получить хороший javascript, пока я полностью не удалил его из проекта Eclipse и не перезапустил Eclipse. Таким образом, эта комбинация не сработала, и в итоге я создал часть SmartGWT отдельно в другом проекте. Другая проблема заключается в том, что смарт-клиент, похоже, хочет контролировать всю страницу в смысле css. Итак, встроенный модуль SmartGWT был испорчен, потому что стили не были изолированы должным образом. Ваш пробег может отличаться.

Лично, если вы используете только SmartGWT и для всего, то, скорее всего, все будет хорошо, но если вы попробуете смешать его, то мои результаты были катастрофическими. Так что я им больше не пользуюсь.

3
ответ дан 28 November 2019 в 04:52
поделиться

Так же, как контрапункт вышеупомянутому плакату, который упомянул проблемы С Wicket форумы SmartClient (forum.smartclient.com) сообщают об успешной интеграции SmartGWT с широким спектром других технологий. Проблемы этого плаката звучат как 1) ошибка GWT, вызывающая плохой JavaScript и 2) конфликты именования CSS между SmartGWT и Wicket, вероятно, ни одна из них не является ошибкой фреймворка. Все имена стилей SmartGWT могут быть переименованы с помощью системы скинов для разрешения любого такого конфликта.

2
ответ дан 28 November 2019 в 04:52
поделиться

Я думаю, что в SmartGWT есть тонна отличных виджетов, но есть и огромная цена. Создайте простой проект на базе SmartGWT и посмотрите, сколько файлов загрузит ваша страница. Это, я думаю, полностью противоречит идеалам нечто вроде GWT. В то время как SmartGWT может быть довольно хорошим вариантом для людей, у которых срок сдачи проекта поджимает, если вы хотите сырую производительность, держитесь от него подальше. Количество HTTP-запросов просто убьет ваше приложение.

.
4
ответ дан 28 November 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: