С Новым годом! Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/71: Рейтинг темы: голосов - 71, средняя оценка - 4.85
0 / 0 / 0
Регистрация: 23.06.2009
Сообщений: 16
1

Алгоритм решения Судоку

23.06.2009, 23:45. Показов 13635. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Интересует алгоритм для программы, которая решает Судоку. Те, что обсуждались тут - не подходят. Мне ненравиться программа которая вылетает если однозначных вариантов подстановки нет.
Знаю, что нужна рекурсия, попытался написать, но мало что получилось (С++):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
bool Sudoku::Anser ()
{
    if (
        Calculation(0,0) && Calculation(0,1) && Calculation(0,2) && Calculation(0,3) && Calculation(0,4) && Calculation(0,5) && Calculation(0,6) && Calculation(0,7) && Calculation(0,8) &&
        Calculation(1,0) && Calculation(1,1) && Calculation(1,2) && Calculation(1,3) && Calculation(1,4) && Calculation(1,5) && Calculation(1,6) && Calculation(1,7) && Calculation(1,8) &&
        Calculation(2,0) && Calculation(2,1) && Calculation(2,2) && Calculation(2,3) && Calculation(2,4) && Calculation(2,5) && Calculation(2,6) && Calculation(2,7) && Calculation(2,8) &&
        Calculation(3,0) && Calculation(3,1) && Calculation(3,2) && Calculation(3,3) && Calculation(3,4) && Calculation(3,5) && Calculation(3,6) && Calculation(3,7) && Calculation(3,8) &&
        Calculation(4,0) && Calculation(4,1) && Calculation(4,2) && Calculation(4,3) && Calculation(4,4) && Calculation(4,5) && Calculation(4,6) && Calculation(4,7) && Calculation(4,8) &&
        Calculation(5,0) && Calculation(5,1) && Calculation(5,2) && Calculation(5,3) && Calculation(5,4) && Calculation(5,5) && Calculation(5,6) && Calculation(5,7) && Calculation(5,8) &&
        Calculation(6,0) && Calculation(6,1) && Calculation(6,2) && Calculation(6,3) && Calculation(6,4) && Calculation(6,5) && Calculation(6,6) && Calculation(6,7) && Calculation(6,8) &&
        Calculation(7,0) && Calculation(7,1) && Calculation(7,2) && Calculation(7,3) && Calculation(7,4) && Calculation(7,5) && Calculation(7,6) && Calculation(7,7) && Calculation(7,8) &&
        Calculation(8,0) && Calculation(8,1) && Calculation(8,2) && Calculation(8,3) && Calculation(8,4) && Calculation(8,5) && Calculation(8,6) && Calculation(8,7) && Calculation(8,8)
        )
        return true;
//  Add (pole_tmp);
    return false;
}
bool Sudoku::Calculation (int I, int K, int C)
{
    if (pole_tmp[I][K])
        return true;
    if (!Verification(I,K,C))   // Перебераються возможные цифры для поля
    {
        if (C<9)
            Calculation (I,K,C+1);
        else
            return false;
    }
    else
    {
        pole[I][K]=C;
        return true;
    }
}
bool Sudoku::Verification(int I, int K, int C)
{
    //----------------------- проверка совпадений по вертикали
    for (int i=I+1;i<9;i++)
    {
        if (pole[i][K]==C)
            return false;
    }
    for (int ii=I-1;ii>=0;ii--)
    {
        if (pole[ii][K]==C)
            return false;
    }
    //----------------------- проверка совпадений по горизонтали
    for (int k=K+1;k<9;k++)
    {
        if (pole[I][k]==C)
            return false;
    }
    for (int kk=K-1;kk>=0;kk--)
    {
        if (pole[I][kk]==C)
            return false;
    }
    return true;
}
Больше интересует алгоритм, зная алгоритм, думаю, программу напишу. По этому строчу сюда
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.06.2009, 23:45
Ответы с готовыми решениями:

Алгоритм решения судоку
Доброго времени суток. Хочу попросить кого-нибудь привести псевдокод или подробное словесное...

Алгоритм генерации судоку - нужна помощь
Сразу извиняюся за возможное повторение темы! Необходима помощь в составлении алгоритма...

Алгоритм решения
Буквально вчера встретил в интернете программу http://ru.akinator.com. Знаю, вышла довольно давно...

Составить алгоритм решения
Помогите пожалуйста составить алгоритм решения. Заранее огромное спасибо !!!! Условие: ...

4
3896 / 899 / 122
Регистрация: 16.04.2009
Сообщений: 1,825
02.07.2009, 16:14 2
У мен где-то был на 1С алгоритм. Вечером гляну.
0
Evg
Эксперт CАвтор FAQ
21280 / 8304 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
02.07.2009, 20:05 3
Для истории
https://www.cyberforum.ru/post203228.html
0
0 / 0 / 0
Регистрация: 07.02.2011
Сообщений: 3
07.02.2011, 15:38 4
Вот мое решение на Java: http://sites.google.com/site/sudokujavasolution/
0
Заблокирован
07.02.2011, 17:12 5
Ну и поносец, няши.
OK. Сжалюсь над немощными.
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
import System.Environment(getArgs)
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Concurrent.Chan
 
 
import Data.Array.Diff
import Data.List(iterate,findIndices,sortBy,(\\),delete)
import qualified Data.IntSet as Set
import Control.Monad.State
import Data.Tree
 
type CellVars = Set.IntSet
type Pole = Array (Int,Int) CellVars
 
empty_pole = listArray ((1,1),(puzzle_size,puzzle_size)) (repeat Set.empty)
 
puzzle_size = 9
diap = [1..puzzle_size]
block_diap = [1..3]
 
resolve_conflict :: State [CellVars] Bool
resolve_conflict = do
  cells <- get
  let definite = findIndices (\c -> Set.size c == 1) cells
      double = findIndices (\c -> Set.size c == 2) cells
      pairs = [(x,y) | x <- double, y <- double, x < y, cells !! x == cells !! y]
  seqWhileM $ map drop_conflicting definite ++ map drop_conflicting_pairs pairs
    
drop_conflicting :: Int -> State [CellVars] Bool
drop_conflicting ind = do
  cells <- get 
  let (prev,cur:next) = splitAt ind cells
      drop_cur = map ( `Set.difference` cur)
      new_cells = drop_cur prev ++ cur : drop_cur next 
  put new_cells
  return $! all (not . Set.null) new_cells
 
drop_conflicting_pairs :: (Int,Int) -> State [CellVars] Bool
drop_conflicting_pairs (x,y) = do
    cells <- get
    let (part1,el1:next) = splitAt x cells
        (part2,el2:part3) = splitAt (y-x-1) next
        pair = cells !! x
        drop_pair = map ( `Set.difference` pair)
        new_cells = drop_pair part1 ++ el1 : drop_pair part2 ++ el2 : drop_pair part3
    put new_cells 
    return $! all (not . Set.null) new_cells
 
resolve_conflicts :: State [CellVars] Bool
resolve_conflicts = stabilize resolve_conflict 
 
-- applies an action until result stop changing or it returns false
stabilize act = do
  old <- get
  flag <- act
  new <- get
  if old == new then return flag
   else if flag then stabilize act
         else return False
    
stabilize_pole :: State Pole Bool
stabilize_pole = stabilize resolve_pole
 
 
seqWhileM :: Monad m => [m Bool] -> m Bool
seqWhileM (x:xs) = do r <- x
                      if r then seqWhileM xs
                       else return False
  
seqWhileM [] = return True
 
resolve_pole :: State Pole Bool
resolve_pole = do
    seqWhileM $ map resolve_row diap ++
                map resolve_col diap ++ 
                map resolve_block [(x,y) | x <- block_diap, y <- block_diap]
 
resolve_row :: Int -> State Pole Bool
resolve_row row_num = let
    coords = zip (repeat row_num) diap
    in resolve_coords coords
 
resolve_col :: Int -> State Pole Bool
resolve_col col_num = let
    coords = zip diap (repeat col_num)
    in resolve_coords coords
 
resolve_block :: (Int,Int) -> State Pole Bool
resolve_block (bx,by) = let
    diap_x = [bx*3-2 .. bx*3]
    diap_y = [by*3-2 .. by*3]
    coords = [(x,y) | x <- diap_x, y <- diap_y]
    in resolve_coords coords
 
get_list :: Pole -> [(Int,Int)] -> [CellVars]
get_list pole coords = map (pole !) coords
 
resolve_coords :: [(Int,Int)] -> State Pole Bool
resolve_coords coords = do
  pole <- get
  let (not_empty, new_cells) = runState resolve_conflicts (get_list pole coords)
      new_pole = pole // (zip coords new_cells)
  put new_pole
  return $! not_empty 
  
build_tree :: Pole -> Tree Pole
build_tree root = unfoldTree build_node root
 
build_node :: Pole -> (Pole, [Pole])
build_node pole = let
    (not_empty, stable_pole) = runState stabilize_pole pole
    cells = assocs stable_pole
    possible_forks = sortBy (compareBy num_vars) . 
                     filter ( (>= 2) . num_vars) $ cells
    (coord,vars) = head possible_forks
    pole_vars = map (\x -> pole // [(coord,Set.singleton x)]) $ Set.elems vars
    in if not_empty 
       then if null possible_forks 
             then (stable_pole, [])
             else (stable_pole, pole_vars)
       else (empty_pole,[])
 where num_vars = Set.size . snd
 
       
compareBy f a b = compare (f a) (f b)
 
find_solutions :: Pole -> [Pole]
find_solutions pole = filter (all (\a -> Set.size a == 1) . elems) $ flatten $ build_tree pole  
 
-- interface
 
time = 49000
 
type EncodedPole = String
main = do
  inp <- getContents
  let (n:puzzles) = lines inp
      indexed = zip [1..(read n)] puzzles
      ranged = map (\(i,p) -> (i, read_pole p)) . sortBy (compare_by (est_difficulty . snd) ) $ indexed
      
  sols_chan <- newChan
  succ_flag <- newEmptyMVar
  forkIO (processor ranged sols_chan succ_flag)
  timeout time (takeMVar succ_flag >> return ())
  
  sols <- read_whole_chan sols_chan 
  let tasks = elems $ (listArray (1,read n) (repeat Nothing) :: Array Int (Maybe EncodedPole)) // sols
 
  mapM_ print_sol tasks
 
compare_by f a b = compare (f a) (f b)
est_difficulty = length . filter (== '.')
 
 
processor :: [(Int,Pole)] -> Chan (Int,Maybe EncodedPole) -> MVar () -> IO ()
processor [] _ flag = putMVar flag ()
processor ((k,p):rest) c flag = do
  let sol = case find_solutions p of
              (s:ss) -> s
              [] -> error "no solutions"
      enc_sol = show_pole sol
  length enc_sol `seq` writeChan c (k,Just enc_sol)
  processor rest c flag
 
read_whole_chan :: Chan a -> IO [a]
read_whole_chan c = do
  e <- isEmptyChan c
  if e then return []
   else do a <- readChan c
           rst <- read_whole_chan c
           return (a:rst)
 
print_sol :: Maybe EncodedPole -> IO ()
print_sol Nothing = putStrLn "N"
print_sol (Just p) = do
  putStrLn "Y"
  putStrLn p
 
read_pole :: String -> Pole 
read_pole s = listArray ((1,1),(puzzle_size,puzzle_size)) . map read_cell $ s
 
show_pole :: Pole -> String
show_pole s = concatMap (show . head . Set.elems) $ elems s
 
read_cell '.' = Set.fromList diap
read_cell d = Set.fromList [read [d]]
 
par_io :: IO a -> IO a -> IO a
par_io t1 t2 = do c <- newEmptyMVar :: IO (MVar a)
                  id1 <- forkIO $ wrapper c t1
                  id2 <- forkIO $ wrapper c t2
                  res <- takeMVar c
                  killThread id1
                  killThread id2
                  return res
    where wrapper :: MVar a -> IO a -> IO ()
          wrapper mvar io = do res <- io
                               putMVar mvar res
 
timeout :: Int -> IO a -> IO (Maybe a)
timeout n t = do res <- par_io timer thr 
                 return res
    where thr = do res <- t
                   return $! Just res
          timer = do threadDelay $ n * 1000
                     return Nothing
0
07.02.2011, 17:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.02.2011, 17:12
Помогаю со студенческими работами здесь

Алгоритм решения задачи
Всем привет! есть задача : Растет Роща реликтовых деревьев.Для их защиты требуется обнести рощу...

Нужен алгоритм решения задачи
Дана квадратная матрица n x n заполнена случайными целыми числами. Надо найти: 1. наименьшие...

Алгоритм решения японских кроссвордов
Сразу к делу - для тех кто не знает что такое ЯК - википедия...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru