2016-03-24 30 views
4

sekans kısıtlamaları için optimizasyon olduğu:3-in-a-satır mantık bulmaca: deneyin ve bu şekilde, mavi ve beyaz kareler ile ızgara doldurmak aşağıdaki bulmaca listeler/diziler

  • A3 Aynı rengin satırında (veya sütununda) izin verilmez.
  • Her satır ve sütun eşit sayıda mavi ve beyaz kareye sahiptir.

    0 _ _ _ 1 _ 
    _ 0 _ _ _ _ 
    _ _ _ _ _ 0 
    1 _ _ 0 _ _ 
    _ _ 1 1 _ _ 
    _ 0 _ _ 1 _ 
    

    Ve biz oldukça hızlı bir şekilde

    0 1 0 0 1 1 
    0 0 1 1 0 1 
    1 1 0 1 0 0 
    1 1 0 0 1 0 
    0 0 1 1 0 1 
    1 0 1 0 1 0 
    

    olduğunu doğrulayabilirsiniz: Biz şimdi 1'den 0 ile beyaz ve mavi temsil ederse

example_puzzle

, biz olsun Bu örnek için çözüm. Belirtilen üst üste Her sekans satır/col ve

constraints(Board,N) :- 
    N2 is N // 2, 
    (for(I,1,N), param(Board,N2,N) 
    do 
     Row is Board[I,1..N], 
     Col is Board[1..N,I], 
     ic_global:sequence_total(N2,N2,1,2,3,Row), 
     ic_global:sequence_total(N2,N2,1,2,3,Col) 
    ). 

sequence_total/6

değeri 1 tam olarak N2 kez gerçekleşmelidir sağlar (N buçuk kat) /: kısıtlamalar olarak

Aşağıdaki yazdım 3 elementin col değeri 1 ve 2 kat arasında 1 değerini içermelidir (birbiri ardına 1 değeri ile 3 karesi görünmeyebilir).

Solved in 147 backtracks 
Yes (10.39s cpu, solution 1) 

Çok iyi herhangi bir arama gerçekleştirilir önce işlerini yapıyorlar kısıtlamaları gibi görünüyor 'sadece' 147 geri adım attığı ihtiyaç vardır beri:

aşağıdaki 18x18 bulmaca örneği için sonuçları (*) olsun . Ancak çalışma süresi, özellikle de geri dönüşlerin miktarına kıyasla, gerçekten uzun sürüyor. Bunun gerçekleşmesi gereken tüm dizi kontrolünden kaynaklandığını tahmin ediyorum. search/6'daki seçim/seçim yöntemlerinin herhangi birinin değiştirilmesinin çalışma süresi üzerinde neredeyse hiç bir etkisi olmadığı doğrudur. Öyleyse, bir dizinin/dizideki dizileri birbirinin yanında N özdeş öğeleri olmaması ve çalışma süresini iyileştirmesi için kısıtlamak için başka, daha verimli yollar var mı?

DÜZENLEME

aşağıdaki @jschimpf sağladığı ayrıştırılmış versiyonunu kullanarak sonra aşağıdaki sonuçlar elde edilmiştir:

Solved in 310 backtracks 
Yes (0.22s cpu, solution 1) 

yeni kısıtlamalar dizisi/6 kadar güçlü değildir, bir gerekir Biraz daha fazla geri dönüşler, ancak bizim çalışma süresi 10.39secs 0.22secs aşağı gitti, bu yüzden genel sonuç çok arzu edilir.

Örnek veriler: bu soru için kullanılan

bulmaca,

sorunu (p (6,1), [(1,1,0), (1 (adım attığı olmadan çözer) 5,1), (2,2,0), (3,6,0), (4,1,1), (4,4,0), (5,3,1), (5,4, 1), (6,2,0), (6,5,1)]).Benim sonuçları yayınlanmıştır hangi

Bulmaca (*):

sorunu (p (18,1), [(1,3,0), (1,9,0), (1,10,0), (1,12,0), (1,14,0), (1,18,1), (2,4,0), (2,7,1), (2, 8,1), (3.2.1), (3,6,0), (3,16,0), (3,17,0), (4,2,1), (4,4, 1), (4,10,1), (4,13,1), (4,18,1), (5,8,1), (5,10,1), (5,15,0) (5,16,1), (6,12,1), (7,3,0), (7,4,0), (7,6,1), (7,9,0), (7,12,1), (7,17,0), (8,1,1), (8,4,0), (8,8,1), (8,15,1), (8, 16,1), (9,7,0), (9,10,0), (9,14,0), (10,2,1), (10,4,1), (10,6, 1), (10,13,1), (11,7,0), (11,10,1), (12,1,1), (12,4,1), (12,7,1) (12,15,1), (12,16,1), (13,1,1), (13,6,0), (13,8,1), (13,10,0), (13,16,1), (14,5,1), (14,10,0), (14,13,1), (15,1,1), (15,3,1), (15, 12,0), (15,13,1), (15,15,0), (16,2,1), (16,4,0), (16,12,0), (16,18, 0), (17,9,0), (17,15,0), (17,18,0), (18,2,1), (18,8,1), (18,11,1), (18 , 15,1), (18,16,1)]).

+1

Güzel soru, +1! Birkaç örnek örnek verebilir misiniz? – mat

+2

Teşekkürler. Cevabı ben düzenledim. – SND

+2

Teşekkür ederim. Lütfen mümkünse, garajı temsil etmek için üçlü bir terim kullanın. Şu anda, örneğin, "ve-listeler" olarak da adlandırılan, '', '(1,', '(1,0)) ', yani yuvalanmış" ve "lerdir. Daha temiz bir temsil örneğin: x_y_v (1, 1, 0) 'dır. – mat

cevap

2

Bu durumda, sekansı kısıtlamasının bir el yapımı, dekompoze sürüm daha verimli olduğu ortaya çıkmıştır. Örnek 1 veya 2 için herhangi bir 3-eleman alt-dizisinin toplamı kısıtlamaktadır

sequence_1_2([X1,X2,X3|Xs]) :- !, 
    S #:: 1..2, 
    X1+X2+X3 #= S, 
    sequence_1_2([X2,X3|Xs]). 
sequence_1_2(_). 

için kullanımı ve

..., 
    sum(Row) #= N2, 
    sequence_1_2(Row), 

ile sequence_total/6 kısıtlamaları yerine Bu 0.2'ye kadar çözme zamanı getiriyor saniye.