数理逻辑-杀人推理

Posted hiec

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数理逻辑-杀人推理相关的知识,希望对你有一定的参考价值。

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词 - 春风来不来的博客 - CSDN博客

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词。
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。

现在请根据这些信息,写一个程序来确定到底谁是凶手。

#include <stdio.h>
int main() 
{
    char killer;
    for(killer='A'; killer<='D'; killer++)
    {
        //>>> 分别对应每个人都供词:不是A 是C 是D 不是D
        if (((killer!='A') + (killer=='C') + (killer=='D') + (killer!='D'))==3)  //这里等于3表示 有三个人说了真话
        {
            printf("
%c 是凶手。
",killer);
            // break;
        }
    }
    return 0;
}

走到一条岔路上,前面遇到两个人,一个人永远说真话,一个人永远说假话,你并不知道谁说真话谁说假话,只许问其中一个人一句话,就知道该-CSDN论坛

走到一条岔路上,前面遇到两个人,一个人永远说真话,一个人永远说假话。
你并不知道谁说真话谁说假话,只许问其中一个人一句话,就知道该往那里走了。

随便问其中一个人:如果我问他(指旁边那个人),他会告诉我走哪条路呢?然后再将你问的人告诉你的答案取反,就是应该走的路。
永远说假话的人其实就是个非门,这样问一定会通过那个非门,因此再将答案取反就行了。

解:设真为1,假为0。异或符为^,取反符为~。
1^0=0
(或0^1=0)
~0=1

神秘的谋杀案,有事实如下: (1)在这栋房子里仅住有A,B,C三人…【人工智能吧】_百度贴吧

神秘的谋杀案,有事实如下:
(1)在这栋房子里仅住有A,B,C三人。
(2)是住在这栋房子里的人杀了A。
(3)谋杀者非常恨受害者。
(4)A所恨的人,C一定不恨。
(5)除了B之外, A恨所有的人。
(6) B恨所有不比A富有的人。
(7) A所恨的人, B也恨。
(8)没有一个人恨所有的人。
(9)杀人嫌疑犯一定不会比受害者富有。
(10)A不等于B。
谋杀者是谁?

K(Killer), H(Hate), V(Victim), RT(Rich Than)
神秘的谋杀案,有事实如下:
(1)在这栋房子里仅住有A,B,C三人。 N={A,B,C}
(2)是住在这栋房子里的人杀了A。 K∈N, V=A
(3)谋杀者非常恨受害者。 K[H]V
(5)除了B之外, A恨所有的人。 A[H]A, A[H]C
(4)A所恨的人,C一定不恨。 C[?H]A, C[?H]C
(6) B恨所有不比A富有的人。 B[H]X, ?X, X[?RT]A
(7) A所恨的人, B也恨。 B[H]A, B[H]C
(8)没有一个人恨所有的人。 ?Y, Y[H]A, Y[H]B, Y[H]C, Y?N
(9)杀人嫌疑犯一定不会比受害者富有。 K[?RT]V
(10)A不等于B。 A≠B
谋杀者是谁?
(3),(4):

(11) C≠K
(5),(7),(8):

(12) A[?H]B, B[?H]B
(6),(12):

(13) B[RT]A
(9),(13):

(14) B≠K
(2),(10),(11),(14):
A=K
自杀。。。

代码有待完善……

//运行环境visualStudio2017
#define _CRT_SECURE_NO_DEPRECATE

#include<stdio.h>
#include<stdlib.h>

/*
Killa(x) x kill a
Hate(x,y) x hate y
Rich(x,y) x is richer than y
*/

void fn_init();
void fn_print_killa();
void fn_print_hate();
void fn_print_rich();
void fn_killa();
void fn_hate();
void fn_rich();
bool fn_judge();
void fn_print_result();

const int m = 3;
int count = 0;
int killa[m], hate[m][m], rich[m][m];

void fn_init() {
    for (int i = 0; i < m; ++i) killa[i] = 0;
    for (int i = 0; i < m; ++i) for (int j = 0; j < m; ++j) hate[i][j] = 0;
    for (int i = 0; i < m; ++i) for (int j = 0; j < m; ++j) rich[i][j] = 0;
}


void fn_print_killa() {
    for (int i = 0; i < m; ++i)
        printf("%d ", killa[i]);
    printf("
");
}

void fn_print_hate() {
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < m; ++j)
            printf("%d ", hate[i][j]);
        printf("
");
    }
}

void fn_print_rich() {
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < m; ++j)
            printf("%d ", rich[i][j]);
        printf("
");
    }
}

void fn_print_result() {
    //freopen("E:\[000]2018\TimeEvent\20180903-\[周5am]人工智能\code\work2\data2.txt", "a+", stdout);
    printf("
---------------------
");
    printf("killa: 
"); fn_print_killa();
    printf("hate: 
"); fn_print_hate();
    printf("rich: 
"); fn_print_rich();
    printf("
---------------------
");
    //fclose(stdout);
}

void fn_killa() {
    for (int k0 = 0; k0 <= 1; ++k0) {
        killa[0] = k0;

        for (int k1 = 0; k1 <= 1; ++k1) {
            killa[1] = k1;

            for (int k2 = 0; k2 <= 1; ++k2) {
                killa[2] = k2;

                fn_hate();
            }
        }
    }
}

void fn_hate() {
    for (int h00 = 0; h00 <= 1; ++h00) {
        hate[0][0] = h00;

        for (int h01 = 0; h01 <= 1; ++h01) {
            hate[0][1] = h01;

            for (int h02 = 0; h02 <= 1; ++h02) {
                hate[0][2] = h02;

                for (int h10 = 0; h10 <= 1; ++h10) {
                    hate[1][0] = h10;

                    for (int h11 = 0; h11 <= 1; ++h11) {
                        hate[1][1] = h11;

                        for (int h12 = 0; h12 <= 1; ++h12) {
                            hate[1][2] = h12;

                            for (int h20 = 0; h20 <= 1; ++h20) {
                                hate[2][0] = h20;

                                for (int h21 = 0; h21 <= 1; ++h21) {
                                    hate[2][1] = h21;

                                    for (int h22 = 0; h22 <= 1; ++h22) {
                                        hate[2][2] = h22;

                                        fn_rich();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void fn_rich() {
    for (int h00 = 0; h00 <= 1; ++h00) {
        rich[0][0] = h00;

        for (int h01 = 0; h01 <= 1; ++h01) {
            rich[0][1] = h01;

            for (int h02 = 0; h02 <= 1; ++h02) {
                rich[0][2] = h02;

                for (int h10 = 0; h10 <= 1; ++h10) {
                    rich[1][0] = h10;

                    for (int h11 = 0; h11 <= 1; ++h11) {
                        rich[1][1] = h11;

                        for (int h12 = 0; h12 <= 1; ++h12) {
                            rich[1][2] = h12;

                            for (int h20 = 0; h20 <= 1; ++h20) {
                                rich[2][0] = h20;

                                for (int h21 = 0; h21 <= 1; ++h21) {
                                    rich[2][1] = h21;

                                    for (int h22 = 0; h22 <= 1; ++h22) {
                                        rich[2][2] = h22;

                                        if (fn_judge()) {
                                            ++count;
                                            fn_print_result();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

bool fn_judge() {
    //(1)在这栋房子里仅住有A,B,C三人。
    //(2)是住在这栋房子里的人杀了A。     
    // 说明:凶手只有一个人。
    if (killa[0] + killa[1] + killa[2] != 1) return false;
    //或者凶手不止一个人:if (killa[0] + killa[1] + killa[2] < 1) return false;

    //(3)谋杀者非常恨受害者。 
    for (int i = 0; i < m; ++i)
        if (killa[i] && !hate[i][0])  return false;
    //(4)A所恨的人,C一定不恨。    
    for (int i = 0; i < m; ++i)
        if (hate[0][i] && hate[2][i]) return false;
    //(5)除了B之外, A恨所有的人。
    if (hate[0][1]) return false;
    for (int i = 0; i < m; ++i) {
        if (i == 1) continue;
        if (!hate[0][i]) return false;
    }
    //(6) B恨所有不比A富有的人。
    for (int i = 0; i < m; ++i) {
        if (!rich[i][0] && !hate[1][i])
            return false;
    }
    //(7) A所恨的人, B也恨。
    for (int i = 0; i < m; ++i) {
        if (hate[0][i] && !hate[1][i])
            return false;
    }
    //(8)没有一个人恨所有的人。
    for (int i = 0; i < m; ++i) {
        if (hate[i][0] + hate[i][1] + hate[i][2] == 3)
            return false;
    }
    //(9)杀人嫌疑犯一定不会比受害者富有。 
    for (int i = 0; i < m; ++i) {
        if (killa[i] && rich[i][0])
            return false;
    }

    return true;
}

int main() {
    fn_init();

    fn_killa();
    printf("共有%d情况
", count);

    system("pause");
    return 0;
}

共有2097152种排列
其中256种情况有效
请按任意键继续. . .

以上是关于数理逻辑-杀人推理的主要内容,如果未能解决你的问题,请参考以下文章

逻辑推理的基本步骤

数理逻辑命题逻辑的等值演算与推理演算 ( 命题逻辑 | 等值演算 | 主合取 ( 析取 ) 范式 | 推理演算 ) ★★

逻辑推理-推测排名

逻辑推理 2 4 3 5 6 8 7 ( ) A15 B13 C11 D9 求推理过程

逻辑与推理

逻辑学的研究对象