ç§ã®æèŠã§ã¯ãã€ã³ã¿ãŒãããã®ãã·ã¢èªåéã§ã¯ã圢åŒçæ€èšŒã®ããŒããååã«ã«ããŒãããŠããããç¹ã«åçŽãã€æ確ãªäŸãäžè¶³ããŠããŸãã
å€åœã®æ å ±æºããã®äŸãæãããªãªã«ããã€ã®ããã£ãããå·ã®åãã岞ã«æž¡ããšããããç¥ãããåé¡ã«ç§ãªãã®è§£æ±ºçãå ããŸãã
ãã®åã«ãæ£åŒãªæ€èšŒãšã¯äœãããããŠãªããããå¿ èŠãªã®ãã«ã€ããŠç°¡åã«èª¬æããŸãã
æ£åŒãªæ€èšŒã¯éåžžãããããã°ã©ã ãŸãã¯ã¢ã«ãŽãªãºã ãå¥ã®ããã°ã©ã ãŸãã¯ã¢ã«ãŽãªãºã ã䜿çšããŠãã§ãã¯ããããšãæå³ããŸãã
ããã¯ãããã°ã©ã ãæåŸ ã©ããã«åäœããããšãä¿èšŒãããŸããã®ã»ãã¥ãªãã£ã確ä¿ããããã«å¿ èŠã§ãã
æ£åŒæ€èšŒã¯ãè匱æ§ãçºèŠããŠæé€ããããã®æã匷åãªæ段ã§ããããã«ãããããã°ã©ã ã«ååšãããã¹ãŠã®ããŒã«ããã°ãèŠã€ããããããããååšããªãããšã蚌æãããããããšãã§ããŸãã
ããŒãå¹
8 ãã¹ã® 1000 ã¯ã€ãŒã³ã®åé¡ãªã©ãå Žåã«ãã£ãŠã¯ãããäžå¯èœã§ããããšã«æ³šæããŠãã ããããã¹ãŠã¯ã¢ã«ãŽãªãºã ã®è€éããŸãã¯åæ¢åé¡ã«åž°çããŸãã
ãã ãããããã®å Žåããããã°ã©ã ãæ£ãããééã£ãŠããããŸãã¯çããèšç®ã§ããªãã£ããšãã XNUMX ã€ã®çãã®ãã¡ XNUMX ã€ãè¿ãããŸãã
çããèŠã€ããããšãã§ããªãå Žåã¯ãå€ãã®å Žåãç¹å®ã®ãã¯ãããŸãã¯ãããããã®çããåŸãããã«ãããã°ã©ã ã®äžæ確ãªéšåãåå å·¥ããŠã¢ã«ãŽãªãºã ã®è€éãã軜æžããããšãå¯èœã§ãã
ãŸããæ倧ã¬ãã«ã®ä¿è·ã確ä¿ããããã«ãWindows ã«ãŒãã«ã Darpa ãããŒã³ ãªãã¬ãŒãã£ã³ã° ã·ã¹ãã ãªã©ã§æ£åŒãªæ€èšŒã䜿çšãããŸãã
èªåå®ç蚌æãšæ¹çšåŒè§£æ±ºã®ããã®éåžžã«åŒ·åãªããŒã«ã§ãã Z3Prover ã䜿çšããŸãã
ããã«ãZ3 ã¯æ¹çšåŒã解ããåããã§å€ãéžæããŸããã
ããã¯ãå
¥åãªãã·ã§ã³ã®çµã¿åããã 10^100 éãããå Žåã§ããçããèŠã€ããããšãã§ããããšãæå³ããŸãã
ãã ãããã㯠Integer åã®å ¥ååŒæ°ãçŽ XNUMX åã ãã§ãããå®éã«ã¯ããçºçããŸãã
8 ã¯ã€ãŒã³ã«é¢ããåé¡ (è±èªããæç²)
# We know each queen must be in a different row.
# So, we represent each queen by a single integer: the column position
Q = [ Int('Q_%i' % (i + 1)) for i in range(8) ]
# Each queen is in a column {1, ... 8 }
val_c = [ And(1 <= Q[i], Q[i] <= 8) for i in range(8) ]
# At most one queen per column
col_c = [ Distinct(Q) ]
# Diagonal constraint
diag_c = [ If(i == j,
True,
And(Q[i] - Q[j] != i - j, Q[i] - Q[j] != j - i))
for i in range(8) for j in range(i) ]
solve(val_c + col_c + diag_c)
Z3 ãå®è¡ãããšã次ã®è§£æ±ºçãåŸãããŸãã
[Q_5 = 1,
Q_8 = 7,
Q_3 = 8,
Q_2 = 2,
Q_6 = 3,
Q_4 = 6,
Q_7 = 5,
Q_1 = 4]
ã¯ã€ãŒã³åé¡ã¯ã8 ã€ã®ã¯ã€ãŒã³ã®åº§æšãå ¥åãšããŠåãåããã¯ã€ãŒã³ãäºãã«åã€ãã©ããã®çããåºåããããã°ã©ã ã«çžåœããŸãã
ãã®ãããªããã°ã©ã ã圢åŒçæ€èšŒã䜿çšããŠè§£æ±ºããå Žåãåé¡ãšæ¯èŒãããšãããã°ã©ã ã³ãŒããæ¹çšåŒã«å€æãããšãã圢ã§ãã XNUMX ã€ã®æé ãå®è¡ããã ãã§æžã¿ãŸããã€ãŸããããã¯æ¬è³ªçã«ç§ãã¡ã®ãã®ãšåãã§ããããšãããããŸã (ãã¡ãããããã°ã©ã ãæ£ããæžãããŠããã°ã®è©±ã§ãã)ã
è匱æ§ã®æ€çŽ¢ã®å Žåãã»ãŒåãããšãèµ·ãããŸããå¿ èŠãªåºåæ¡ä»¶ (管çè ãã¹ã¯ãŒããªã©) ãèšå®ãããœãŒã¹ãŸãã¯éã³ã³ãã€ã«ãããã³ãŒããæ€èšŒã«é©åããåŒã«å€æããã ãã§ãçµæãäœã§ãããã«ã€ããŠã®çããåŸãããŸããç®æšãéæããã«ã¯ãããŒã¿ãå ¥åãšããŠæäŸããå¿ èŠããããŸãã
ç§ã®æèŠã§ã¯ããªãªã«ããã€ã®ããã£ããã®åé¡ã¯ããã«èå³æ·±ããã®ã§ãããªããªããããã解ãã«ã¯ãã§ã«å€ãã® (7) ã¹ããããå¿ èŠã ããã§ãã
ã¯ã€ãŒã³ã®åé¡ããåäžã® GET ãŸã㯠POST ãªã¯ãšã¹ãã䜿çšããŠãµãŒããŒã«äŸµå ¥ã§ããå Žåã«å¹æµããå Žåããªãªã«ããã€ã®ããã£ããã¯ãããè€éã§åºç¯ãªã«ããŽãªã®äŸã瀺ããŠããããã®äžã§ã®ã¿ç®æšãéæã§ããŸããããã€ãã®ãªã¯ãšã¹ãã«ããã
ããã¯ãããšãã°ãSQL ã€ã³ãžã§ã¯ã·ã§ã³ãèŠã€ããŠããããä»ããŠãã¡ã€ã«ãæžã蟌ã¿ãæš©éãææ ŒããŠãããã¹ã¯ãŒããååŸããå¿ èŠãããã·ããªãªã«çžåœããŸãã
åé¡ã®ç¶æ³ãšãã®è§£æ±ºç蟲倫ã¯ãªãªã«ããã€ã®ããã£ãããå·ãæž¡ã£ãŠéã¶å¿ èŠããããŸãã èŸ²å Žäž»ã¯ãèŸ²å Žäž»èªèº«ã®ä»ã«ãXNUMX ã€ã®ãªããžã§ã¯ãã®ã¿ãå容ã§ããããŒããæã£ãŠããŸãã 蟲倫ãæŸã£ãŠãããšãªãªã«ããã€ã®ãé£ã¹ãã€ã®ããã£ãããé£ã¹ãŠããŸããŸãã
解決çã¯ãã¹ããã 4 ã§èŸ²å®¶ãã€ã®ãåãæ»ãå¿
èŠãããããšã§ãã
ã§ã¯ãããã°ã©ã ã§è§£æ±ºããŠã¿ãŸãããã
蟲倫ããªãªã«ããã€ã®ããã£ãããã4 ãŸã㯠0 ã®å€ã®ã¿ãåã 1 ã€ã®å€æ°ãšããŠè¡šããŸããXNUMX ã¯ãããã巊岞ã«ããããšãæå³ããXNUMX ã¯ããããå³å²žã«ããããšãæå³ããŸãã
import json
from z3 import *
s = Solver()
Num= 8
Human = [ Int('Human_%i' % (i + 1)) for i in range(Num) ]
Wolf = [ Int('Wolf_%i' % (i + 1)) for i in range(Num) ]
Goat = [ Int('Goat_%i' % (i + 1)) for i in range(Num) ]
Cabbage = [ Int('Cabbage_%i' % (i + 1)) for i in range(Num) ]
# Each creature can be only on left (0) or right side (1) on every state
HumanSide = [ Or(Human[i] == 0, Human[i] == 1) for i in range(Num) ]
WolfSide = [ Or(Wolf[i] == 0, Wolf[i] == 1) for i in range(Num) ]
GoatSide = [ Or(Goat[i] == 0, Goat[i] == 1) for i in range(Num) ]
CabbageSide = [ Or(Cabbage[i] == 0, Cabbage[i] == 1) for i in range(Num) ]
Side = HumanSide+WolfSide+GoatSide+CabbageSide
Num ã¯ã解決ããããã«å¿ èŠãªã¹ãããæ°ã§ãã åã¹ãããã¯ãå·ãããŒããããã³ãã¹ãŠã®ãšã³ãã£ãã£ã®ç¶æ ãè¡šããŸãã
ãšããããã©ã³ãã ã«éžãã§äœè£ãæã£ãŠ10ååããŸãããã
åãšã³ãã£ãã£ã¯ 10 åã®ã³ããŒã§è¡šãããŸãããã㯠10 åã®åã¹ãããã§ã®å€ã§ãã
次ã«ãéå§ãšçµäºã®æ¡ä»¶ãèšå®ããŸãããã
Start = [ Human[0] == 0, Wolf[0] == 0, Goat[0] == 0, Cabbage[0] == 0 ]
Finish = [ Human[9] == 1, Wolf[9] == 1, Goat[9] == 1, Cabbage[9] == 1 ]
次ã«ããªãªã«ããã€ã®ãé£ã¹ãããã€ã®ããã£ãããé£ã¹ããã®æ¡ä»¶ãæ¹çšåŒã®å¶çŽãšããŠèšå®ããŸãã
ïŒèŸ²æ°ããããšäŸµç¥ã¯äžå¯èœïŒ
# Wolf cant stand with goat, and goat with cabbage without human. Not 2, not 0 which means that they are one the same side
Safe = [ And( Or(Wolf[i] != Goat[i], Wolf[i] == Human[i]), Or(Goat[i] != Cabbage[i], Goat[i] == Human[i])) for i in range(Num) ]
ãããŠæåŸã«ã蟲倫ãåãã岞ã«æž¡ããšãããŸãã¯æ»ã£ãŠãããšãã«èãããããã¹ãŠã®è¡åãå®çŸ©ããŸãã
ãªãªã«ããã€ã®ããã£ãããé£ããŠè¡ãããšãã誰ãé£ããŠè¡ããªããããããã¯ã©ãã«ãèªæµ·ããªãããšãã§ããŸãã
ãã¡ããã蟲æ°ãªãã§ã¯èª°ãæž¡ããŸããã
ããã¯ãå·ãããŒããããã³ãšã³ãã£ãã£ã®åŸç¶ã®åç¶æ ããå³å¯ã«éå®ãããæ¹æ³ã§ã®ã¿åã®ç¶æ ãšç°ãªãå¯èœæ§ããããšããäºå®ã«ãã£ãŠè¡šçŸãããŸãã
ãã¡ãŒããŒã¯äžåºŠã« 2 ã€ã®ãšã³ãã£ãã£ã®ã¿ã転éã§ãããã¹ãŠãäžç·ã«ããŠããããšã¯ã§ããªããããXNUMX ããã以äžã§ããããã®ä»å€ãã®å¶éããããŸãã
Travel = [ Or(
And(Human[i] == Human[i+1] + 1, Wolf[i] == Wolf[i+1] + 1, Goat[i] == Goat[i+1], Cabbage[i] == Cabbage[i+1]),
And(Human[i] == Human[i+1] + 1, Goat[i] == Goat[i+1] + 1, Wolf[i] == Wolf[i+1], Cabbage[i] == Cabbage[i+1]),
And(Human[i] == Human[i+1] + 1, Cabbage[i] == Cabbage[i+1] + 1, Wolf[i] == Wolf[i+1], Goat[i] == Goat[i+1]),
And(Human[i] == Human[i+1] - 1, Wolf[i] == Wolf[i+1] - 1, Goat[i] == Goat[i+1], Cabbage[i] == Cabbage[i+1]),
And(Human[i] == Human[i+1] - 1, Goat[i] == Goat[i+1] - 1, Wolf[i] == Wolf[i+1], Cabbage[i] == Cabbage[i+1]),
And(Human[i] == Human[i+1] - 1, Cabbage[i] == Cabbage[i+1] - 1, Wolf[i] == Wolf[i+1], Goat[i] == Goat[i+1]),
And(Wolf[i] == Wolf[i+1], Goat[i] == Goat[i+1], Cabbage[i] == Cabbage[i+1])) for i in range(Num-1) ]
ãœãªã¥ãŒã·ã§ã³ãå®è¡ããŠã¿ãŸãããã
solve(Side + Start + Finish + Safe + Travel)
ãããŠçããåãããŸããïŒ
Z3 ã¯ããã¹ãŠã®æ¡ä»¶ãæºããäžè²«ããç¶æ
ã®ã»ãããèŠã€ããŸããã
æ空ã®å次å
ãã£ã¹ãã®äžçš®ã
äœãèµ·ãã£ãã®ã調ã¹ãŠã¿ãŸãããã
æçµçã«ã¯å šå¡ãæž¡ã£ãããšãããããŸãããæåã ãç§ãã¡ã®èŸ²å€«ã¯äŒãããšã«æ±ºããæåã®2ã¹ãããã§ã¯ã©ãã«ãæ³³ããŸããã§ããã
Human_2 = 0
Human_3 = 0
ããã¯ãéžæããå·ã®æ°ãéå°ã§ããã8 ã€ã§ååã§ããããšã瀺åããŠããŸãã
ç§ãã¡ã®å Žåã蟲倫ã¯ãããè¡ããŸãããåºçºãäŒæ©ãäŒæ©ãã€ã®ã暪åããæ»ã£ãŠãã£ããã暪åããã€ã®ãšäžç·ã«æ»ãããªãªã«ãã暪åããäžäººã§æ»ããã€ã®ãåé éããŸãã
ãããæçµçã«ã¯åé¡ã¯è§£æ±ºãããŸããã
#СÑаÑÑ.
Human_1 = 0
Wolf_1 = 0
Goat_1 = 0
Cabbage_1 = 0
#ЀеÑÐŒÐµÑ ÐŸÑÐŽÑÑ
аеÑ.
Human_2 = 0
Wolf_2 = 0
Goat_2 = 0
Cabbage_2 = 0
#ЀеÑÐŒÐµÑ ÐŸÑÐŽÑÑ
аеÑ.
Human_3 = 0
Wolf_3 = 0
Goat_3 = 0
Cabbage_3 = 0
#ЀеÑÐŒÐµÑ ÐŸÑÐ²ÐŸÐ·ÐžÑ ÐºÐŸÐ·Ñ ÐœÐ° ÐœÑжМÑй беÑег.
Human_4 = 1
Wolf_4 = 0
Goat_4 = 1
Cabbage_4 = 0
#ЀеÑÐŒÐµÑ Ð²ÐŸÐ·Ð²ÑаÑаеÑÑÑ.
Human_5 = 0
Wolf_5 = 0
Goat_5 = 1
Cabbage_5 = 0
#ЀеÑÐŒÐµÑ ÐŸÑÐ²ÐŸÐ·ÐžÑ ÐºÐ°Ð¿ÑÑÑÑ ÐœÐ° ÐœÑжМÑй беÑег.
Human_6 = 1
Wolf_6 = 0
Cabbage_6 = 1
Goat_6 = 1
#ÐлÑÑÐµÐ²Ð°Ñ ÑаÑÑÑ ÐŸÐ¿ÐµÑаÑОО: ÑеÑÐŒÐµÑ Ð²ÐŸÐ·Ð²ÑаÑÐ°ÐµÑ ÐºÐŸÐ·Ñ ÐŸÐ±ÑаÑМП.
Human_7 = 0
Wolf_7 = 0
Goat_7 = 0
Cabbage_7 = 1
#ЀеÑÐŒÐµÑ ÐŸÑÐ²ÐŸÐ·ÐžÑ Ð²ÐŸÐ»ÐºÐ° Ма ÐŽÑÑгПй беÑег, гЎе ПМ ÑепеÑÑ ÐœÐ°Ñ
ПЎОÑÑÑ Ð²ÐŒÐµÑÑе Ñ ÐºÐ°Ð¿ÑÑÑПй.
Human_8 = 1
Wolf_8 = 1
Goat_8 = 0
Cabbage_8 = 1
#ЀеÑÐŒÐµÑ Ð²ÐŸÐ·Ð²ÑаÑаеÑÑÑ Ð·Ð° кПзПй.
Human_9 = 0
Wolf_9 = 1
Goat_9 = 0
Cabbage_9 = 1
#ЀеÑÐŒÐµÑ Ð¿ÐŸÐ²ÑПÑМП ЎПÑÑавлÑÐµÑ ÐºÐŸÐ·Ñ ÐœÐ° ÐœÑжМÑй беÑег О завеÑÑаÑÑ Ð¿ÐµÑепÑавÑ.
Human_10 = 1
Wolf_10 = 1
Goat_10 = 1
Cabbage_10 = 1
次ã«ãæ¡ä»¶ãå€æŽããŠã解決çããªãããšã蚌æããŠã¿ãŸãããã
ãããè¡ãã«ã¯ããªãªã«ãã«èé£åç©ãäžããŸãããããšããªãªã«ãã¯ãã£ãããé£ã¹ãããããã«ãªããŸãã
ããã¯ãã¢ããªã±ãŒã·ã§ã³ãä¿è·ããããšãç®æšã§ãããæãç©Žããªãããšã確èªããå¿
èŠãããå Žåãšæ¯èŒã§ããŸãã
Safe = [ And( Or(Wolf[i] != Goat[i], Wolf[i] == Human[i]), Or(Goat[i] != Cabbage[i], Goat[i] == Human[i]), Or(Wolf[i] != Cabbage[i], Goat[i] == Human[i])) for i in range(Num) ]
Z3 ããã¯æ¬¡ã®ãããªåçãåŸãããŸããã
no solution
ããã¯æ¬åœã«è§£æ±ºçããªãããšãæå³ããŸãã
ãã®ããã«ããŠã蟲倫ã«æ倱ãäžããã«éé£æ§ã®ãªãªã«ããšäº€é ããããšã¯äžå¯èœã§ããããšãããã°ã©ã çã«èšŒæããŸããã
èªè ããã®ãããã¯ã«èå³ããããšæããããä»åŸã®èšäºã§ãéåžžã®ããã°ã©ã ãŸãã¯é¢æ°ã圢åŒçææ³ãšäºææ§ã®ããæ¹çšåŒã«å€æããããã解ãæ¹æ³ã説æããŸããããã«ããããã¹ãŠã®æ£åœãªã·ããªãªãšè匱æ§ã®äž¡æ¹ãæããã«ãªããŸãã æåã¯åãã¿ã¹ã¯ã§ãããããã°ã©ã ã®åœ¢åŒã§æ瀺ããã次ã«ãããåŸã ã«è€éã«ããŠããœãããŠã§ã¢éçºã®äžçã®ææ°ã®äŸã«ç§»ããŸãã
次ã®èšäºã¯ãã§ã«æºåãããŠããŸãã
ãã®äžã§ãåé¡ã®æ£åŒãªæ€èšŒããããã°ã©ã ã«ç§»ãã次ã®ããã«èª¬æããŸãã
ããããæ£åŒãªã«ãŒã«ã·ã¹ãã ã«èªåçã«å€æããã«ã¯ã©ãããã°ããã§ããããã
åºæïŒ habr.com