เขียนตัวแก้ปัญหาการไหลของ ASP / Prolog / SAT


9

Flow Free เป็นเกมแอนดรอยด์ที่น่าติดตามซึ่งคุณต้องเชื่อมต่อคู่ธาตุต่างๆเข้าด้วยกันผ่านงูที่ไม่ทับซ้อนกันและเติมเต็มทั้งกริด สำหรับคำอธิบายดูที่นี่:

https://play.google.com/store/apps/details?id=com.bigduckgames.flow&hl=en

ฉันมีโซลูชัน ASP (ชุดคำตอบการเขียนโปรแกรม) ซึ่งเป็นเพียงกฎคู่และฉันไม่คิดว่ามันจะเป็นไปได้ที่จะพูดถึงวิธีการแก้ปัญหาเดียวกันเกือบจะรัดกุมเช่นกรณี SAT แต่ฉันสนใจที่จะพิสูจน์ผิด

ภาษาใดก็ได้ แต่ฉันสงสัยว่ามันสามารถทำได้อย่างกระชับโดยไม่ต้องใช้ตัวแก้ปัญหาบางชนิดซึ่งเป็นสาเหตุที่ฉันติดป้ายว่า ASP / Prolog / SAT

ผู้ชนะคือตัวละครน้อยที่สุด

คุณอาจคิดว่าปัญหาถูกกำหนดโดยใช้ภาคแสดง:

v(V). % A vertex

a(V,W). % V and W are adjacent

c(C). % A color

s(V,C). % V is an endpoint of color C

นอกจากนี้อินพุตยังเป็นที่น่าพอใจ

a(W,V) :- a(V,W) % Adjacencies are bidirectional

2{s(V,C) : v(V)}2 :- c(C). % Every color has exactly two endpoints

เพรดิเคตโซลูชันจะอยู่ในรูปแบบ

e(V,W,C).

การบอกว่ามีขอบระหว่าง V และ W ของสี C

ขอบจะต้องเป็นแบบสองทิศทาง (มีสีเดียวกัน) จุดสุดยอดแต่ละจุดจะต้องมีขอบเข้าและออกจากสีเดียว จุดสิ้นสุดมีขอบเดียวทั้งหมดส่วนจุดอื่น ๆ ทั้งหมดมีสองขอบอย่างแน่นอน ไม่มีลูปงูทุกตัวจะต้องตรวจสอบย้อนกลับได้ถึงสองจุดสิ้นสุด

นี่คือตัวอย่างอินพุตสำหรับทดสอบบน (5x5 ระดับ 2 ในชุดปกติ):

v(v11; v12; v13; v14; v15).
v(v21; v22; v23; v24; v25).
v(v31; v32; v33; v34; v35).
v(v41; v42; v43; v44; v45).
v(v51; v52; v53; v54; v55).

a(v11, v12).
a(v12, v13).
a(v13, v14).
a(v14, v15).
a(v12, v11).
a(v13, v12).
a(v14, v13).
a(v15, v14).
a(v11, v21).
a(v12, v22).
a(v13, v23).
a(v14, v24).
a(v15, v25).

a(v21, v22).
a(v22, v23).
a(v23, v24).
a(v24, v25).
a(v22, v21).
a(v23, v22).
a(v24, v23).
a(v25, v24).
a(v21, v31).
a(v22, v32).
a(v23, v33).
a(v24, v34).
a(v25, v35).
a(v21, v11).
a(v22, v12).
a(v23, v13).
a(v24, v14).
a(v25, v15).

a(v31, v32).
a(v32, v33).
a(v33, v34).
a(v34, v35).
a(v32, v31).
a(v33, v32).
a(v34, v33).
a(v35, v34).
a(v31, v41).
a(v32, v42).
a(v33, v43).
a(v34, v44).
a(v35, v45).
a(v31, v21).
a(v32, v22).
a(v33, v23).
a(v34, v24).
a(v35, v25).

a(v41, v42).
a(v42, v43).
a(v43, v44).
a(v44, v45).
a(v42, v41).
a(v43, v42).
a(v44, v43).
a(v45, v44).
a(v41, v51).
a(v42, v52).
a(v43, v53).
a(v44, v54).
a(v45, v55).
a(v41, v31).
a(v42, v32).
a(v43, v33).
a(v44, v34).
a(v45, v35).

a(v51, v52).
a(v52, v53).
a(v53, v54).
a(v54, v55).
a(v52, v51).
a(v53, v52).
a(v54, v53).
a(v55, v54).
a(v51, v41).
a(v52, v42).
a(v53, v43).
a(v54, v44).
a(v55, v45).

s(v11, yellow).
s(v45, yellow).
s(v41, blue).
s(v55, blue).
s(v51, red).
s(v43, red).
s(v42, green).
s(v33, green).

c(red; green; blue; yellow).

และเพื่อทดสอบผลลัพธ์

shouldbe(v33,v32,green).
shouldbe(v42,v32,green).
shouldbe(v43,v53,red).
shouldbe(v51,v52,red).
shouldbe(v55,v54,blue).
shouldbe(v41,v31,blue).
shouldbe(v45,v35,yellow).
shouldbe(v11,v12,yellow).
shouldbe(v12,v11,yellow).
shouldbe(v35,v45,yellow).
shouldbe(v31,v41,blue).
shouldbe(v54,v55,blue).
shouldbe(v52,v51,red).
shouldbe(v53,v43,red).
shouldbe(v32,v42,green).
shouldbe(v32,v33,green).
shouldbe(v53,v52,red).
shouldbe(v52,v53,red).
shouldbe(v54,v44,blue).
shouldbe(v31,v21,blue).
shouldbe(v35,v25,yellow).
shouldbe(v12,v13,yellow).
shouldbe(v13,v12,yellow).
shouldbe(v25,v35,yellow).
shouldbe(v21,v31,blue).
shouldbe(v44,v54,blue).
shouldbe(v44,v34,blue).
shouldbe(v21,v22,blue).
shouldbe(v25,v15,yellow).
shouldbe(v13,v14,yellow).
shouldbe(v14,v13,yellow).
shouldbe(v15,v25,yellow).
shouldbe(v22,v21,blue).
shouldbe(v34,v44,blue).
shouldbe(v34,v24,blue).
shouldbe(v22,v23,blue).
shouldbe(v15,v14,yellow).
shouldbe(v14,v15,yellow).
shouldbe(v23,v22,blue).
shouldbe(v24,v34,blue).
shouldbe(v24,v23,blue).
shouldbe(v23,v24,blue).

:-not e(V,W,C),shouldbe(V,W,C).
:-e(V,W,C),not shouldbe(V,W,C).

นอกจากนี้เลเวล 21 5x5 ควรเป็นตัวต่อตัวแรกที่มีมากกว่า 1 ตัวแก้ปัญหา (โดยเฉพาะมี 9 ตัวไม่ใช่ 40) ในการตั้งค่าระดับ 21 ให้ตั้งค่าสองสามบรรทัดสุดท้ายของอินพุตเป็น

s(v55, yellow).
s(v44, yellow).
s(v15, blue).
s(v45, blue).
s(v51, red).
s(v53, red).
s(v22, green).
s(v14, green).
s(v23, orange).
s(v43, orange).

c(red; green; blue; yellow; orange).

คำตอบ:


4

ASP (clingo), 180 ไบต์

{e(V,W,C):a(V,W),c(C)}.r(V):-s(V,_).r(V):-r(W),e(W,V,_).o(V):-r(V),{e(V,W,_):v(W);s(V,_)}=2.:-e(V,_,C),e(V,_,D),C!=D.:-e(V,W,C),not e(W,V,C).:-v(V),not o(V).:-s(V,C),e(V,_,D),C!=D.

ฉันยังใหม่กับ ASP ดังนั้นฉันจึงรู้สึกตื่นเต้นที่จะหางานนี้แม้ว่ามันจะค่อนข้างเก่า มันดีที่ได้เห็นว่ามีสถานที่สำหรับการเปลี่ยนแปลงและโอกาสในการเล่นกอล์ฟซึ่งนำไปสู่ข้อ จำกัด ของความเข้าใจของฉัน (ฉันหวังว่ามันจะยังคงถูกต้องดูเหมือนว่าจะเป็น)

นี่คือเวอร์ชันที่มีความคิดเห็น:

% Select some edges e(V,W,C) s.t. V and W are adjacent and C is a color.
{e(V,W,C):a(V,W),c(C)}.

% Auxilary predicates:

% A vertex is reachable from an endpoint if
% it is an endpoint ...
r(V):-s(V,_).
% ... or it has an edge to it from a reachable vertex.
r(V):-r(W),e(W,V,_).

% A vertex is okay if it is reachable and either
% is an endpoint with one edge or is not an endpoint and has two edges.
% This is golfed to: the set of edges from V and endpoints V has
% cardinality 2.
o(V):-r(V),{e(V,W,_):v(W);s(V,_)}=2.

% Constraints:  We do not want ...

% edges from the same vertex with different colors:
:-e(V,_,C),e(V,_,D),C!=D.

% edges without their inverses:
:-e(V,W,C),not e(W,V,C).

% vertices that are not okay:
:-v(V),not o(V).

% edges from endpoints with the wrong color
:-s(V,C),e(V,_,D),C!=D.

% We're only interested in the e predicate:
#show e/3.

ฉันไม่รู้เกี่ยวกับตัวแก้ ASP ที่แตกต่างกัน แต่ฉันใช้ clingo ซึ่งเดเบียนมีอยู่ในแพ็คเกจ gringo

ถ้าคุณมีปัญหาในแฟ้มprobและรหัสของฉันในไฟล์โทรsolve clingo 0 prob solveสำหรับแต่ละโซลูชันคุณจะได้รับรายการขอบสีที่ใช้ (และเพรดิเคตอื่น ๆ ทั้งหมดหากคุณใช้เวอร์ชัน golfed ที่ไม่มี#showเส้น) หากคุณต้องการเพียง -qแต่จำนวนของการแก้ปัญหาให้เพิ่มตัวเลือก 0ถ้าคุณเพียงต้องการที่จะทราบว่ามีอย่างน้อยหนึ่งวิธีการแก้ปัญหาโดยไม่ต้องโทร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.