zoukankan      html  css  js  c++  java
  • 关于工序设计中最优解的一个算法【原创】

      以前做了个什么网络计划的算法,昨天拿来一看,好像还有问题,早上过来,弄了下,加了注释,和调试信息输出的功能,方便理解,我调试了下,没发现什么问题,如果大家发现的话,请告诉我,谢谢。
      由于程序是没人那么聪明的,只有遍历了。
      首先,两点之间加上中间那条线,用个类保存,类说明了这段路程的三个基本属性:起始点、结束点、需要时间,剩下的五个附加属性是遍历的时候要用到的:skip、hasFrontNode、eNodeIsBranchEndNode、sNodeIsBranchEndNode、sNodeIsBranchBeginNode,skip说明这段是否已经走过, hasFrontNode说明是否还有前驱节点,eNodeIsBranchEndNode说明这段路程的尾节点是否有多个前驱,sNodeIsBranchBeginNode是头节点是否有多个后继。
      首先,将所有路程信息用个数组保存起来。addProcessInfo(int sNode,int eNode,int lTime)是将一段路程的基本信息保存,setup()加入多段具体的路程信息,然后setNodeTag() 为每段路程信息的附加属性赋值。
      最主要的就在searchProcess(int sNode,int eNode)函数了,这是求任意两点间的,理论上来说,顺着找和倒着找是一样的,但是为了这个项目,我用的是倒着找的,因为要的是开始点到某个点的,顺着找的话,会走好多冤枉路,倒着的话,由于起点就一个,一般可以直接找到,而不会走过去了。
      下面说说这段函数的原理:
      找路径,好比人走路,找最优路径,需要走遍所有的路才能知道。一开始,看看所处的位置可以有几条路,都记下来,然后,每次挑一条可以走的路,走下去,走到走不动的地方,往回走,直到回到上个叉路口,如果回到起点,只能说明,没路了.....否则,就从后退到的那个路口继续那样的找路过程。走到终点后,记下这条路,然后,回到上个叉路口,继续走,又到终点,比比原来记下来的路,看哪条好,去掉不好的。一直就这么找,直到你走完所有的可能,才可能得到最优的解。
      找一个点到另一个点的最优路径,对于程序来说,问题就在于怎么保存走过的路,应该怎么保存,保存的是什么内容。由于我是倒着找的,所以在这段代码中,我保存的是new ProcessInfo(sNode, eNode,pInfo.lastingTime),实际上是不存在这样的路径的,只是为了方便回溯保存的,然后,递归找开始节点到当前路径的开始节点间的路径。
      下面我把代码贴出来,再附加二个调试信息,方便大家理解,关于那个网络图的定义可以在setup()函数中修改。
      首先是保存路径信息的类(ProcessInfo.java):
     1/**
     2 * @author zxub Created on 2005-5-21 10:36:29
     3 * 
     4 */

     5public class ProcessInfo {
     6    
     7    //基本信息:startNode,endNode,lastingTime
     8    protected int startNode; //开始节点
     9    protected int endNode; //终止节点
    10    protected int lastingTime; //路径持续时间
    11    //下面是附加信息,遍历的时候用到 
    12    protected boolean skip; //判断该路径是否已经走过
    13    protected boolean hasFrontNode; //路径是否有前驱节点
    14    protected boolean eNodeIsBranchEndNode; //路径终止节点是否有多个前驱
    15    protected boolean sNodeIsBranchBeginNode; //路径开始节点是否有多个后继   
    16
    17    /**
    18     *  保存任意两点间路径信息
    19     * @param sNode 开始节点
    20     * @param eNode 终止节点
    21     * @param lTime 持续时间
    22     */

    23    public ProcessInfo(int sNode,int eNode,int lTime)
    24    {
    25        this.startNode=sNode;
    26        this.endNode=eNode;
    27        this.lastingTime=lTime;
    28        //由于是刚开始保存,下面的几个信息不能确立,所以都是false
    29        this.skip=false;
    30        this.hasFrontNode=false;
    31        this.eNodeIsBranchEndNode=false;        
    32        this.sNodeIsBranchBeginNode=false;
    33    }

    34}
      然后,是主要的处理类(ProcessOpera.java):
      1import java.util.Stack;
      2
      3/**
      4 * @author zxub Created on 2005-5-22 10:19:51
      5 */

      6public class ProcessOpera
      7{
      8
      9    final int MAX = 100;
     10    // 保存路径信息的数组
     11    ProcessInfo process[] = new ProcessInfo[MAX];
     12    // 保存路径数目
     13    int numProcess = 0;
     14    // 分支路径栈
     15    Stack branchProcessStack = new Stack();
     16    // 用于搜索回退的栈
     17    Stack backTrackStack = new Stack();
     18    // 保存最后结果的栈
     19    Stack resultStack = new Stack();
     20    // 最长持续时间
     21    int maxLastingTime = 0;
     22
     23    /**
     24     * 测试用
     25     * 
     26     * @param args
     27     */

     28    public static void main(String[] args)
     29    {
     30
     31        ProcessOpera processOpera = new ProcessOpera();
     32        processOpera.setup();
     33        processOpera.setNodeTag();
     34//         for (int i = 0; i < processOpera.numProcess; i++)
     35//         {
     36//         System.out.print(processOpera
     37//         .getItemEarliestBeginTime(processOpera.process[i].startNode)
     38//         + " ");
     39//         System.out.print(processOpera.getProcessEarliestEndTime(
     40//         processOpera.process[i].startNode,
     41//         processOpera.process[i].endNode)
     42//         + " ");
     43//         System.out.print(processOpera.getProcessEarliestBeginTime(
     44//         processOpera.process[i].startNode,
     45//         processOpera.process[i].endNode)
     46//         + " ");
     47//         System.out.print(processOpera
     48//         .getItemLatestEndTime(processOpera.process[i].startNode)
     49//         + " ");
     50//         System.out.print(processOpera.getProcessLatestBeginTime(
     51//         processOpera.process[i].startNode,
     52//         processOpera.process[i].endNode)
     53//         + " ");
     54//         System.out.print(processOpera.getProcessLatestEndTime(
     55//         processOpera.process[i].startNode,
     56//         processOpera.process[i].endNode)
     57//         + " ");
     58//         System.out.print(processOpera.getProcessIntervalTime(
     59//         processOpera.process[i].startNode,
     60//         processOpera.process[i].endNode)
     61//         + " ");
     62//         System.out.print(processOpera.getKeyPath(
     63//         processOpera.process[i].startNode,
     64//         processOpera.process[i].endNode)
     65//         + " ");
     66//         System.out.println();
     67//         }
     68//        
     69//         System.out.println(processOpera.getItemEarliestBeginTime(1));
     70        processOpera.searchProcess(280);
     71        processOpera.showPath();
     72    }

     73
     74    /**
     75     * 初始化所有路径信息,放进数组中
     76     */

     77    public void setup()
     78    {
     79        addProcessInfo(1260);
     80        addProcessInfo(2310);
     81        addProcessInfo(2420);
     82        addProcessInfo(2540);
     83        addProcessInfo(2745);
     84        addProcessInfo(3718);
     85        addProcessInfo(450);
     86        addProcessInfo(4630);
     87        addProcessInfo(5715);
     88        addProcessInfo(6725);
     89        addProcessInfo(7835);
     90        addProcessInfo(880);
     91    }

     92
     93    /**
     94     * 增加路径信息到数组中
     95     * 
     96     * @param sNode
     97     *            开始节点
     98     * @param eNode
     99     *            终止节点
    100     * @param lTime
    101     *            持续时间
    102     */

    103    public void addProcessInfo(int sNode, int eNode, int lTime)
    104    {
    105        if (numProcess < MAX) // 如果数组没满的话
    106        {
    107            process[numProcess] = new ProcessInfo(sNode, eNode, lTime);
    108            numProcess++;
    109        }

    110        else
    111        {
    112            System.out
    113                .println("ProcessInfo database full!\nAdd error,program exit!");
    114            System.exit(0);
    115        }

    116    }

    117
    118    /**
    119     * 给所有路径信息中的附加属性赋值,要完成的话,需要遍历路径数组中的所有元素。 对于每个元素,要查看数组中的其它元素,确立关系
    120     */

    121    public void setNodeTag()
    122    {
    123        for (int i = 0; i < numProcess; i++// 遍历路径数组中的所有元素,process[i]是选取的路径
    124        {
    125            for (int j = 0; j < numProcess; j++// 查看其它元素
    126            {
    127                if (i == j) continue// 自己比自己,没得比,继续下次循环
    128                // 发现有路径可以和选取路径连接
    129                if (process[j].endNode == process[i].startNode)
    130                {
    131                    process[i].hasFrontNode = true;
    132                }

    133                // 两条不同路径的终结点一样
    134                if (process[j].endNode == process[i].endNode)
    135                {
    136                    process[i].eNodeIsBranchEndNode = true;
    137                }

    138                // 两条不同路径的起始点一样
    139                if (process[j].startNode == process[i].startNode)
    140                {
    141                    process[i].sNodeIsBranchBeginNode = true;
    142                }

    143            }

    144        }

    145    }

    146
    147    /**
    148     * 找出以选取点为终结点的没走过的一条路径
    149     * 
    150     * @param eNode
    151     *            所选取的点
    152     * @return 没被走过的以选取点为终结点的一条路径
    153     */

    154    public ProcessInfo findProcessInfo(int eNode)
    155    {
    156        for (int i = 0; i < numProcess; i++// 遍历路径信息
    157        {
    158            // process[i].skip=false 路径才没被走过
    159            if ((process[i].endNode == eNode) && (!process[i].skip))
    160            {
    161                // 由于深度复制和浅度复制的问题,所以复制的时候要新建一个ProcessInfo,而不是引用原来
    162                // 这是实现问题,算法与此可以无关
    163                ProcessInfo pInfo = new ProcessInfo(process[i].startNode,
    164                    process[i].endNode, process[i].lastingTime);
    165                process[i].skip = true;
    166                pInfo.hasFrontNode = process[i].hasFrontNode;
    167                pInfo.eNodeIsBranchEndNode = process[i].eNodeIsBranchEndNode;
    168                return pInfo;
    169            }

    170        }

    171        return null// 没有合适的路径就返回null了
    172    }

    173
    174    /**
    175     * 核心部分所在,查找任意2点间最长路径 基于AI设计,简单的AI 理论上来说,顺着找和倒着找是一样的,由于项目原因,这里我是倒着找的
    176     * 查找到的路径放在结果栈resultStack中
    177     * 
    178     * @param sNode
    179     *            开始节点
    180     * @param eNode
    181     *            终止节点
    182     * @param depth
    183     *            显示debug信息的时候用到,用于显示层次关系
    184     */

    185    public void searchProcess(int sNode, int eNode, int depth)
    186    {
    187        // 变量定义尽量少放循环中,故先定义
    188        int lastingTime; // 持续时间
    189        ProcessInfo pInfo; // 保存路径信息的对象
    190        int numStartNode = 0// 查找起点的个数
    191        Stack resultTemp; // 保存查找到路径的临时栈
    192        while ((pInfo = findProcessInfo(eNode)) != null)
    193        {
    194            // 分支节点数目+1
    195            numStartNode++;
    196            // 将查找到的路径信息放到分支节点栈,然后再查
    197            branchProcessStack.push(pInfo);
    198            showDebugInfo("分支路径栈加入:" + pInfo.startNode + "-->" + pInfo.endNode,
    199                depth);
    200        }

    201        if (numStartNode > 0// 有分支的话,如果这里不成立,整个就结束了
    202        {
    203            for (int i = 0; i < numStartNode; i++// 遍历分支节点栈
    204            {
    205                pInfo = (ProcessInfo) branchProcessStack.pop(); // 获得一条分支路径
    206                showDebugInfo("分支路径栈弹出:" + pInfo.startNode + "-->"
    207                        + pInfo.endNode, depth);
    208                // 为了防止头尾一样的路径,有了下面的判断,理论上是没有,但实际会出现
    209                if (pInfo.startNode == pInfo.endNode)
    210                {
    211                    showDebugInfo("头尾节点一样,丢弃!", depth + 1);
    212                    continue;
    213                }

    214
    215                // 如果存在可到达的路径的话,注意,这是个递归过程
    216                if (pInfo.startNode == sNode)
    217                {
    218                    // 当前路径加入回退栈,此时,回退栈里可以找出一条完整的路径了
    219                    backTrackStack.push(pInfo);
    220                    showDebugInfo("--------到达起点:" + pInfo.startNode + "-->"
    221                            + pInfo.endNode + "--------", depth);
    222                    int numbackTrackStack = backTrackStack.size();
    223                    resultTemp = new Stack();
    224                    lastingTime = 0;
    225                    for (int j = 0; j < numbackTrackStack; j++)
    226                    {
    227                        pInfo = (ProcessInfo) backTrackStack.get(j);
    228                        showDebugInfo("回溯栈内容进入临时结果栈:" + pInfo.startNode + "-->"
    229                                + pInfo.endNode, depth);
    230                        lastingTime += pInfo.lastingTime;
    231                        resultTemp.push(pInfo);
    232                    }

    233                    // 判断是不是更好的解
    234                    if (lastingTime > maxLastingTime)
    235                    {
    236                        showDebugInfo("========找到更优解!========", depth);
    237                        maxLastingTime = lastingTime;
    238                        resultStack = resultTemp;
    239                    }

    240                    // 找出一条后,需要回退,然后继续找下一条
    241                    // 获得剩余分支路径的数目
    242                    int numBranch = branchProcessStack.size();
    243
    244                    if (numBranch == 0)
    245                    {
    246                        // 没分支路径了,查找结束,清空回退栈
    247                        backTrackStack.removeAllElements();
    248                    }

    249                    else if (numBranch > 0)
    250                    {
    251                        int index = numBranch - 1;
    252                        int backTrackValue = ((ProcessInfo) branchProcessStack
    253                            .get(index)).endNode;
    254                        showDebugInfo("--------回退到节点:" + backTrackValue
    255                                + "--------", depth);
    256                        // 要回退到的节点必是分支路径栈中最上路径的尾节点
    257                        // 下面的循环就是一直回退,由于还有分支路径,所以可以找到要退到的点
    258                        do
    259                        {
    260                            pInfo = (ProcessInfo) backTrackStack.pop();
    261                            showDebugInfo("找到目标,回溯栈回退到:" + pInfo.startNode
    262                                    + "-->" + pInfo.endNode, depth);
    263                        }

    264                        while (pInfo.endNode != backTrackValue);
    265                    }

    266                    // 回退后,继续查找的话,所有路径的经过标记都要重置,否则经过了的路径是不会再去查的
    267                    // 由于开始路径不同,所以不会找到同样的结果
    268                    resetAllSkip();
    269                    continue;// 开始从下个分支路径查找
    270                }

    271                else
    272                // 没有直接从sNode到eNode的工序
    273                {
    274                    // 还没到目标
    275                    // 如果当前路径的起点还有前驱节点的话,需要递归查找,这是重点
    276                    if (pInfo.hasFrontNode)
    277                    {
    278                        ProcessInfo btPInfo = new ProcessInfo(sNode, eNode,
    279                            pInfo.lastingTime);
    280                        btPInfo.eNodeIsBranchEndNode = pInfo.eNodeIsBranchEndNode;
    281                        // 说明找过sNode-->eNode
    282                        backTrackStack.push(btPInfo);
    283                        showDebugInfo("回溯栈加入:" + sNode + "-->" + eNode
    284                                + ",说明找过" + sNode + "-->" + eNode, depth + 1);
    285                        showDebugInfo("查找:" + sNode + "-->" + pInfo.startNode,
    286                            depth + 1);
    287                        searchProcess(sNode, pInfo.startNode, depth + 2);
    288                    }

    289                    else
    290                    // 当前路径的起点无前驱,则路径错误,需要回溯
    291                    {
    292                        // 如果当前路径的终结点还有其它前驱的话,则退出本次循环,从下个分支路径查找
    293                        if (pInfo.eNodeIsBranchEndNode)
    294                        {
    295                            continue;
    296                        }

    297                        // 如果当前路径的终结点没有其它前驱,就要回退了
    298                        else if (backTrackStack.size() > 0)
    299                        {
    300                            // 开始回退,一直到找到个路径的终止节点有多个前驱为止,或者是回退栈已经空了。
    301                            do
    302                            {
    303                                pInfo = (ProcessInfo) backTrackStack.pop();
    304                                showDebugInfo("路径错误,开始回溯,回溯栈弹出:"
    305                                        + pInfo.startNode + "-->"
    306                                        + pInfo.endNode, depth + 1);
    307                            }

    308                            while ((!pInfo.eNodeIsBranchEndNode)
    309                                    && (backTrackStack.size() > 0));
    310                        }

    311                    }

    312                }

    313            }

    314            showDebugInfo("分支已被找遍", depth);
    315        }

    316        else
    317        {
    318            showDebugInfo("前面已走过这条路径且被证明走不通,或尾节点没有前驱节点", depth);
    319            if (backTrackStack.size()>0)
    320            {
    321                pInfo = (ProcessInfo) backTrackStack.pop();
    322                showDebugInfo("路径不通,回溯栈弹出:" + pInfo.startNode + "-->"
    323                        + pInfo.endNode, depth - 1);
    324                if (branchProcessStack.size()>0)
    325                {
    326                    int fixNode = ((ProcessInfo) branchProcessStack.lastElement()).endNode;            
    327                    if (fixNode != pInfo.endNode)
    328                    {
    329                        showDebugInfo("========需要调整回溯栈========", depth);
    330                        showDebugInfo("========开始调整回溯栈========", depth);
    331                        do
    332                        {
    333                            pInfo = (ProcessInfo) backTrackStack.pop();
    334                            showDebugInfo("回溯栈弹出:" + pInfo.startNode + "-->"
    335                                    + pInfo.endNode, depth + 1);
    336                        }

    337                        while (fixNode != pInfo.endNode);
    338                        showDebugInfo("========回溯栈调整结束========", depth);
    339                    }

    340                }

    341            }
                            
    342        }

    343    }

    344    
    345    private void showDebugInfo(String info, int blankCount)
    346    {
    347        String blank = "";
    348        for (int i = 0; i < blankCount; i++)
    349        {
    350            blank += "  ";
    351        }

    352        System.out.println(blank + info);
    353    }

    354
    355    public int getLastingTime(int sNode, int eNode)
    356    {
    357        int lastingTime = 0;
    358        ProcessInfo pInfo;
    359        searchProcess(sNode, eNode, 0);
    360        int num = resultStack.size();
    361        for (int i = num - 1; i >= 0; i--)
    362        {
    363            pInfo = (ProcessInfo) resultStack.get(i);
    364            lastingTime += pInfo.lastingTime;
    365        }

    366        return lastingTime;
    367    }

    368
    369    public void showPath()
    370    {
    371        ProcessInfo pInfo;
    372        int num = resultStack.size();
    373        if (num==0)
    374        {
    375            showDebugInfo("========没有符合要求的路径========",0);
    376        }

    377        else
    378        {
    379            for (int i = 0; i < num; i++)
    380            {
    381                pInfo = (ProcessInfo) resultStack.pop();
    382                System.out.print("-->" + pInfo.endNode);
    383            }

    384        }
            
    385    }

    386
    387    public void resetAllSkip()
    388    {
    389        for (int i = 0; i < numProcess; i++)
    390        {
    391            process[i].skip = false;
    392        }

    393    }

    394
    395    public int getItemEarliestBeginTime(int itemIndex)
    396    {
    397        maxLastingTime = 0;
    398        backTrackStack.removeAllElements();
    399        resultStack.removeAllElements();
    400        return getLastingTime(1, itemIndex);
    401    }

    402
    403    public int getProcessEarliestEndTime(int sNode, int eNode)
    404    {
    405        for (int i = 0; i < numProcess; i++)
    406        {
    407            if ((process[i].startNode == sNode)
    408                    && (process[i].endNode == eNode))
    409            {
    410                return (getItemEarliestBeginTime(sNode) + process[i].lastingTime);
    411            }

    412        }

    413        return 0;
    414    }

    415
    416    public int getProcessEarliestBeginTime(int sNode, int eNode)
    417    {
    418        return (getItemEarliestBeginTime(sNode));
    419    }

    420
    421    public int getItemLatestEndTime(int itemIndex)
    422    {
    423        int maxTime = 0;
    424        int t = 0;
    425        int pos = -1;
    426        boolean hasNextNode = false;
    427        backTrackStack.removeAllElements();
    428        resultStack.removeAllElements();
    429        for (int i = 0; i < numProcess; i++)
    430        {
    431            if (process[i].startNode == itemIndex)
    432            {
    433                if (process[i].sNodeIsBranchBeginNode)
    434                {
    435                    return (getItemEarliestBeginTime(itemIndex));
    436                }

    437                hasNextNode = true;
    438                t = getItemEarliestBeginTime(process[i].endNode);
    439                if (t > maxTime)
    440                {
    441                    pos = i;
    442                    maxTime = t;
    443                }

    444            }

    445        }

    446        if (!hasNextNode)
    447        {
    448            return (getItemEarliestBeginTime(itemIndex));
    449        }

    450        else
    451        {
    452            return (t - process[pos].lastingTime);
    453        }

    454    }

    455
    456    public int getProcessLatestEndTime(int sNode, int eNode)
    457    {
    458        return (getItemLatestEndTime(eNode));
    459    }

    460
    461    public int getProcessLatestBeginTime(int sNode, int eNode)
    462    {
    463        for (int i = 0; i < numProcess; i++)
    464        {
    465            if ((process[i].startNode == sNode)
    466                    && (process[i].endNode == eNode))
    467            {
    468                return (getProcessLatestEndTime(sNode, eNode) - process[i].lastingTime);
    469            }

    470        }

    471        return 0;
    472    }

    473
    474    public int getProcessIntervalTime(int sNode, int eNode)
    475    {
    476        return (getProcessLatestEndTime(sNode, eNode) - getProcessEarliestEndTime(
    477            sNode, eNode));
    478    }

    479
    480    public int getKeyPath(int sNode, int eNode)
    481    {
    482        if ((getProcessIntervalTime(sNode, eNode) == 0&& (sNode != eNode))
    483        {
    484            return eNode;
    485        }

    486        else
    487        {
    488            return 0;
    489        }

    490    }
        
    491}
      最后是调试信息(找2到8):
    分支路径栈加入:7-->8
    分支路径栈加入:
    8-->8
    分支路径栈弹出:
    8-->8
      头尾节点一样,丢弃
    !
    分支路径栈弹出:
    7-->8
      回溯栈加入:
    2-->8,说明找过2-->8
      查找:
    2-->7
        分支路径栈加入:
    2-->7
        分支路径栈加入:
    3-->7
        分支路径栈加入:
    5-->7
        分支路径栈加入:
    6-->7
        分支路径栈弹出:
    6-->7
          回溯栈加入:
    2-->7,说明找过2-->7
          查找:
    2-->6
            分支路径栈加入:
    4-->6
            分支路径栈弹出:
    4-->6
              回溯栈加入:
    2-->6,说明找过2-->6
              查找:
    2-->4
                分支路径栈加入:
    2-->4
                分支路径栈弹出:
    2-->4
                
    --------到达起点:2-->4--------
                回溯栈内容进入临时结果栈:
    2-->8
                回溯栈内容进入临时结果栈:
    2-->7
                回溯栈内容进入临时结果栈:
    2-->6
                回溯栈内容进入临时结果栈:
    2-->4
                
    ========找到更优解!========
                
    --------回退到节点:7--------
                找到目标,回溯栈回退到:
    2-->4
                找到目标,回溯栈回退到:
    2-->6
                找到目标,回溯栈回退到:
    2-->7
                分支已被找遍
            分支已被找遍
        分支路径栈弹出:
    5-->7
          回溯栈加入:
    2-->7,说明找过2-->7
          查找:
    2-->5
            分支路径栈加入:
    2-->5
            分支路径栈加入:
    4-->5
            分支路径栈弹出:
    4-->5
              回溯栈加入:
    2-->5,说明找过2-->5
              查找:
    2-->4
                分支路径栈加入:
    2-->4
                分支路径栈弹出:
    2-->4
                
    --------到达起点:2-->4--------
                回溯栈内容进入临时结果栈:
    2-->8
                回溯栈内容进入临时结果栈:
    2-->7
                回溯栈内容进入临时结果栈:
    2-->5
                回溯栈内容进入临时结果栈:
    2-->4
                
    --------回退到节点:5--------
                找到目标,回溯栈回退到:
    2-->4
                找到目标,回溯栈回退到:
    2-->5
                分支已被找遍
            分支路径栈弹出:
    2-->5
            
    --------到达起点:2-->5--------
            回溯栈内容进入临时结果栈:
    2-->8
            回溯栈内容进入临时结果栈:
    2-->7
            回溯栈内容进入临时结果栈:
    2-->5
            
    --------回退到节点:7--------
            找到目标,回溯栈回退到:
    2-->5
            找到目标,回溯栈回退到:
    2-->7
            分支已被找遍
        分支路径栈弹出:
    3-->7
          回溯栈加入:
    2-->7,说明找过2-->7
          查找:
    2-->3
            分支路径栈加入:
    2-->3
            分支路径栈弹出:
    2-->3
            
    --------到达起点:2-->3--------
            回溯栈内容进入临时结果栈:
    2-->8
            回溯栈内容进入临时结果栈:
    2-->7
            回溯栈内容进入临时结果栈:
    2-->3
            
    --------回退到节点:7--------
            找到目标,回溯栈回退到:
    2-->3
            找到目标,回溯栈回退到:
    2-->7
            分支已被找遍
        分支路径栈弹出:
    2-->7
        
    --------到达起点:2-->7--------
        回溯栈内容进入临时结果栈:
    2-->8
        回溯栈内容进入临时结果栈:
    2-->7
        分支已被找遍
    分支已被找遍
    -->4-->6-->7-->8
      下面来个找3到7的:
     1分支路径栈加入:2-->7
     2分支路径栈加入:3-->7
     3分支路径栈加入:5-->7
     4分支路径栈加入:6-->7
     5分支路径栈弹出:6-->7
     6  回溯栈加入:3-->7,说明找过3-->7
     7  查找:3-->6
     8    分支路径栈加入:4-->6
     9    分支路径栈弹出:4-->6
    10      回溯栈加入:3-->6,说明找过3-->6
    11      查找:3-->4
    12        分支路径栈加入:2-->4
    13        分支路径栈弹出:2-->4
    14          回溯栈加入:3-->4,说明找过3-->4
    15          查找:3-->2
    16            分支路径栈加入:1-->2
    17            分支路径栈弹出:1-->2
    18              路径错误,开始回溯,回溯栈弹出:3-->4
    19              路径错误,开始回溯,回溯栈弹出:3-->6
    20              路径错误,开始回溯,回溯栈弹出:3-->7
    21            分支已被找遍
    22        分支已被找遍
    23    分支已被找遍
    24分支路径栈弹出:5-->7
    25  回溯栈加入:3-->7,说明找过3-->7
    26  查找:3-->5
    27    分支路径栈加入:2-->5
    28    分支路径栈加入:4-->5
    29    分支路径栈弹出:4-->5
    30      回溯栈加入:3-->5,说明找过3-->5
    31      查找:3-->4
    32        前面已走过这条路径且被证明走不通,或尾节点没有前驱节点
    33      路径不通,回溯栈弹出:3-->5
    34    分支路径栈弹出:2-->5
    35      回溯栈加入:3-->5,说明找过3-->5
    36      查找:3-->2
    37        前面已走过这条路径且被证明走不通,或尾节点没有前驱节点
    38      路径不通,回溯栈弹出:3-->5
    39        ========需要调整回溯栈========
    40        ========开始调整回溯栈========
    41          回溯栈弹出:3-->7
    42        ========回溯栈调整结束========
    43    分支已被找遍
    44分支路径栈弹出:3-->7
    45--------到达起点:3-->7--------
    46回溯栈内容进入临时结果栈:3-->7
    47========找到更优解!========
    48--------回退到节点:7--------
    49找到目标,回溯栈回退到:3-->7
    50分支路径栈弹出:2-->7
    51  回溯栈加入:3-->7,说明找过3-->7
    52  查找:3-->2
    53    分支路径栈加入:1-->2
    54    分支路径栈弹出:1-->2
    55      路径错误,开始回溯,回溯栈弹出:3-->7
    56    分支已被找遍
    57分支已被找遍
    58-->7
      先写到这里,以后再来修改。
  • 相关阅读:
    localStorage溢出问题
    面试题梳理
    灵活的楼梯导航条代码
    日期初始化
    css 控制横向布局,超出隐藏,滚动
    自定义滚动条样式
    jquery源码之JQ对象
    jqeury源码之变量解析
    jquery源码之通篇概要
    工作站流处理
  • 原文地址:https://www.cnblogs.com/zxub/p/261426.html
Copyright © 2011-2022 走看看