Java 铁人三项赛团队实现最佳完成时间的算法
老师计划一场比赛,每位参赛者必须完成20圈的游泳,然后是10公里的自行车赛,最后是3公里的跑步。例如,换句话说,第一个参赛者游了20圈,下车,开始骑自行车。第一个人一离开游泳池,第二个选手就开始游20圈;当他或她出去并开始骑自行车时,第三名选手开始游泳。等等 每位参赛者都有一个预计的游泳时间,即完成20圈游泳的预计时间,同时每位参赛者都有一个预计的自行车和跑步时间。问题是为比赛设计一个时间表,也就是为参赛者的起跑顺序。参与者可以同时骑自行车和比赛,但最多只能有一个人在游泳池中 问题:设计一个有效的算法来调度上述任务? 并用程序证明了算法的正确性 尝试的解决方案: 我有一个想法: 将参赛者从1初始化为n, 让si、bi、ri表示游泳、自行车和跑步时间选手i。 我们按循环时间+跑步时间的降序排列参赛者,并按此顺序发送。Java 铁人三项赛团队实现最佳完成时间的算法,java,algorithm,Java,Algorithm,老师计划一场比赛,每位参赛者必须完成20圈的游泳,然后是10公里的自行车赛,最后是3公里的跑步。例如,换句话说,第一个参赛者游了20圈,下车,开始骑自行车。第一个人一离开游泳池,第二个选手就开始游20圈;当他或她出去并开始骑自行车时,第三名选手开始游泳。等等 每位参赛者都有一个预计的游泳时间,即完成20圈游泳的预计时间,同时每位参赛者都有一个预计的自行车和跑步时间。问题是为比赛设计一个时间表,也就是为参赛者的起跑顺序。参与者可以同时骑自行车和比赛,但最多只能有一个人在游泳池中 问题:设计一个有效
我无法正确制定算法和程序,因此需要帮助。这是贪婪编程的明显例子注:贪婪并非最佳选择始终: 我在这里假设您希望最小化总时间,因为这里没有提到 算法: 让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;