Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 铁人三项赛团队实现最佳完成时间的算法_Java_Algorithm - Fatal编程技术网

Java 铁人三项赛团队实现最佳完成时间的算法

Java 铁人三项赛团队实现最佳完成时间的算法,java,algorithm,Java,Algorithm,老师计划一场比赛,每位参赛者必须完成20圈的游泳,然后是10公里的自行车赛,最后是3公里的跑步。例如,换句话说,第一个参赛者游了20圈,下车,开始骑自行车。第一个人一离开游泳池,第二个选手就开始游20圈;当他或她出去并开始骑自行车时,第三名选手开始游泳。等等 每位参赛者都有一个预计的游泳时间,即完成20圈游泳的预计时间,同时每位参赛者都有一个预计的自行车和跑步时间。问题是为比赛设计一个时间表,也就是为参赛者的起跑顺序。参与者可以同时骑自行车和比赛,但最多只能有一个人在游泳池中 问题:设计一个有效

老师计划一场比赛,每位参赛者必须完成20圈的游泳,然后是10公里的自行车赛,最后是3公里的跑步。例如,换句话说,第一个参赛者游了20圈,下车,开始骑自行车。第一个人一离开游泳池,第二个选手就开始游20圈;当他或她出去并开始骑自行车时,第三名选手开始游泳。等等

每位参赛者都有一个预计的游泳时间,即完成20圈游泳的预计时间,同时每位参赛者都有一个预计的自行车和跑步时间。问题是为比赛设计一个时间表,也就是为参赛者的起跑顺序。参与者可以同时骑自行车和比赛,但最多只能有一个人在游泳池中

问题:设计一个有效的算法来调度上述任务? 并用程序证明了算法的正确性

尝试的解决方案: 我有一个想法: 将参赛者从1初始化为n, 让si、bi、ri表示游泳、自行车和跑步时间选手i。 我们按循环时间+跑步时间的降序排列参赛者,并按此顺序发送。
我无法正确制定算法和程序,因此需要帮助。

这是贪婪编程的明显例子注:贪婪并非最佳选择始终: 我在这里假设您希望最小化总时间,因为这里没有提到

算法:

让si、bi、ri表示游泳、自行车和跑步时间选手i

按参赛者完成所有三项任务的时间对他们进行排序,并按降序排列

根据步骤2的顺序对其进行调度

对于选手的分类:

计算每个人游泳、骑自行车和跑步所需的时间

将这些时间相加,并按降序排序


您只需要考虑两个简单的规则:

如果我们先派出花费最少时间游泳的选手,我们将缩短选手之间的完成时间。 如果两名选手的游泳时间相同怎么办?在这种情况下,总跑步+骑自行车时间较高的参赛者应首先被派去,以便他们能够在剩余活动中抢先一步。 考虑每位参赛者参加特定活动所需的时间:

Contestant->Swim time(mins)->Run time(mins)->Cycle time(mins)
A->1->1->1
B->2->1->1
C->1->1->1
案例1: 游泳时间最长的选手优先。比赛于下午12:00开始,顺序为B、A、C,我们有:

Swimming complete->Running complete->Cycling complete
B->12:02->12:03->12:04
A->12:03->12:04->12:05
C->12:04->12:05->12:06
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
B->12:03->12:04->12:05
C->12:04->12:05->12:06
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
C->12:02->12:03->12:04
B->12:04->12:05->12:06
案例2: 游泳时间最长的选手排名第二。比赛于下午12:00开始,顺序为A、B、C,我们有:

Swimming complete->Running complete->Cycling complete
B->12:02->12:03->12:04
A->12:03->12:04->12:05
C->12:04->12:05->12:06
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
B->12:03->12:04->12:05
C->12:04->12:05->12:06
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
C->12:02->12:03->12:04
B->12:04->12:05->12:06
案例3: 游泳时间最长的选手排名第三。比赛于下午12:00开始,顺序为A、C、B,我们有:

Swimming complete->Running complete->Cycling complete
B->12:02->12:03->12:04
A->12:03->12:04->12:05
C->12:04->12:05->12:06
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
B->12:03->12:04->12:05
C->12:04->12:05->12:06
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
C->12:02->12:03->12:04
B->12:04->12:05->12:06
你可以看到,在所有情况下,最后一名选手在12:06结束比赛。但是,如果有一名游泳时间最长的选手先走,第一名选手将在下午12:04结束比赛,第二名选手将在12:05结束比赛。如果两名游泳时间最长的选手获得第二名,第一名选手将在12:03结束比赛,第二名选手将在12:05结束比赛。在案例3中,游泳时间最长的选手排名第三,第一名选手在12:03结束比赛,第二名选手在12:04结束比赛。这是迄今为止最有效的命令,因为到12:04,您已经有两名选手完成了比赛

但是,如果两名参赛者游泳时间相同,但循环和跑步时间不同呢。考虑:

Contestant->Swim time(mins)->Run time(mins)->Cycle time(mins)
A->1->1->1
B->2->2->1
C->2->1->1
案例4:在游泳时间相同的两名选手中,自行车和跑步总时间较短的选手先:

Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
C->12:03->12:04->12:05
B->12:05->12:07->12:08
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
B->12:03->12:05->12:06
C->12:05->12:06->12:07
案例5:在游泳时间相同的两名选手中,自行车和跑步总时间较高的选手优先:

Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
C->12:03->12:04->12:05
B->12:05->12:07->12:08
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
B->12:03->12:05->12:06
C->12:05->12:06->12:07
可以看出,在案例4中,最后一名选手在下午12:08结束比赛,而在案例5中,最后一名选手在12:07结束比赛。这意味着,如果两名选手的游泳时间相同,则自行车+跑步总时间较高的选手应先走

要用Java编写此代码,请执行以下操作:

首先创建一个类来保存参赛者信息:

public class Contestant {
    private String name;
    private Map<String,Integer> timings = new HashMap<>();

    public Contestant(String name, Map<String, Integer> timings) {
        this.name = name;
        this.timings = timings;
    }

    public Integer getTimingFor(String activity) {
        return timings.get(activity);
    }

    public Map<String, Integer> getTimings() {
        return timings;
    }

    public String getName() {
        return name;
    }


}
然后创建一个比较器,决定哪位选手应该先于另一位选手。这个想法是按照游泳时间上升的顺序排列参赛者,然后按照剩余活动下降的顺序排列

  public class ContestantComparator implements Comparator<Contestant> {

    @Override
    public int compare(Contestant one, Contestant two) {
        int contestantOneSwimTime = one.getTimingFor("Swimming");
        int contestantTwoSwimTime = two.getTimingFor("Swimming");

        if(contestantOneSwimTime<contestantTwoSwimTime) {
            return -1;
        } else if(contestantOneSwimTime>contestantTwoSwimTime) {
            return 1;
        } else {
            int c1RemainingTimeExceptSwimming = 0;
            int c2RemainingTimeExceptSwimming = 0;

            for(String activity : one.getTimings().keySet()) {
                if(!activity.equals("Swimming")) {
                    c1RemainingTimeExceptSwimming+=one.getTimingFor(activity);
                }
            }

            for(String activity : two.getTimings().keySet()) {
                if(!activity.equals("Swimming")) {
                    c2RemainingTimeExceptSwimming+=two.getTimingFor(activity);
                }
            }

            if(c1RemainingTimeExceptSwimming>c2RemainingTimeExceptSwimming) {
                return -1;
            } else if(c1RemainingTimeExceptSwimming<c2RemainingTimeExceptSwimming) {
                return 1;
            } else {
                return 0;
            }
        }
    }
}
要使用代码的主类:

public class Contest {

    public static void main(String []args) {
        Map<String,Integer> timings = new HashMap<String,Integer>();
        timings.put("Swimming", 1);
        timings.put("Running", 1);
        timings.put("Cycling", 1);
        Contestant a = new Contestant("A",timings);

        timings = new HashMap<String,Integer>();
        timings.put("Swimming", 1);
        timings.put("Running", 2);
        timings.put("Cycling", 1);
        Contestant b = new Contestant("B",timings);

        timings = new HashMap<String,Integer>();
        timings.put("Swimming", 1);
        timings.put("Running", 2);
        timings.put("Cycling", 2);
        Contestant c = new Contestant("C",timings);

        List<Contestant> contestants = new ArrayList<Contestant>();
        contestants.add(a);
        contestants.add(b);
        contestants.add(c);
        Collections.sort(contestants,new ContestantComparator());

        for(Contestant contestant : contestants) {
            System.out.println(contestant.getName());
        }

    }

}

请注意,参赛者类包含一个地图。此地图的目的是允许您为参赛者添加任意数量的任务,而无需更改代码。键表示游泳等活动,值整数表示相应活动的时间

如果你想按所需的时间来订购,可以考虑使用PriorityQueue,它可以让你以最快的时间找到下一个人。有什么帮助吗
你需要什么?您能发布到目前为止您已经尝试过的伪代码或实际java代码吗?您在哪里被卡住了?否则,看起来你只是在要求别人帮你完成这项任务。这真的不像按总时间降序排序那么简单。看我的答案。它是贪婪的方法,不确定它是否最优。但是我在这里做的是,最慢的选手应该先被送出,如此类推,最快的选手应该最后被送出,因为他可以覆盖其他选手。在你的方法中,如果游泳时间最少的选手被排在最后,但是如果他的自行车和跑步时间非常长呢。最终会增加总时间。因此,根据我的说法,考虑到总时间是很好的。@bot如果有两名选手10,10,10和9,20,30与你的接近,你会让选手第一次游完泳,所以当他在10后游完泳时,你会让下一名选手。总时间:10+9+20+30=69个单位在我的方法中,我会首先发送参赛者2:在我的方法中,总时间:9+20+30=59个单位在这里有一个基本的限制:参赛者可以同时骑车和比赛,但最多只能有人在游泳池中。我会先发送{9,20,30}和{10,10,10}秒。看来你不明白我的方法。@bot好的,如果时间是。。9,10,10 & 10,20,30.. 你的方法需要9+10+20+30=69,我的方法需要10+20+30=60,顺便说一句,我不是来证明我的方法是对的还是错的,也不是来证明你的方法。我在这里学习自己,帮助别人,也了解解决问题的不同方法。所以你需要一个输入,例如我在这里给出的。代码的时间复杂度是^2。我这样想的-如果有n个参赛者,那么我们将一直到最后n个选择截止日期最早的人。这个循环将运行n次。我的错我猜是错的T.C将是Onoops抱歉,伙计,我不知道我的笔记本电脑在这个网站上被冻结了,并随意点击它一定是在那个时候发生的,因为我是新的网站界面,所以我需要时间来适应,非常感谢你的时间和努力,虽然我对你的程序有一些疑问,但我不明白这部分代码的作用是什么?else{int p1TimeExceptSweering=0;int p2TimeExceptSweering=0;forString活动:one.getTimings.keySet{if!activity.EqualSweering{p1TimeExceptSweering+=one.getTimeFrameactivity;}}forString活动:two.getTimings.keySet{if!activity.equalswiming{p2timeexceptswiming+=two.getTimeFrameactivity;}}ifp1timeexceptswiming>p2timeexceptswiming{return-1;