5588葡京线路逾期火车集体杀人事件

火车临时停车之上,林瑜看了同等肉眼车窗外,一侧的室外是同样漫漫斜纵的便道,电线杆安静地好在麦田里。另一侧是乌漆漆的煤运火车,标在几只看无太明了的数字。

目录

1 style=”font-family: 宋体;”>问题讲述

2 style=”font-family: 宋体;”>解决方案

2.1 style=”font-family: 宋体;”>蛮力法

2.2 style=”font-family: 宋体;”>减治法

2.2.1 Johson-Trotter style=”font-family: 宋体;”>算法

2.2.2 style=”font-family: 宋体;”>基于字典序的算法

它任了邻近一个钟头的音乐,等回喽神来,车还没出发,车厢里还有人口当吃中饭,泡面的含意让它们沉浸了一阵子,转又戴上了耳机。

 

顶车少只钟头后它们起觉得渴,书包放在行李架及,车厢里人潮拥挤,不绝好意思麻烦人家支援它得到,卖零食之车推过来,她问了可乐的标价,六块,售货员有点邪恶,她摇摇头,不要了谢谢。


车上有有限只娃娃,一个孩开始哭,撕心裂肺的啼哭,要吃奶,妈妈说在口前不能够吃奶,孩子就大声哭嚷,林瑜瞪了那么儿女同一目,那孩子满地持续大哭,大约二十分钟竟使停止下之时,另一个孩子开始哭,要下车打,家长开心地落在他,像是子女正落地得使哭几名声大家才知晓他是一样,连续不停的哭声加剧了车厢里藏已老的苦恼。

1 问题讲述

岂为同步行商问题?随非专业的传教,这个题目要求找来一致漫漫**n**个给定的城池中的极致差路径,使我们在返回触发的城前面,对每个都还仅仅看同一糟糕。这般该问题即使得表达为请一个图的极度缺乏哈密顿回路的题材。(哈密顿回路:定义为一个对图的每个终端都只有穿一软的回路)

 

万分轻看下,哈密顿回路也足以定义也n+1只相邻顶点v1,v2,v3,…,vn,v1的一个列。其中,序列的首先单极点和尾声一个终端是一致的,而另外n-1个顶都是互不相同之。并且,在不去一般性的前提下,可以要,所有的回路都开同终止于同一的特定顶点。因此,可以经过生成n-1个中等都的结合来赢得所有的远足路线,计算这些线路的长短,然后求取最短的路线。下图是拖欠问题的一个小范围实例,并就此该方法取得了它的散,具体如下:

 5588葡京线路 1

贪图1 使用蛮力法求解旅行商问题

 

 


鲜个半钟头了邪,她打开手机看了拘留,准备去划一和洗手间,在洗煤间门口等候之空里,她看来了有人当网上查询过时,还闹非至一个小时才会出发,她思量了相思音乐列表里睡的凡几乎首歌唱,大概听个别整个就是会出发了。

2 解决方案

回站位上的时节,旁边学生模样的口无奈的说了句手机电量要耗尽了,她再望窗外,小路延伸的自由化破旧的房间空荡荡地一直于视线里,乘务员通过的早晚,大家像围观外星生物一样问这问那,什么时移动,为什么停车,哪里故障了,车厢拥挤不堪,一些人大为着,向前移动什么,堵在怎么!乘务员什么具体的语也从没说,只是尽量安抚乘客的心思。她打开手机,时间表又为后拖了大体上时。戴耳机太老了头干巴巴地疼,大概把列表里之乐又任一遍,应该能出发了。

2.1 蛮力法

此使用蛮力法解决旅行商问题,取之是4只市面,并一度定义好各个城市次的去(**PS**:该去下二维数组初始化定义,此处的距离是依据图1蒙所显示距离定义)。此处主要是于体会下蛮力法解决该问题的琢磨,如一旦加上化普遍规模问题,还请大家温馨有些修改一下哒。对于代码中一旦遇到不可知亮的地方,可以参见文章最后给闹之参考资料链接,以及有关代码注解~

具体代码如下:

package com.liuzhen.chapterThree;

public class TravelingSalesman {

    public int count = 0;     //定义全局变量,用于计算当前已行走方案次数,初始化为0
    public int MinDistance = 100;    //定义完成一个行走方案的最短距离,初始化为100(PS:100此处表示比实际要大很多的距离)
    public int[][] distance = {{0,2,5,7},{2,0,8,3},{5,8,0,1},{7,3,1,0}};   //使用二维数组的那个音图的路径相关距离长度
    /*
     * start为开始进行排序的位置
     * step为当前正在行走的位置
     * n为需要排序的总位置数
     * Max为n!值
     */
    public void Arrange(int[] A,int start,int step,int n,int Max){
        if(step == n){   // 当正在行走的位置等于城市总个数时
            ++count;           //每完成一次行走方案,count自增1
            printArray(A);     //输出行走路线方案及其总距离
        }
        if(count == Max)
            System.out.println("已完成全部行走方案!!!,最短路径距离为:"+MinDistance);  
        else{
            for(int i = start;i < n;i++){   
                /*第i个数分别与它后面的数字交换就能得到新的排列,从而能够得到n!次不同排序方案
                 * (PS:此处代码中递归的执行顺序有点抽象,具体解释详见本人另一篇博客:)  
                 *算法笔记_017:递归执行顺序的探讨(Java)

*/
                swapArray(A,start,i);
                Arrange(A,start+1,step+1,n,Max);
                swapArray(A,i,start);
            }
        }
    }

    //交换数组中两个位置上的数值
    public  void swapArray(int[] A,int p,int q){
        int temp = A[p];
        A[p] = A[q];
        A[q] = temp;
    }

    //输出数组A的序列,并输出当前行走序列所花距离,并得到已完成的行走方案中最短距离
    public void printArray(int[] A){
        for(int i = 0;i < A.length;i++)   //输出当前行走方案的序列
            System.out.print(A[i]+"  ");

        int tempDistance = distance[A[0]][A[3]];     //此处是因为,最终要返回出发地城市,所以总距离要加上最后到达的城市到出发点城市的距离
        for(int i = 0;i < (A.length-1);i++)   //输出当前行走方案所花距离
            tempDistance += distance[A[i]][A[i+1]];

        if(MinDistance > tempDistance)   //返回当前已完成方案的最短行走距离
            MinDistance = tempDistance;

        System.out.println("  行走路程总和:"+tempDistance);
    }

    public static void main(String[] args){
        int[] A = {0,1,2,3};
        TravelingSalesman test = new TravelingSalesman();
        test.Arrange(A,0,0,4,24);    //此处Max = 4!=24
    }
}

 

运行结果:

0  1  2  3    行走路程总和:18
0  1  3  2    行走路程总和:11
0  2  1  3    行走路程总和:23
0  2  3  1    行走路程总和:11
0  3  2  1    行走路程总和:18
0  3  1  2    行走路程总和:23
1  0  2  3    行走路程总和:11
1  0  3  2    行走路程总和:18
1  2  0  3    行走路程总和:23
1  2  3  0    行走路程总和:18
1  3  2  0    行走路程总和:11
1  3  0  2    行走路程总和:23
2  1  0  3    行走路程总和:18
2  1  3  0    行走路程总和:23
2  0  1  3    行走路程总和:11
2  0  3  1    行走路程总和:23
2  3  0  1    行走路程总和:18
2  3  1  0    行走路程总和:11
3  1  2  0    行走路程总和:23
3  1  0  2    行走路程总和:11
3  2  1  0    行走路程总和:18
3  2  0  1    行走路程总和:11
3  0  2  1    行走路程总和:23
3  0  1  2    行走路程总和:18
已完成全部行走方案!!!,最短路径距离为:11

 

为就五分钟的年月,她更询问的时光曾经以过半时,此时既停车4只钟头,她起查找火车晚点的赔付,可惜并没发生因此之规章,她还要询问过时,已经远非有关信息了。又有乘务员通过时,告诉大家前方站线路故障,所有的车都以这边住在。

2.2 减治法

旅行商问题之着力,就是求n个例外城市之通通排,通俗一点吧,就是求1~n的均列。下面两种方法还是基于减治思想进行的,此处就兑现求取1~n的净排。对于各级一样栽排列,在旅行商问题被尚得求取其对应路径长度,最后,在进展比从而获得最好短路径,对于求取最差路径的思辨在2.1蛮力法中已经反映,此处不以又,感兴趣的校友可以团结还下手实现转~

旁边的煤运火车走了,十分钟后以来了同一部又开走了,再过了老大钟左右,又是如出一辙辆经过的车。

2.2.1 Johson-Trotter算法

 此处算法思想借用《算法设计及分析基础》第三版及教学,具体如下:

5588葡京线路 2

5588葡京线路 3

切切实实贯彻代码如下:

package com.liuzhen.chapter4;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

public class Arrange {
    //使用JohnsonTrotter算法获取1~n的全排列
    public HashMap<Integer , String> getJohnsonTrotter(int n){
        HashMap<Integer , String> hashMap = new HashMap<Integer , String>();
        int count = 0;                //用于计算生成排列的总个数,初始化为0
        int[] arrayN = new int[n];
        int[] directionN = new int[n+1];      //directionN[i]用于标记1~n中数字i上的箭头方向,初始化值为0,表示箭头方向向左;值为1 表示箭头方向向右
        for(int i = 0;i < n;i++)
            arrayN[i] = i+1;
        String result = getArrayString(arrayN);
        hashMap.put(count, result);        //将原始排列添加到哈希表中
        while(judgeMove(arrayN,directionN)){      //存在一个移动元素
            int maxI = getMaxMove(arrayN,directionN);
            if(directionN[arrayN[maxI]] == 0)      //箭头指向左方
                swap(arrayN,maxI,--maxI);
            if(directionN[arrayN[maxI]] == 1)       //箭头指向右方
                swap(arrayN,maxI,++maxI);
            for(int i = 0;i < n;i++){               //调转所有大于arrayN[maxI]的数的箭头方向
                if(arrayN[i] > arrayN[maxI]){
                    if(directionN[arrayN[i]] == 0)
                         directionN[arrayN[i]] = 1;
                    else
                        directionN[arrayN[i]] = 0;
                }
            }
            count++;
            result = getArrayString(arrayN);
            hashMap.put(count, result);        //将得到的新排列添加到哈希表中
        }
        return hashMap;
    }
    //判断数组arrayN中是否存在可移动元素
    public boolean judgeMove(int[] arrayN,int[] directionN){
        boolean judge = false;
        for(int i = arrayN.length - 1;i >= 0;i--){
            if(directionN[arrayN[i]] == 0 && i != 0){     //当arrayN[i]数字上的箭头方向指向左边时
                if(arrayN[i] > arrayN[i-1])
                    return true;
            }
            if(directionN[arrayN[i]] == 1 && i != (arrayN.length-1)){    //当arrayN[i]数字上的箭头方向指向右边时
                if(arrayN[i] > arrayN[i+1])
                    return true;
            }
        }
        return judge;
    }
    //获取数组arrayN中最大的可移动元素的数组下标
    public int getMaxMove(int[] arrayN,int[] directionN){
        int result = 0;
        int temp = 0;
        for(int i = 0;i < arrayN.length;i++){
            if(directionN[arrayN[i]] == 0 && i != 0){     //当arrayN[i]数字上的箭头方向指向左边时
                if(arrayN[i] > arrayN[i-1]){
                    int max = arrayN[i];
                    if(max > temp)
                        temp = max;
                }
            }
            if(directionN[arrayN[i]] == 1 && i != (arrayN.length-1)){    //当arrayN[i]数字上的箭头方向指向右边时
                if(arrayN[i] > arrayN[i+1]){
                    int max = arrayN[i];
                    if(max > temp)
                        temp = max;
                }    
            }
        }
        for(int i = 0;i < arrayN.length;i++){
            if(arrayN[i] == temp)
                return i;
        }
        return result;
    }
    //交换数组中两个位置上的数值
    public void swap(int[] array,int m,int n){
        int temp = array[m];
        array[m] = array[n];
        array[n] = temp;
    }
    //把数组array中所有元素按照顺序以字符串结果返回
    public String getArrayString(int[] array){
        String result = "";
        for(int i = 0;i < array.length;i++)
            result = result + array[i];
        return result;
    }

    public static void main(String[] args){
        Arrange test = new Arrange();
        HashMap<Integer , String> hashMap = test.getJohnsonTrotter(3);
        Collection<String> c1 = hashMap.values();
        Iterator<String> ite = c1.iterator();
        while(ite.hasNext())
            System.out.println(ite.next());
        System.out.println(hashMap);

    }
}

运作结果:

123
132
312
321
231
213
{0=123, 1=132, 2=312, 3=321, 4=231, 5=213}

 

停车5独小时后,太阳落下来了,天苍苍黑,路灯发出微弱的独,火车广播热切切的游说起来供晚餐了,餐车及零食车不断推进过来,乘客等一致赖以同样赖躲避,小车的车轮也磨了相同各又平等各乘客的下。

2.2.2 基于字典序的算法

  此处算法思想为借《算法设计以及析基础》第三版本上教学,具体如下:

5588葡京线路 4

5588葡京线路 5

切切实实落实代码如下:

package com.liuzhen.chapter4;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

public class Arrange1 {

    public HashMap<Integer,String> getLexicographicPermute(int n){
        HashMap<Integer,String> hashMap = new HashMap<Integer,String>();
        int count = 0;         //用于计算生成排列的总个数,初始化为0
        int[] arrayN = new int[n];
        for(int i = 0;i < n;i++)
            arrayN[i] = i+1;
        String result = getArrayString(arrayN);
        hashMap.put(count, result);        //将原始排列添加到哈希表中
        while(riseTogetherArray(arrayN)){     //数组中存在两个连续的升序元素
            int i = getMaxI(arrayN);     //找出使得ai<ai+1的最大i: ai+1>ai+2>...>an
            int j = getMaxJ(arrayN);     //找到使得ai<aj的最大索引j: j>=i,因为ai<ai+1
            swap(arrayN,i,j);
            reverseArray(arrayN,i+1,arrayN.length-1);
            result = getArrayString(arrayN);
            count++;
            hashMap.put(count, result);        //将新得到的排列添加到哈希表中
        }
        System.out.println("排列总个数count = "+(count+1));
        return hashMap;
    }
    //判断数组中是否 包含两个连续的升序元素
    public boolean riseTogetherArray(int[] arrayN){
        boolean result = false;
        for(int i = 1;i < arrayN.length;i++){
            if(arrayN[i-1] < arrayN[i])
                return true;
        }
        return result;
    }
    //返回i:满足ai<ai+1,ai+1>ai+2>...>an(PS:an为数组中最后一个元素)
    public int getMaxI(int[] arrayN){
        int result = 0;
        for(int i = arrayN.length-1;i > 0;){
            if(arrayN[i-1] > arrayN[i])
                i--;
            else
                return i-1;
        }
        return result;
    }
    //返回j:ai<aj的最大索引,j>=i+1,因为ai<ai+1(此处i值为上面函数getMaxI得到值)
    public int getMaxJ(int[] arrayN){
        int result = 0;
        int tempI = getMaxI(arrayN);
        for(int j = tempI+1;j < arrayN.length;){
            if(arrayN[tempI] < arrayN[j]){
                if(j == arrayN.length-1)
                    return j;
                j++;
            }
            else
                return j-1;
        }
        return result;
    }
    //交换数组中两个位置上的数值
    public void swap(int[] array,int m,int n){
        int temp = array[m];
        array[m] = array[n];
        array[n] = temp;
    }
    //将数组中a[m]到a[n]一段元素反序排列
    public void reverseArray(int[] arrayN,int m,int n){
        while(m < n){
            int temp = arrayN[m];
            arrayN[m++] = arrayN[n];
            arrayN[n--] = temp;
        }
    }
    //把数组array中所有元素按照顺序以字符串结果返回
    public String getArrayString(int[] array){
        String result = "";
        for(int i = 0;i < array.length;i++)
            result = result + array[i];
        return result;
    }

    public static void main(String[] args){
         Arrange1 test = new  Arrange1();
         HashMap<Integer,String> hashMap = test.getLexicographicPermute(3);
         Collection<String> c1 = hashMap.values();
         Iterator<String> ite = c1.iterator();
         while(ite.hasNext())
            System.out.println(ite.next());
         System.out.println(hashMap);
    }
}

运转结果:

排列总个数count = 6
123
132
213
231
312
321
{0=123, 1=132, 2=213, 3=231, 4=312, 5=321}

 

 

 参考资料:

        1. 【算法设计与析基础】蛮力法解决旅行商问题

 

零食车的肥乘务员在经这节车厢时,使劲推了了一样位乘客的脚,还没当回喽神来,又大力挤在那位乘客的不行腿,乘客给了千篇一律名气,胖乘务员不耐烦地或继续向前推进,乘客低声咒骂了同样词,胖乘务员不甘示弱一秒钟回骂过去,乘客伸出手去抓胖乘务员的发,不思装的拉链甩了一个胎的颜,孩子哇的等同名声杀哭起来,家长站起一拳揍到乘客的脸庞,车厢人大多,这号乘客一个趔趄没有摔倒,后面的人头也像多米诺骨牌一样倒下了,车厢里惨叫连连,孩子辈还吓哭了,一时间胡成一碗掺了酸咸苦辣的宏阔腐臭的粥。

车厢里由起了,被践踏踩的人满脸都是月经,倒在地上根本站不起来,肇事的肥胖乘务员像相同修巨大的鲨鱼游为窗边,外面了暗下来了,她取得下安全锤使劲砸向窗户,一下,两产,巨大的鸣响吸引了方方面面车厢里的眼光,三生,四生,嘭!车窗被挫折开,玻璃碎片划了它的肩,她勇敢跳下车窗,乘客接连在开为生超过,从行李架及取得下自己的箱往窗外扔,刚过下车的司乘人员为箱子砸中,发出同样名沉闷的痛叫,人们沿着火车的规则为前走,像极了逃离僵尸的幸存者。

林瑜以角落去躲了生遥远,直到车厢里的口逃空了,她由地上捡起充满是污浊的行李箱,往窗外扔,自己超越下来的下才发觉有些腿受伤,她昏沉沉地上前移动,慢慢的,她开始觉得大地在通往后低落,她差点没站稳。

“终于启动了!”车厢里一阵踊跃,接着是增加的掌声,她环顾了相同环车里之丁,涨红了脸。

5小时18分。