Saya menggunakan pemecah SAT untuk menyandikan masalah, dan sebagai bagian dari contoh SAT, saya memiliki variabel boolean mana dimaksudkan bahwa salah satu dari ini harus benar dan sisanya harus salah. (Saya terkadang melihat ini digambarkan sebagai pengkodean "satu-panas".)
Saya ingin menyandikan batasan "tepat satu dari harus benar" di SAT. Apa cara terbaik untuk menyandikan batasan ini, untuk membuat pemecah SAT berjalan seefisien mungkin?
Saya dapat melihat banyak cara untuk menyandikan batasan ini:
Kendala berpasangan. Saya dapat menambahkan batasan berpasangan untuk semua untuk memastikan bahwa paling banyak satu adalah benar, dan kemudian menambahkan untuk memastikan bahwa setidaknya satu benar.
Ini menambahkan klausa dan tidak ada variabel boolean tambahan.
Pengkodean biner. Aku bisa memperkenalkan variabel boolean baru untuk mewakili (dalam biner) integer sehingga (menambahkan beberapa kendala boolean untuk memastikan bahwa berada dalam kisaran yang diinginkan ). Lalu, saya dapat menambahkan kendala menegakkan bahwa adalah pohon dan bahwa semua lainnya 's adalah palsu. Dengan kata lain, untuk setiap , kami menambahkan klausa yang menyatakan bahwa .
Ini menambahkan klausa dan saya tidak tahu berapa banyak variabel boolean tambahan.
Hitung jumlah nilai sebenarnya. Saya dapat mengimplementasikan pohon rangkaian boolean adder dan mensyaratkan bahwa , memperlakukan masing-masing sebagai 0 atau 1 sebagai ganti false atau true, dan menggunakan transformasi Tseitin untuk mengubah sirkuit ke SAT klausa. Pohon setengah-adders sudah mencukupi: membatasi output carry masing-masing setengah-penambah menjadi 0, dan membatasi output akhir dari setengah-penambah akhir di pohon menjadi 1. Pohon dapat dipilih dari segala bentuk ( pohon biner seimbang, atau tidak seimbang, atau apa pun).
Ini dapat dilakukan di gerbang dan dengan demikian menambahkan Θ ( n ) klausa dan Θ ( n ) variabel boolean baru.
Kasus khusus dari pendekatan ini adalah untuk memperkenalkan variabel boolean , dengan gagasan bahwa y i harus berisi nilai x 1 ∨ x 2 ∨ ⋯ ∨ x i . Maksud ini dapat ditegakkan dengan menambahkan klausa y i ∨ ¬ x i , y i ∨ ¬ y i - 1 , dan ¬ y i ∨ x i ∨ y i - (di mana kami memperlakukan y 0 sebagai sinonim untuk false) untuki=1,…,n. Selanjutnya, kita dapat menambahkan batasan¬ y i ∨¬ x i + 1 untuki=1,2,…,n-1. Ini pada dasarnya setara dengan transformasi Tseitin dari pohon setengah-penambah, di mana pohon tersebut memiliki bentuk yang tidak seimbang secara maksimal.
Jaringan kupu-kupu. Saya dapat membangun jaringan kupu - kupu pada bit, membatasi input n- bit menjadi 000 ⋯ 01 , membatasi output n- bit menjadi x 1 x 2 ⋯ x n , dan memperlakukan setiap gerbang kupu-kupu 2-bit sebagai gerbang independen yang bertukar atau tidak menukar inputnya dengan keputusan yang harus dilakukan berdasarkan variabel boolean baru yang dibiarkan tidak dibatasi. Lalu, saya bisa menerapkan transformasi Tseitin untuk mengubah rangkaian ke klausa SAT.
Ini membutuhkan gerbang dan dengan demikian menambahkan Θ ( n lg n ) klausa dan Θ ( n lg n ) variabel boolean baru.
Apakah ada metode lain yang saya abaikan? Yang mana yang harus saya gunakan? Adakah yang menguji ini atau mencobanya secara eksperimental, atau adakah yang punya pengalaman dengan semua ini? Apakah jumlah klausa dan / atau jumlah variabel boolean baru metrik stand-in yang baik untuk memperkirakan dampak ini pada kinerja pemecah SAT, atau jika tidak, metrik apa yang akan Anda gunakan?
Saya hanya melihat bahwa jawaban ini memiliki beberapa referensi tentang menegakkan kendala kardinalitas untuk SAT, yaitu, menegakkan kendala yang tepat keluar dari n variabel adalah benar. Jadi, pertanyaan saya sampai pada kasus khusus di mana k = 1 . Mungkin literatur tentang batasan kardinalitas akan membantu menjelaskan pertanyaan saya.