ስለ ተኩላ፣ ፍዹል እና ጎመን ቜግር ምሳሌ ላይ መደበኛ ማሚጋገጫ

በእኔ አስተያዚት, በበይነመሚብ ዚሩስያ ቋንቋ ዘርፍ, መደበኛ ዚማሚጋገጫ ርዕስ በበቂ ሁኔታ አልተሾፈነም, እና በተለይም ቀላል እና ግልጜ ምሳሌዎቜ እጥሚት አለ.

ኚባዕድ ምንጭ አንድ ምሳሌ እሰጣለሁ እና ተኩላ ፣ ፍዹል እና ጎመንን ወደ ወንዝ ማዶ ለመሻገር ዚራሎን መፍትሄ እጚምራለሁ ።

በመጀመሪያ ግን መደበኛ ማሚጋገጫ ምን እንደሆነ እና ለምን እንደሚያስፈልግ በአጭሩ እገልጻለሁ።

መደበኛ ማሚጋገጫ አብዛኛውን ጊዜ አንድን ፕሮግራም ወይም አልጎሪዝም በሌላ በመጠቀም ማሚጋገጥ ማለት ነው።

ይህ መርሃግብሩ ዹሚጠበቀው ባህሪ እንዲኖሚው እና ደህንነቱን ለማሚጋገጥ አስፈላጊ ነው.

መደበኛ ማሚጋገጫ ድክመቶቜን ለማግኘት እና ለማስወገድ በጣም ኃይለኛው መንገድ ነው-ሁሉንም ነባር ጉድጓዶቜ እና ስህተቶቜ በፕሮግራሙ ውስጥ እንዲያገኙ ወይም አለመኖራ቞ውን ያሚጋግጣል።
በአንዳንድ ሁኔታዎቜ ይህ ዚማይቻል መሆኑን ልብ ሊባል ዚሚገባው ነው, ለምሳሌ በ 8 ንግስቶቜ ቜግር ውስጥ በ 1000 ካሬዎቜ ዚቊርድ ስፋት: ሁሉም ወደ አልጎሪዝም ውስብስብነት ወይም ዹማቆም ቜግር ይመጣል.

ሆኖም ግን, በማንኛውም ሁኔታ, ኚሶስቱ መልሶቜ አንዱ ይቀበላል-ፕሮግራሙ ትክክል ነው, ትክክል አይደለም, ወይም መልሱን ማስላት አልተቻለም.

መልስ ለማግኘት ዚማይቻል ኹሆነ, ብዙውን ጊዜ ግልጜ ያልሆኑትን ዚፕሮግራሙ ክፍሎቜን እንደገና መሥራት, ዚአልጎሪዝም ውስብስብነታ቞ውን በመቀነስ, ዹተወሰነ አዎ ወይም ዹለም መልስ ለማግኘት.

እና መደበኛ ማሚጋገጫ ኹፍተኛውን ዚጥበቃ ደሹጃ ለማሚጋገጥ ለምሳሌ በዊንዶውስ ኹርነል እና በዳርፓ ድሮን ኊፕሬቲንግ ሲስተሞቜ ውስጥ ጥቅም ላይ ይውላል።

ለራስ-ሰር ቲዎሚም ማሚጋገጫ እና እኩልታ መፍታት በጣም ኃይለኛ መሳሪያ ዹሆነውን Z3Proverን እንጠቀማለን።

በተጚማሪም ፣ Z3 እኩልታዎቜን ይፈታል ፣ እና እሎቶቻ቞ውን በብርቱ ኃይል አይመርጥም ።
ይህ ማለት 10 ^ 100 ዚግቀት አማራጮቜ ጥምሚት በሚኖርበት ጊዜ እንኳን መልሱን ማግኘት ይቜላል ማለት ነው።

ነገር ግን ይህ ዚኢንቲጀር አይነት ወደ ደርዘን ዹሚጠጉ ግቀት ነጋሪ እሎቶቜ ብቻ ነው፣ እና ይሄ በተግባር ብዙ ጊዜ ያጋጥመዋል።

ቜግር ወደ 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 ንግሥቶቜን መጋጠሚያዎቜ እንደ ግብአት ወስዶ ንግሥቲቱ እርስበርስ መምታታ቞ውን መልሱን ኚሚሰጥ ፕሮግራም ጋር ሊወዳደር ይቜላል።

መደበኛ ማሚጋገጫን በመጠቀም እንዲህ ዓይነቱን ፕሮግራም ዚምንፈታ ኹሆነ ፣ ኚቜግሩ ጋር ሲነፃፀር ፣ ዚፕሮግራሙን ኮድ ወደ ቀመር በመቀዹር አንድ ተጚማሪ እርምጃ ብቻ መውሰድ አለብን ፣ እሱ በመሠሚቱ ኚእኛ ጋር ተመሳሳይ ይሆናል () በእርግጥ, ፕሮግራሙ በትክክል ኹተፃፈ).

ተጋላጭነቶቜን በሚፈልጉበት ጊዜ አንድ አይነት ነገር ይኚሰታል ማለት ይቻላል: እኛ ዹምንፈልገውን ዚውጀት ሁኔታዎቜን ብቻ እናዘጋጃለን ፣ ለምሳሌ ፣ ዚአስተዳዳሪ ዹይለፍ ቃል ፣ ምንጩን ወይም ዹተበላሾውን ኮድ ኚማሚጋገጫ ጋር ወደሚስማሙ እኩልታዎቜ እንለውጣለን እና ኚዚያ ምን መልስ እናገኛለን ግቡን ለማሳካት መሹጃን እንደ ግብአት ማቅሚብ ያስፈልጋል።

በእኔ አስተያዚት ስለ ተኩላ ፣ ፍዹል እና ጎመን ያለው ቜግር ዹበለጠ አስደሳቜ ነው ፣ ምክንያቱም እሱን ለመፍታት ቀድሞውኑ ብዙ (7) እርምጃዎቜን ይፈልጋል ።

ዚንግሥቲቱ ቜግር ነጠላ GET ወይም POST ጥያቄን ተጠቅመህ ሰርቹር ውስጥ መግባት ኚምትቜልበት ጉዳይ ጋር ዚሚነጻጞር ኹሆነ ተኩላ፣ ፍዹል እና ጎመን ግቡን ብቻ ማሳካት ኚሚቻልበት በጣም ውስብስብ እና ሰፊ ምድብ ምሳሌ ያሳያል። በበርካታ ጥያቄዎቜ.

ይህ ለምሳሌ ዹ SQL መርፌን ለማግኘት ኚሚፈልጉበት ሁኔታ ጋር ተመሳሳይ ነው ፣ በእሱ ውስጥ ፋይል ይፃፉ ፣ ኚዚያ መብቶቜዎን ኹፍ ያድርጉ እና ኚዚያ ብቻ ዹይለፍ ቃል ያግኙ።

ዚቜግሩ ሁኔታዎቜ እና መፍትሄውገበሬው ተኩላ፣ ፍዹል እና ጎመን ወንዙን ማሻገር አለበት። ገበሬው ኚራሱ ኚገበሬው በተጚማሪ አንድ ዕቃ ብቻ ማስተናገድ ዚሚቜል ጀልባ አለው። ተኩላው ፍዹሉን ይበላል ፍዹሉም ጎመንውን ይበላዋል ገበሬው ሳይጠብቅ ቢተውዋ቞ው።

መፍትሄው በደሹጃ 4 ገበሬው ፍዹሉን መልሶ መውሰድ ያስፈልገዋል.
አሁን በፕሮግራም መፍታት እንጀምር።

ገበሬውን፣ ተኩላውን፣ ፍዹሉን እና ጎመንን 4 ተለዋዋጮቜ እንጥቀስ እና እሎቱን 0 ወይም 1 ብቻ ይወስዳሉ። ዜሮ ማለት በግራ ባንክ ላይ ና቞ው፣ አንደኛው ደግሞ በቀኝ ናቾው ማለት ነው።

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

ቁጥር ለመፍታት ዚሚያስፈልጉት ዚእርምጃዎቜ ብዛት ነው። እያንዳንዱ እርምጃ ዹወንዙን, ዚጀልባውን እና ሁሉንም አካላትን ሁኔታ ይወክላል.

ለአሁን፣ በዘፈቀደ እንመርጠው እና በህዳግ 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 ቢት ያልበለጠ እና ኚሌሎቜ ብዙ ገደቊቜ ጋር።

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

በእውነቱ ምንም መፍትሄዎቜ ዹሉም ማለት ነው.

ስለዚህም በገበሬው ላይ ያለ ኪሳራ ኹሁሉን ቻይ ተኩላ ጋር መሻገር ዚማይቻል መሆኑን በፕሮግራም አሚጋግጠናል።

ተሰብሳቢዎቹ ይህንን ርዕስ አስደሳቜ ሆኖ ካገኙት ፣ ኚዚያ በሚቀጥሉት መጣጥፎቜ ውስጥ አንድ ተራ ፕሮግራም ወይም ተግባር ኹመደበኛ ዘዎዎቜ ጋር ወደሚስማማ እኩልታ እንዎት እንደሚቀይሩ እነግርዎታለሁ ፣ እና መፍታት ፣ በዚህም ሁለቱንም ህጋዊ ሁኔታዎቜን እና ተጋላጭነቶቜን ያሳያል ። በመጀመሪያ ፣ በተመሳሳይ ተግባር ላይ ፣ ግን በፕሮግራም መልክ ቀርቧል ፣ እና ኚዚያ ቀስ በቀስ ውስብስብ እና ኚሶፍትዌር ልማት ዓለም ወደ ወቅታዊ ምሳሌዎቜ ይሂዱ።

ዚሚቀጥለው ጜሑፍ አስቀድሞ ዝግጁ ነው፡-
መደበኛ ዚማሚጋገጫ ስርዓት ኚባዶ መፍጠር፡ ተምሳሌታዊ ቪኀምን በPHP እና Python መጻፍ

በእሱ ውስጥ ዚቜግሮቜን መደበኛ ማሚጋገጫ ወደ ፕሮግራሞቜ እሞጋገር እና እገልጻለሁ
እንዎት እነሱን ወደ መደበኛ ህጎቜ ስርዓት በራስ-ሰር መቀዹር እንደሚቜሉ።

ምንጭ: hab.com

አስተያዚት ያክሉ