⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dalgo.cpp

📁 数字电路故障分析之D算法C++实现。按照教科书编写
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------

                                                                                                
#pragma hdrstop

#include "Dalgo.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#include <alloc.h>

#ifdef __Dalgo_debug__
#include <iostream.h>
#endif

using namespace DAlgorithm;

//typedef DAlgorithmRenderer::TestNodeRes TestNodeRes;
//const TestNodeRes Out   = DAlgorithmRenderer::Out;
//const TestNodeRes NoOut = DAlgorithmRenderer::NoOut;
//const TestNodeRes Fail  = DAlgorithmRenderer::Fail;
//

const ExtStep       = 10;

const Intercube     = 0;
const LineConfirm   = 1;
const SelectDev     = 2;
const SelectTransD  = 3;
const End           = 4;

static DLogic IntercubeTable[5][5] = {
        {DL_0, DL_E, DL_E, DL_E, DL_0},
        {DL_E, DL_1, DL_E, DL_E, DL_1},
        {DL_E, DL_E, DL_D, DL_E, DL_D},
        {DL_E, DL_E, DL_E, DL_N, DL_N},
        {DL_0, DL_1, DL_D, DL_N, DL_X} };

//  DAlgorighm

bool DAlgorithmRenderer::intercube(DCube &cube, const DCube &cube1,
        const DCube &cube2)
{
    bool result = true;
    for(int i = 0; i < nodeNum; i++)
    {
        cube[i] = IntercubeTable[cube1[i]][cube2[i]];
        if(cube[i] == DL_E)
        {
            result = false;
        }
    }
    return result;
}

void DAlgorithmRenderer::add(const DCube &cube)
{
    int i;
    int transDSize = transDTable.getRowNum();
    if(transDEnd >= transDSize)
    {
        transDSize += 5;
        transDTable.setRowNum(transDSize);
        for(i = transDSize - 5; i < transDSize; i++)
        {
            transDTable.createRow(i, nodeNum);
        }
    }
    for(i = 0; i < nodeNum; i++)
    {
        transDTable[transDEnd][i] = cube[i];
    }
    transDEnd++;
}

void DAlgorithmRenderer::addTransDCube(/* const */ DCube &cube)
{
    int diff;
    add(cube);
    int nodeNum = transDTable.getColNum();
    for(int i = transDEnd - 1; i >= 0; i--)
    {
        diff = -1;
        for(int j = nodeNum - 1; j >= 0; j--)
        {
            bool cmp1 = transDTable[i][j] == DL_D || transDTable[i][j] == DL_N;
            bool cmp2 = transDTable[transDEnd - 1][j] == DL_D ||
                    transDTable[transDEnd - 1][j] == DL_N;
            if(cmp1 && !cmp2 || !cmp1 && cmp2)
            {
                diff = -3;
                break;
            }
            if(transDTable[i][j] + transDTable[transDEnd - 1][j] == 1)
            {
                if(diff != -1)
                {
                    diff = -2;
                    break;
                }
                else
                {
                    diff = j;
                }
            }
        }
        if(diff == -3)
        {
            break;
        }
        if(diff >= 0)
        {
            add(transDTable[transDEnd - 1]);
            transDTable[transDEnd - 1][diff] = DL_X;
        }
    }
}

void DAlgorithmRenderer::testPDCheck(_TestPD &testPD)
{
    int i, j;
    unsigned char transDType;
    for(i = testPD.cubeIndex; i < originalNum &&
            devInfoList[originalDevMap[i]].outpNode == testPD.devNode; i++)
    {
        if(originalTable[i][testPD.vPD] != DL_0)
        {
            continue;
        }
        testPD.tryCube[testPD.vPD] = DL_0;
        testPD.tryCube[testPD.devNode] = DL_X;
        if(!intercube(testPD.transDCube, testPD.tryCube, originalTable[i]))
        {
            continue;
        }
        transDType = testPD.transDCube[testPD.devNode];
        testPD.tryCube[testPD.vPD] = DL_1;
        testPD.tryCube[testPD.devNode] = DL_X;
        for(j = testPD.cubeIndex; j < originalNum &&
                devInfoList[originalDevMap[j]].outpNode == testPD.devNode; j++)
        {
            if(originalTable[j][testPD.vPD] != DL_1)
            {
                continue;
            }
            testPD.tryCube[testPD.vPD] = DL_1;
            testPD.tryCube[testPD.devNode] = DL_X;
            if(!intercube(testPD.transDCube, testPD.tryCube, originalTable[j]))
            {
                continue;
            }
            if(testPD.transDCube[testPD.devNode] ==
                    testPD.transDCube[testPD.vPD])
            {
                if(transDType == 0)
                {
                    testPD.transDCube[testPD.vPD] = DL_D;
                    testPD.transDCube[testPD.devNode] = DL_D;
                    addTransDCube(testPD.transDCube);
                    testPD.transDCube[testPD.vPD] = DL_N;
                    testPD.transDCube[testPD.devNode] = DL_N;
                    addTransDCube(testPD.transDCube);
                    return;
                }
            }
            else if(transDType == 1)
            {
                testPD.transDCube[testPD.vPD] = DL_D;
                testPD.transDCube[testPD.devNode] = DL_N;
                addTransDCube(testPD.transDCube);
                testPD.transDCube[testPD.vPD] = DL_N;
                testPD.transDCube[testPD.devNode] = DL_D;
                addTransDCube(testPD.transDCube);
                return;
            }
        }   // for j
    }   // for i
}

void DAlgorithmRenderer::testPD(_TestPD &testPD) const
{
    int i, p;
    unsigned char carry = 0;
    while(1)
    {
        if(carry != 1)
        {
            testPDCheck(testPD);
        }
        else
        {
            for(i = 0; i < testPD.ptEnd - 1; i++)
            {
                testPD.tryCube[testPD.ptKeep[i]] = DL_0;
            }
            break;
        }

        // Get next combination
        carry = 1;
        for(i = 0; i < testPD.ptEnd - 1; i++)
        {
            if(testPD.ptKeep[i] == testPD.vPD)
            {
                continue;
            }
            p = testPD.ptKeep[i];
            if(carry == 1)
            {
                if(testPD.tryCube[p] == DL_0)
                {
                    testPD.tryCube[p] = DL_1;
                    carry = 0;
                    break;
                }
                if(testPD.tryCube[p] == DL_1)
                {
                    testPD.tryCube[p] = DL_0;
                    carry = 1;
                }
            }
        }   // for
    }   // while
}

int DAlgorithmRenderer::contained(const DCube &cube1, const DCube &cube2) const
{
    int result = 0;
    for(int i = 0; i < nodeNum; i++)
    {
        if(cube1[i] != cube2[i])
        {
            if(cube2[i] == DL_0 || cube2[i] == DL_1)
            {
                return 1;
            }
            else if(cube2[i] == DL_D || cube2[i] == DL_N)
            {
                if(!(cube1[i] == DL_D || cube1[i] == DL_N))
                {
                    return 2;
                }
                else
                {
                    result = 1;
                }
            }
        }
    }
    return result;
}

void DAlgorithmRenderer::compressTransD()
{
    int i, j, k, lastOutp, devPt;
    unsigned char res;
    Array<bool> delToken;
    delToken.setLength(transDEnd);
    for(i = 0; i < transDEnd; i++)
    {
        delToken[i] = false;

        for(j = i + 1/*, res = 3*/; j < transDEnd; j++)
        {
            res = contained(transDTable[i], transDTable[j]);
            if(res == 0)
            {
                delToken[i] = true;
                break;
            }
            else if(res == 2)
            {
                break;
            }
        }
    }
    i = j = 0;
    lastOutp = devPt = -1;
    transDDevMap.setLength(transDEnd);
    while(1)
    {
        for(; j < transDEnd && delToken[j]; j++);
        if(j >= transDEnd)
        {
            break;
        }
        if(i != j)
        {
            transDTable.copyRow(i, transDTable[j]);
        }
        for(k = nodeNum - 1; k >= 0; k--)
        {
            if(transDTable[i][k] != DL_X)
            {
                if(lastOutp != k)
                {
                    lastOutp = k;
                    devPt++;
                    devInfoList[devPt].firstTransDCubeIndex = i;
                }
                break;
            }
        }
        transDDevMap[i] = devPt;
        i++; j++;
    }
    transDNum = i;
    transDDevMap.setLength(transDNum);
    transDTable.setRowNum(transDNum);
}

DAlgorithmRenderer::DAlgorithmRenderer()
{
}

DAlgorithmRenderer::~DAlgorithmRenderer()
{
}

void DAlgorithmRenderer::setParams(ConstDCube &original,
        ConstNodeStyles &nodeStyles, int nodeNum, int devNum)
{
    this->nodeNum = nodeNum;
    this->devNum = devNum;
    originalNum = original.getLength() / nodeNum;
    originalTable.setRowNum(originalNum);
    originalDevMap.setLength(originalNum);
    devInfoList.setLength(devNum);
    nodeStyleList.setLength(nodeNum);
    for(int i = 0; i < nodeNum; i++)
    {
        nodeStyleList[i] = nodeStyles[i];
    }
    int lastOutpPos = -1, devPt = -1;
    unsigned char stat;
    for(int i = 0; i < originalNum; i++)
    {
        // set the size of original DL_D-cube
        originalTable.createRow(i, nodeNum);

        stat = 0;
        for(int j = nodeNum - 1; j >= 0; j--)
        // probe from the end of the current cube
        {
            // set the value of original D-cube
            originalTable[i][j] = original[i * nodeNum + j];

            if(stat == 0)
            {
                if(originalTable[i][j] != DL_X)
                {
                    if(lastOutpPos != j)
                    // find the output node in current D-cube
                    {
                        // set last output position to current node, then
                        // it points to the output node of current device
                        lastOutpPos = j;

                        devPt++;

                        // BEGIN: set info for the new device
                        devInfoList[devPt].devCube.setLength(nodeNum);
                        for (int k = nodeNum - 1; k >= 0; k--)
                        // initialization
                        {
                            devInfoList[devPt].devCube[k] = None;
                        }
                        // set output node property for current device
                        devInfoList[devPt].outpNode = lastOutpPos;

                        // current node is an output node
                        devInfoList[devPt].devCube[lastOutpPos] = Output;

                        devInfoList[devPt].firstOriginalCubeIndex = i;
                        // END: set info for the new device
                    }   // if(lastOutpPos != j)
                    stat = 1;
                    originalDevMap[i] = devPt;
                }   // if(originalTable[i][j] != DL_X)
            }   // if(stat == 0)
            else if(stat == 1)
            // if a new device(OriginalTable[i]) found
            {
                if(originalTable[i][j] != DL_X)
                // the node must be an input node for the (one-output) device
                {
                    devInfoList[devPt].devCube[j] = Input;
                }
            }
        }   // for(int j = nodeNum - 1; j >= 0; j--)
    }   // for(int i = 0; i < originalNum; i++)
}

void DAlgorithmRenderer::autoCreateTransDTable()
{
    _TestPD test;
    test.ptEnd = test.cubeIndex = 0;
    test.ptKeep.setLength(nodeNum);
    test.tryCube.setLength(nodeNum);
    test.transDCube.setLength(nodeNum);

    transDEnd = 0;

    int j;
    for(int i = test.cubeIndex; test.cubeIndex < originalNum;
            test.cubeIndex = i)
    {
        //  get device node index
        test.devNode = devInfoList[originalDevMap[test.cubeIndex]].outpNode;
        test.ptEnd = 0;
        for(j = 0; j < nodeNum; j++)
        {
            test.tryCube[j] = DL_X;
        }
        for(; i < originalNum &&
                test.devNode == devInfoList[originalDevMap[i]].outpNode; i++)
        {
            for(j = 0; j < nodeNum; j++)
            {
                if(originalTable[i][j] != DL_X)
                {
                    test.tryCube[j] = DL_0;
                }
            }
        }
        
        for(j =  0; j < nodeNum; j++)
        {
            if(test.tryCube[j] == DL_0)
            {
                // register the non-"DL_X"s ("DL_0"s at the first time)
                test.ptKeep[test.ptEnd++] = j;
            }
        }
        for(j = 0; j < test.ptEnd - 1; j++)
        {
            test.vPD = test.ptKeep[j];
            testPD(test);
        }
    }
    compressTransD();
}

void DAlgorithmRenderer::autoCreateFaultDTable()
{
    int i, j, devIndex, len;
    for(j = 0; j < nodeNum; j++)
    {
        // Take it for granted that input nodes is listed at the begining
        if(nodeStyleList[j] != Input)
        {
            break;
        }
    }
    inputNum = j * 2;
    faultDTable.setRowNum(len = inputNum + originalNum);
    for(i = 0; i < inputNum; i++)
    {
        faultDTable.createRow(i, nodeNum);
        for(j = 0; j < nodeNum; j++)
        {
            faultDTable[i][j] = DL_X;
        }
        if(i % 2 == 0)
        {
            faultDTable[i][i / 2] = DL_D;
        }
        else
        {
            faultDTable[i][i / 2] = DL_N;
        }
    }
    for(; i < len; i++)
    {
        faultDTable.createRow(i, nodeNum);
        for(j = 0; j < nodeNum; j++)
        {
            faultDTable[i][j] = originalTable[i - inputNum][j];
        }
        devIndex = originalDevMap[i - inputNum];
        switch(faultDTable[i][devInfoList[devIndex].outpNode])
        {
        case DL_0:
            faultDTable[i][devInfoList[devIndex].outpNode] = DL_N;
            break;
        case DL_1:
            faultDTable[i][devInfoList[devIndex].outpNode] = DL_D;
            break;
        }
    }
}

const DCubeTable &DAlgorithmRenderer::getTransDTable() const
{
    return transDTable;
}

const DCubeTable &DAlgorithmRenderer::getFaultDTable() const
{
    return faultDTable;
}

const CubeMap &DAlgorithmRenderer::getOriginalDevMap() const
{
    return originalDevMap;
}

const CubeMap &DAlgorithmRenderer::getTransDDevMap() const
{
    return transDDevMap;
}

const DevInfoList &DAlgorithmRenderer::getDevInfoList() const
{
    return devInfoList;
}

bool DAlgorithmRenderer::implication(DCube &res, const DCube &tc)
{
    int i, j, lock, outpNode, devPt, lastCubeIndex;
    unsigned char matchStat;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -