首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >消防员在车辆座椅上就座的算法

消防员在车辆座椅上就座的算法
EN

Stack Overflow用户
提问于 2014-10-07 08:42:28
回答 2查看 95关注 0票数 0

我正在做一个项目,当志愿者消防员到达消防局取卡车时,让他们坐在座位上。

此外,一些消防员有驾照,一些人没有,还有一些人受过组长教育。

因此,我的想法是通过GPS跟踪他们,并向服务器发送到消防站的整数距离以及每个消防站的教育类型。

然后,每隔5秒运行一次算法,并根据新的GPS坐标改变自己的座位,直到1个人接近车站,然后标记为坐人。

这应该发生,直到没有空座位或不再有消防员呼叫或所有呼叫的消防员到达

我想要帮助的棘手的事情(除了如果我的想法是最优的),就是让消防员的位置最优。

我在考虑做一个可能的角色的优先列表。以及一份必须离开车站的车辆的优先顺序列表。

然后选择优先级最高的车辆和最高优先级的角色,并用受过教育的最近的消防员填充它。

但是,如果他是一名车手,但已经设置了领队座位,只有1名车手来了,还有更多的领队来了,两辆车不得不离开,这将是一个错误的解决方案,因为第二辆车不能离开。

同样,如果司机而不是团队领导是最高优先级,那么如果最近的被设置为司机,但也是唯一具有teamleader教育的司机,但更多的司机来了,那么这也是错误的。

对算法的工作有什么想法吗?或者有人知道解决这个问题的算法吗?

EN

回答 2

Stack Overflow用户

发布于 2014-10-07 22:31:47

你说得对,这种贪婪的方法不一定会给你一个最优的解决方案。你有没有看过/听说过线性规划,或者更具体地说,整数规划:http://en.wikipedia.org/wiki/Integer_programming

简而言之,整数规划是解决这些类型的调度问题的一种技术。这个问题有一些你希望最大化或最小化的目标,并且受到各种(线性)约束。整数,因为我们不能有半个志愿者。

根据您的描述,目标函数可能是最小化未部署的卡车数量和总等待时间。不同的卡车可以有不同的成本,以捕获不同的车辆优先级。

约束条件包括每辆车至少需要一名司机,至少一名组长,以及一名志愿者只能分配到一辆车上。可能还有其他你没有描述的限制,比如没有人可以在基地等待超过20分钟。

如果你搜索整数规划和调度,你应该能找到一些代码示例。你可能需要一个求解器来帮助你。维基有一个相当全面的列表,选择将取决于您的编程语言偏好和预算:http://en.wikipedia.org/wiki/Linear_programming#Solvers_and_scripting_.28programming.29_languages

票数 0
EN

Stack Overflow用户

发布于 2014-10-08 01:21:54

这样怎么样..。正如你注意到的,唯一冲突的情况是当你有一个消防员,既可以是司机,也可以是领导者。因为它只能占据一个位置..但也可能阻止了另一个..

所以不要从他们开始..首先从那些拥有以太潜水员执照或领导者教育的人开始..因为那些人已经有了预先定义的座位(他们唯一可以坐的座位)..

在这些都填好之后..分配那些能做以太工作的人,找那些缺了的座位,或者如果它们离得更近,就换一些。

在有了一队司机和一队领导之后..根据到消防站的距离对它们进行分类,并成对地分配给卡车。然后装满卡车的其余部分..正在按ETA的顺序从队列中删除。

不确定它是否总能给出最佳解决方案..但似乎是最理想的..你想要一些代码吗?C#?

这个问题让我很好奇。这是我所说的代码..eve如果你不用它的话

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace FF
{
    class Program
    {
        [Flags]
        public enum Skill
        {
            None = 0,
            Driver = 1,
            TeamLeader = 2,
        }
        public class FireFighter : IComparable<FireFighter>
        {
            public int ID;
            public Skill Skills;//the skills that he has
            public Skill Assigned;//the one that he will be deployed with
            public int ETA;
            public override string ToString()
            {
                return ID + "(" + Skills + ")" + " @ " + ETA + " minutes as " + this.Assigned;
            }


            int IComparable<FireFighter>.CompareTo(FireFighter other)
            {
                return this.ETA.CompareTo(other.ETA);
            }
        }
        public class Truck
        {
            public int ID;
            public int Capacity;
            public List<FireFighter> Crew = new List<FireFighter>();
        }
        static int TotalStationTrucks = 8;
        static List<Truck> Trucks = new List<Truck>();
        static List<FireFighter> Team = new List<FireFighter>();
        static Random Rnd = new Random();
        static void Main(string[] args)
        {
            //create the sample data
            int nAvailableSeats = 0;
            for (int i = 0; i < TotalStationTrucks; i++)
            {
                Truck oTruck = new Truck();
                oTruck.ID = i;
                nAvailableSeats += oTruck.Capacity = Rnd.Next(4, 7);//seats between 4 - 6
                Trucks.Add(oTruck);
            }
            for (int i = 0; i < nAvailableSeats * 2; i++)//add twice the amount of FF we need for all trucks
            {
                FireFighter oFireFighter = new FireFighter();
                oFireFighter.ID = i;
                oFireFighter.ETA = Rnd.Next(Int16.MaxValue);
                Team.Add(oFireFighter);
            }
            for (int i = 0; i < Trucks.Count * 2; i++)//add twice the drivers we need
            {
                FireFighter oFireFighter = Team[Rnd.Next(Team.Count)];
                oFireFighter.Skills |= Skill.Driver;
            }
            for (int i = 0; i < Trucks.Count * 2; i++)//add twice the leaders we need
            {
                FireFighter oFireFighter = Team[Rnd.Next(Team.Count)];
                oFireFighter.Skills |= Skill.TeamLeader;
            }
            for (int i = 0; i < Trucks.Count * 2; i++)//add twice the multitaskers  we need
            {
                FireFighter oFireFighter = Team[Rnd.Next(Team.Count)];
                oFireFighter.Skills = (Skill.TeamLeader|Skill.Driver);
            }
            //Truck that are going to be deployed
            int nTrucksToDeploy = Rnd.Next(2, Trucks.Count);  

            // distribute firefighter by ETA to minimize truck deploy
            //*******************************************************

            //Sort by ETA
            Team.Sort();
            //get top the ones that can only drive
            List<FireFighter> oSelectedDrivers = Team.FindAll(delegate(FireFighter item) { return item.Skills == Skill.Driver; }).GetRange(0, nTrucksToDeploy);
            oSelectedDrivers.ForEach(delegate(FireFighter item) { item.Assigned = Skill.Driver; });

            //get top the ones that can only lead
            List<FireFighter> oSelectedLeaders = Team.FindAll(delegate(FireFighter item) { return item.Skills == Skill.TeamLeader; }).GetRange(0, nTrucksToDeploy);
            oSelectedLeaders.ForEach(delegate(FireFighter item) { item.Assigned = Skill.TeamLeader; });

            //put them on a list of already assigned
            List<FireFighter> oAssigned = new List<FireFighter>();
            oAssigned.AddRange(oSelectedDrivers);
            oAssigned.AddRange(oSelectedLeaders);

            //get the ones that can do ether job 
            List<FireFighter> oMultitaskers = Team.FindAll(delegate(FireFighter item) { return item.Skills == (Skill.Driver | Skill.TeamLeader); });
            //sort by ETA
            oMultitaskers.Sort();
            oAssigned.Sort();
            //put a multitaskers in the queue if he is gonna arrive earlier than the most delayed 
            while (oMultitaskers[0].ETA < oAssigned[oAssigned.Count - 1].ETA)
            { 
                FireFighter oIsOut = oAssigned[oAssigned.Count - 1];
                FireFighter oIsIn = oMultitaskers[0];
                //swap tasks
                oIsIn.Assigned = oIsOut.Assigned;
                oIsOut.Assigned = Skill.None;
                //remove from respective queues
                oAssigned.RemoveAt(oAssigned.Count - 1);
                oMultitaskers.RemoveAt(0);
                //Add the multitasker to queue
                //and if you are questioning if the could get a better solution by choosing another assignment
                //that as no influence.. the optmizing condition is removing the slowest that was on queue
                oAssigned.Add(oIsIn);
                //the out guy is not added for two reasons
                //1st is not a multitasker
                //2nd and most importante.. he was the one with the highest ETA, we will NEVER gain by replacing another driver with this one
                //oMultitaskers.Add(oIsOut); 

                oMultitaskers.Sort();
                oAssigned.Sort();
            }

            //start filling the trucks take one of each from top, wich means the first truck will have the earliest departure
            for (int i = 0; i < nTrucksToDeploy; i++)
            {
                int nDriverIndex = oAssigned.FindIndex(delegate(FireFighter item) { return item.Assigned == Skill.Driver; });
                Trucks[i].Crew.Add(oAssigned[nDriverIndex]);
                oAssigned.RemoveAt(nDriverIndex);
                int nLeaderIndex = oAssigned.FindIndex(delegate(FireFighter item) { return item.Assigned == Skill.TeamLeader; });
                Trucks[i].Crew.Add(oAssigned[nLeaderIndex]);
                oAssigned.RemoveAt(nLeaderIndex);
            }
            //now fill the rest of the crew.. also ordered by ETA
            List<FireFighter> oUnassigned = Team.FindAll(delegate(FireFighter item) { return item.Assigned == Skill.None; });
            oUnassigned.Sort();
            for (int i = 0; i < nTrucksToDeploy; i++)
            {
                while (Trucks[i].Crew.Count < Trucks[i].Capacity)
                {
                    Trucks[i].Crew.Add(oUnassigned[0]);
                    oUnassigned.RemoveAt(0);
                }
            }

            //dump truck data
            Trace.WriteLine(String.Format("{0} trucks to be deployed",nTrucksToDeploy));
            for (int i = 0; i < nTrucksToDeploy; i++)
            {
                Trace.WriteLine(new String('-', 20));
                Truck oTruck = Trucks[i];
                oTruck.Crew.Sort();
                Trace.WriteLine(String.Format("truck {0} estimated time of departure: {1}",oTruck.ID,oTruck.Crew[oTruck.Crew.Count-1].ETA));
                for (int j = 0; j < oTruck.Crew.Count; j++)
                {
                    FireFighter oFireFighter = oTruck.Crew[j];
                    Trace.WriteLine(String.Format("{0}({1})\t @ {2} minutes as \t{3}", oFireFighter.ID, oFireFighter.Skills, oFireFighter.ETA, oFireFighter.Assigned));
                }

            }
            Trace.WriteLine(new String('#', 20));
            //list the team
            for (int i = 0; i < Team.Count; i++)
            {
                FireFighter oFireFighter = Team[i];
                Trace.WriteLine(String.Format("{0}({1})\t @ {2} minutes as \t{3}", oFireFighter.ID, oFireFighter.Skills, oFireFighter.ETA, oFireFighter.Assigned));
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26226923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档