首页 > 编程语言 >C# 卡车装车示例

C# 卡车装车示例

时间:2023-04-28 09:03:58浏览次数:36  
标签:cargo float return 示例 C# 装车 List 摆放 货物

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TruckLoader : MonoBehaviour
{
    // 货物信息结构体
    public struct CargoInfo
    {
        public float length;   // 长度
        public float width;    // 宽度
        public float height;   // 高度
        public float weight;   // 重量
        public Vector3 position;  // 位置
        public Quaternion rotation;   // 旋转方向
        public CargoState state;   // 状态
    }

    // 货物状态枚举类型
    public enum CargoState
    {
        NotPlaced,  // 未摆放
        Placed,     // 已摆放
        CannotBePlaced  // 无法摆放
    }

    // 数学模型算法枚举类型
    public enum Algorithm
    {
        Greedy,     // 贪心算法
        Evolutionary    // 进化算法
    }

    // 卡车最大载重和总体积限制
    public float maxTotalWeight = 10000.0f;
    public float maxTotalVolume = 100.0f;

    // 当前使用的数学模型算法
    private Algorithm currentAlgorithm = Algorithm.Greedy;

    // 开始装车
    public void StartLoadingTruck()
    {
        // 选择一个数学模型算法
        currentAlgorithm = Algorithm.Greedy;

        // 获取所有货物的信息
        List<CargoInfo> cargoList = GetCargoList();

        // 计算所有货物的重心
        Vector3 centerOfMass = CalculateCenterOfMass(cargoList);

        // 设置货物的起始位置和旋转方向
        foreach (CargoInfo cargo in cargoList)
        {
            cargo.position = centerOfMass + new Vector3(0, cargo.height / 2.0f, 0);
            cargo.rotation = Quaternion.identity;
            cargo.state = CargoState.NotPlaced;
        }

        // 生成所有摆放方案
        List<List<CargoInfo>> allLayouts = GenerateAllLayouts(cargoList);

        // 找到符合要求的最优摆放方案
        List<CargoInfo> bestLayout = FindBestLayout(allLayouts);

        // 将货物摆放到卡车上
        PlaceCargoToTruck(bestLayout);
    }

    // 生成所有货物的摆放方案
    List<List<CargoInfo>> GenerateAllLayouts(List<CargoInfo> cargoList)
    {
        // 创建一个空的方案列表
        List<List<CargoInfo>> allLayouts = new List<List<CargoInfo>>();

        // 递归生成所有可能的摆放方案
        GenerateAllLayouts(cargoList, new List<CargoInfo>(), allLayouts);

        return allLayouts;
    }

    // 递归生成所有可能的摆放方案
    void GenerateAllLayouts(List<CargoInfo> cargoList, List<CargoInfo> currentLayout, List<List<CargoInfo>> allLayouts)
    {
        // 判断是否已经完成了一个方案的生成
        if (cargoList.Count == 0)
        {
            // 将当前方案添加到列表中
            allLayouts.Add(new List<CargoInfo>(currentLayout));
            return;
        }

        // 获取第一个货物
        CargoInfo cargo = cargoList[0];
        cargoList.RemoveAt(0);

        // 尝试将货物摆放到当前方案中的所有位置和旋转方向
        for (int i = 0; i < 4; i++)
        {
            cargo.rotation = Quaternion.Euler(0, i * 90, 0);

            for (float x = 0; x <= transform.localScale.x - cargo.length; x += 0.1f)
            {
                for (float y = 0; y <= transform.localScale.y - cargo.height; y += 0.1f)
                {
                    for (float z = 0; z <= transform.localScale.z - cargo.width; z += 0.1f)
                    {
                        cargo.position = new Vector3(x, y, z);
                            cargo.state = CargoState.Placed;

                            if (IsColliding(cargo, currentLayout))
                            {
                                cargo.state = CargoState.CannotBePlaced;
                                continue;
                            }

                            if (!IsWithinLimitations(cargo, currentLayout))
                            {
                                cargo.state = CargoState.CannotBePlaced;
                                continue;
                            }

                            // 将货物添加到当前方案中
                            currentLayout.Add(cargo);

                            // 递归生成下一个货物的摆放方案
                            GenerateAllLayouts(cargoList, currentLayout, allLayouts);

                            // 移除当前方案中的货物
                            RemoveCargoFromLayout(cargo, currentLayout);
                        }
                    }
                }
            }
        }

        // 将第一个货物重新加入到列表中
        cargoList.Insert(0, cargo);
    }

    // 判断两个货物是否有碰撞
    bool IsColliding(CargoInfo cargo1, List<CargoInfo> currentLayout)
    {
        foreach (CargoInfo cargo2 in currentLayout)
        {
            Bounds bounds1 = new Bounds(cargo1.position + new Vector3(cargo1.length / 2.0f, cargo1.height / 2.0f, cargo1.width / 2.0f),
                                        new Vector3(cargo1.length, cargo1.height, cargo1.width));
            Bounds bounds2 = new Bounds(cargo2.position + new Vector3(cargo2.length / 2.0f, cargo2.height / 2.0f, cargo2.width / 2.0f),
                                        new Vector3(cargo2.length, cargo2.height, cargo2.width));

            if (bounds1.Intersects(bounds2))
            {
                return true;
            }
        }

        return false;
    }

    // 判断货物是否符合限制条件
    bool IsWithinLimitations(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        float totalWeight = 0.0f;
        float totalVolume = 0.0f;

        foreach (CargoInfo otherCargo in currentLayout)
        {
            totalWeight += otherCargo.weight;
            totalVolume += otherCargo.length * otherCargo.width * otherCargo.height;
        }

        if (totalWeight + cargo.weight > maxTotalWeight || totalVolume + cargo.length * cargo.width * cargo.height > maxTotalVolume)
        {
            return false;
        }

        return true;
    }

    // 移除当前方案中的货物
    void RemoveCargoFromLayout(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        currentLayout.Remove(cargo);
        cargo.state = CargoState.NotPlaced;
    }

    // 找到符合要求的最优摆放方案
    List<CargoInfo> FindBestLayout(List<List<CargoInfo>> allLayouts)
    {
        switch (currentAlgorithm)
        {
            case Algorithm.Greedy:
            default:
                return FindBestGreedyLayout(allLayouts);

            case Algorithm.Evolutionary:
                // TODO: 实现进化算法查找最优摆放方案的功能
                return new List<CargoInfo>();
        }
    }

    // 使用贪心算法查找最优摆放方案
    List<CargoInfo> FindBestGreedyLayout(List<List<CargoInfo>> allLayouts)
    {
        List<CargoInfo> bestLayout = null;
        float bestScore = float.MinValue;

        foreach (List<CargoInfo> layout in allLayouts)
        {
            // 计算货物的最大高度
            float maxHeight = CalculateMaxHeight(layout);

            // 计算摆放方案的得分
            float score = CalculateScore(layout, maxHeight);

            // 更新最优摆放方案
            if (score > bestScore)
            {
                bestScore = score;
                bestLayout = layout;
            }
        }

        return bestLayout;
    }

    // 计算货物的最大高度
    float CalculateMaxHeight(List<CargoInfo> cargoList)
    {
        float maxHeight = 0.0f;

        foreach (CargoInfo cargo in cargoList)
        {
            float height = cargo.position.y + cargo.height / 2.0f;

            if (height > maxHeight)
            {
                maxHeight = height;
            }
        }

        return maxHeight;
    }

    // 计算摆放方案的得分
    float CalculateScore(List<CargoInfo> cargoList, float maxHeight)
    {
        float totalWeight = 0.0f;
        float totalVolume = 0.0f;

        foreach (CargoInfo cargo in cargoList)
        {
            totalWeight += cargo.weight;
            totalVolume += cargo.length * cargo.width * cargo.height;
        }

        // 根据总体积和最大高度计算得分
        float score = totalVolume / maxHeight;

        return score;
    }

    // 将货物摆放到卡车上
    void PlaceCargoToTruck(List<CargoInfo> cargoList)
    {
        foreach (CargoInfo cargo in cargoList)
        {
            if (cargo.state != CargoState.Placed)
            {
                continue;
            }

            GameObject cargoObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
            cargoObject.transform.localScale = new Vector3(cargo.length, cargo.height, cargo.width);
            cargoObject.transform.position = cargo.position;
            cargoObject.transform.rotation = cargo.rotation;

            // TODO: 添加更多的货物信息,例如颜色、纹理等

            cargoObject.transform.parent = transform;
        }
    }

    // 获取所有货物的信息
    List<CargoInfo> GetCargoList()
    {
        List<CargoInfo> cargoList = new List<CargoInfo>();

        // TODO: 获取货物列表并设置货物的长、宽、高、重量等参数

        return cargoList;
    }

    // 计算所有货物的重心
    Vector3 CalculateCenterOfMass(List<CargoInfo> cargoList)
    {
        Vector3 centerOfMass = Vector3.zero;
        float totalWeight = 0.0f;

        foreach (CargoInfo cargo in cargoList)
        {
            centerOfMass += cargo.weight * (cargo.position + new Vector3(0, cargo.height / 2.0f, 0));
            totalWeight += cargo.weight;
        }

        centerOfMass /= totalWeight;

        return centerOfMass;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TruckLoader : MonoBehaviour
{
    // 货物信息参数
    public float cargoLength;
    public float cargoWidth;
    public float cargoHeight;
    public float cargoWeight;

    // 限制规则参数
    public float maxTotalWeight;
    public float maxTotalVolume;

    // 数学模型算法选择
    public enum AlgorithmType
    {
        BruteForce,
        GreedyAlgorithm,
        DynamicProgramming,
        GeneticAlgorithm
    }
    public AlgorithmType algorithmType;

    // 摆放方案导出
    public void ExportLayout()
    {
        // TODO: 实现导出摆放方案的功能
    }

    // 货物摆放到卡车上
    public void LoadCargoToTruck()
    {
        // 根据用户选择的算法类型,选择相应的算法进行货物摆放
        switch (algorithmType)
        {
            case AlgorithmType.BruteForce:
                BruteForceAlgorithm();
                break;
            case AlgorithmType.GreedyAlgorithm:
                GreedyAlgorithm();
                break;
            case AlgorithmType.DynamicProgramming:
                DynamicProgrammingAlgorithm();
                break;
            case AlgorithmType.GeneticAlgorithm:
                GeneticAlgorithm();
                break;
            default:
                break;
        }
    }

    // 枚举类型,表示货物的状态
    enum CargoState
    {
        NotPlaced,      // 没有摆放
        Placed,         // 已经摆放
        CannotBePlaced  // 无法摆放
    }

    // 定义货物信息结构体
    struct CargoInfo
    {
        public float length;
        public float width;
        public float height;
        public float weight;

        public Vector3 position;        // 货物位置
        public Quaternion rotation;     // 货物旋转方向
        public CargoState state;        // 货物状态
    }

    // 使用Brute Force算法进行货物摆放
    void BruteForceAlgorithm()
    {
        // 获取所有货物的信息
        List<CargoInfo> cargoList = GetCargoList();

        // 所有可能的货物摆放情况列表
        List<List<CargoInfo>> allLayouts = new List<List<CargoInfo>>();

        // 遍历所有可能的货物排列组合
        GenerateAllLayouts(cargoList, new List<CargoInfo>(), allLayouts);

        // 找到符合要求的最优摆放方案
        List<CargoInfo> bestLayout = FindBestLayout(allLayouts);

        // 将最优方案的货物摆放到卡车上
        PlaceCargoToTruck(bestLayout);
    }

    // 生成所有可能的货物排列组合
    void GenerateAllLayouts(List<CargoInfo> cargoList, List<CargoInfo> currentLayout, List<List<CargoInfo>> allLayouts)
    {
        // 如果有货物无法摆放,直接返回
        if (cargoList.Exists(c => c.state == CargoState.CannotBePlaced))
        {
            return;
        }

        // 如果当前方案已经包含所有货物,将其添加到所有方案列表中
        if (currentLayout.Count == cargoList.Count)
        {
            allLayouts.Add(currentLayout);
            return;
        }

        // 遍历所有未摆放的货物,尝试在不冲突的情况下进行摆放
        foreach (CargoInfo cargo in cargoList)
        {
            if (cargo.state != CargoState.NotPlaced)
            {
                continue;
            }
            // 摆放货物
            if (TryPlaceCargo(cargo, currentLayout))
            {
                // 递归生成下一个方案
                GenerateAllLayouts(cargoList, currentLayout, allLayouts);

                // 恢复货物状态,继续尝试其他摆放方式
                RemoveCargoFromLayout(cargo, currentLayout);
            }
        }
    }

    // 尝试将货物摆放到当前方案中
    bool TryPlaceCargo(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        // 判断货物是否可以放置在当前摆放方案中
        bool canBePlaced = CanCargoBePlaced(cargo, currentLayout);

        if (canBePlaced)
        {
            // 更新货物信息
            cargo.state = CargoState.Placed;
            cargo.position = CalculateCargoPosition(cargo, currentLayout);
            cargo.rotation = CalculateCargoRotation(cargo, currentLayout);

            // 将货物添加到当前方案中
            currentLayout.Add(cargo);
        }
        else
        {
            // 标记货物为无法摆放
            cargo.state = CargoState.CannotBePlaced;
        }

        return canBePlaced;
    }

    // 判断货物是否可以放置在当前摆放方案中
    bool CanCargoBePlaced(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        // 判断货物是否超出卡车范围
        if (!IsInsideTruck(cargo, currentLayout))
        {
            return false;
        }

        // 判断货物是否与已经摆放的货物有碰撞
        if (IsCollidingWithOtherCargo(cargo, currentLayout))
        {
            return false;
        }

        // 判断货物是否超重或超体积
        if (!IsWithinLimitations(cargo, currentLayout))
        {
            return false;
        }

        return true;
    }

    // 判断货物是否在卡车范围内
    bool IsInsideTruck(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        // 计算货物摆放后的位置
        Vector3 position = CalculateCargoPosition(cargo, currentLayout);

        // 判断货物是否超出卡车范围
        if (position.x < 0 || position.x + cargo.length > transform.localScale.x ||
            position.y < 0 || position.y + cargo.height > transform.localScale.y ||
            position.z < 0 || position.z + cargo.width > transform.localScale.z)
        {
            return false;
        }

        return true;
    }

    // 判断货物是否与已经摆放的货物有碰撞
    bool IsCollidingWithOtherCargo(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        foreach (CargoInfo otherCargo in currentLayout)
        {
            if (otherCargo.state == CargoState.P
            {
                // 判断货物是否与其他货物有碰撞
                if (IsColliding(cargo, otherCargo))
                {
                    return true;
                }
            }

        }

        return false;
    }

    // 判断货物是否超重或超体积
    bool IsWithinLimitations(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        // 计算当前方案中所有货物的重量和体积
        float totalWeight = 0.0f;
        float totalVolume = 0.0f;

        foreach (CargoInfo otherCargo in currentLayout)
        {
            totalWeight += otherCargo.weight;
            totalVolume += otherCargo.length * otherCargo.width * otherCargo.height;
        }

        // 判断是否超重或超体积
        if (totalWeight + cargo.weight > maxTotalWeight || totalVolume + cargo.length * cargo.width * cargo.height > maxTotalVolume)
        {
            return false;
        }

        return true;
    }

    // 计算货物摆放位置
    Vector3 CalculateCargoPosition(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        // 将货物放置在卡车上方
        float height = 0.0f;

        foreach (CargoInfo otherCargo in currentLayout)
        {
            height += otherCargo.height;
        }

        return new Vector3(Random.Range(0.0f, transform.localScale.x - cargo.length),
                           height,
                           Random.Range(0.0f, transform.localScale.z - cargo.width));
    }

    // 计算货物旋转方向
    Quaternion CalculateCargoRotation(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        // 随机旋转货物
        return Quaternion.Euler(0, Random.Range(0, 4) * 90, 0);
    }

    // 判断两个货物是否有碰撞
    bool IsColliding(CargoInfo cargo1, CargoInfo cargo2)
    {
        // 计算两个货物的包围盒
        Bounds bounds1 = new Bounds(cargo1.position + new Vector3(cargo1.length / 2.0f, cargo1.height / 2.0f, cargo1.width / 2.0f), 
                                    new Vector3(cargo1.length, cargo1.height, cargo1.width));
        Bounds bounds2 = new Bounds(cargo2.position + new Vector3(cargo2.length / 2.0f, cargo2.height / 2.0f, cargo2.width / 2.0f), 
                                    new Vector3(cargo2.length, cargo2.height, cargo2.width));

        // 判断两个包围盒是否有交叉部分
        if (bounds1.Intersects(bounds2))
        {
            return true;
        }

        return false;
    }

    // 移除当前方案中的货物
    void RemoveCargoFromLayout(CargoInfo cargo, List<CargoInfo> currentLayout)
    {
        currentLayout.Remove(cargo);
        cargo.state = CargoState.NotPlaced;
    }

    // 找到符合要求的最优摆放方案
    List<CargoInfo> FindBestLayout(List<List<CargoInfo>> allLayouts)
    {
        // TODO: 实现查找符合要求的最优摆放方案的功能

        // 默认返回所有方案中的第一个方案
        return allLayouts[0];
    }

    // 将货物摆放到卡车上
    void PlaceCargoToTruck(List<CargoInfo> cargoList)
    {
        foreach (CargoInfo cargo in cargoList)
        {
            if (cargo.state == CargoState.Placed)
            {
                GameObject cargoObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
                cargoObject.transform.localScale = new Vector3(cargo.length, cargo.height, cargo.width);
                cargoObject.transform.position = cargo.position;
                cargoObject.transform.rotation = cargo.rotation;

                cargoObject.GetComponent<Renderer>().material.color = Random.ColorHSV();

                cargoObject.transform.SetParent(transform);
            }
        }
    }

    // 获取所有货物的信息
    List<CargoInfo> GetCargoList()
    {
        // TODO: 实现获取所有货物的信息的功能

        // 返回一个空的货物列表
        return new List<CargoInfo>();
    }

    // 使用Greedy Algorithm算法进行货物摆放
    void GreedyAlgorithm()
    {
        // 选择一个数学模型算法
        currentAlgorithm = Algorithm.Greedy;

        // 获取所有货物的信息
        List<CargoInfo> cargoList = GetCargoList();

        // 计算所有货物的重心
        Vector3 centerOfMass = CalculateCenterOfMass(cargoList);

        // 设置货物的起始位置和旋转方向
        foreach (CargoInfo cargo in cargoList)
        {
            cargo.position = centerOfMass + new Vector3(0, cargo.height / 2.0f, 0);
            cargo.rotation = Quaternion.identity;
            cargo.state = CargoState.NotPlaced;
        }

        // 生成所有摆放方案
        List<List<CargoInfo>> allLayouts = GenerateAllLayouts(cargoList);

        // 找到符合要求的最优摆放方案
        List<CargoInfo> bestLayout = FindBestLayout(allLayouts);

        // 将货物摆放到卡车上
        PlaceCargoToTruck(bestLayout);
    }

    // 计算所有货物的重心
    Vector3 CalculateCenterOfMass(List<CargoInfo> cargoList)
    {
        Vector3 centerOfMass = Vector3.zero;
        float totalWeight = 0.0f;

        foreach (CargoInfo cargo in cargoList)
        {
            centerOfMass += cargo.weight * (cargo.position + new Vector3(0, cargo.height / 2.0f, 0));
            totalWeight += cargo.weight;
        }

        centerOfMass /= totalWeight;

        return centerOfMass;
    }
}
// 贪心数学模型算法
public class GreedyModel {
    // 按照体积从大到小排序,优先选择放置体积较大的货物
    public static List<Goods> SortByVolume(List<Goods> goodsList) {
        return goodsList.OrderByDescending(goods => goods.Length * goods.Width * goods.Height).ToList();
    }

    // 按照重量从大到小排序,优先选择放置重量较大的货物
    public static List<Goods> SortByWeight(List<Goods> goodsList) {
        return goodsList.OrderByDescending(goods => goods.Weight).ToList();
    }
}

 

标签:cargo,float,return,示例,C#,装车,List,摆放,货物
From: https://www.cnblogs.com/guangzhiruijie/p/17360862.html

相关文章

  • 《Effective C#》系列之(零)——概要
    把全书的内容讲述完整可能需要很长时间,我可以先回答主要目录和核心的内容。如果您有任何特定问题或需要更详细的解释,请告诉我。《EffectiveC#》一书共包含50条C#编程建议,以下是其中的一些主要目录:1.理解C#的基础知识2.使代码更易于阅读和理解3.利用C#语言的新功能4.改进异......
  • 三菱Q02CPU 之 通信协议配置
     Work2编程软件中配置:线序参考手册 ......
  • 论文阅读笔记《Stochastic Grounded Action Transformation for Robot Learning in Si
    StochasticGroundedActionTransformationforRobotLearninginSimulation发表于IROS2020(CCFC)模拟中机器人学习的随机接地动作转换DesaiS,KarnanH,HannaJP,etal.Stochasticgroundedactiontransformationforrobotlearninginsimulation[C]//2020IEEE......
  • 学习C#编程经典书籍
    1.《C#语言程序设计》(第4版):由微软公司的C#语言团队编写,是学习C#语言的必备经典著作。2.《C#高级编程》(第9版):由AndrewTroelsen编写,涵盖了C#语言的高级特性和最佳实践。3.《CLRviaC#》(第4版):由JeffreyRichter编写,深入讲解了C#语言和CLR(公共语言运行时)之间的关系,是学习C#底层知......
  • Halcon Variation_model 详解
    介绍使用Halcon的差异模型进行检测,主要分为下面的四个步骤:create_shape_model创建检测的区域匹配模板注:这里使用形状匹配模板,当然也可以通过其它的匹配算法实现create_variation_model创建差异模型rain_variation_model训练正常图像prepare_variation_model......
  • C# 卡车装车示例(二)
    1.创建一个货物类,包含长、宽、高、重量、颜色、标签等属性,并定义一个列表用于存储所有货物对象。publicclassCargo{publicfloatlength;publicfloatwidth;publicfloatheight;publicfloatweight;publicColorcolor;publicstringlabel......
  • 论文阅读笔记《Residual Physics Learning and System Identification for Sim to rea
    ResidualPhysicsLearningandSystemIdentificationforSimtorealTransferofPoliciesonBuoyancyAssistedLeggedRobots发表于2023年。论文较新,未找到发表期刊。基于浮力辅助的足式机器人策略迁移的残差物理学习与系统识别SontakkeN,ChaeH,LeeS,etal.Resi......
  • NC25879 外挂
    题目链接题目题目描述我的就是我的,你也是我的,记住了,狐狸!​——韩信-白龙吟对于打赌输了的小T会遭受到制裁,小s修改了数据库使他可以派出许多军队来围攻小T.很不幸,小T与小s打赌打输了,现在小T遭受着枪林弹雨与十面埋伏,因为小T是神所以他......
  • 8. SELECT
    一.LIMIT和ORDERBY[root@mysql.sock][employees]>select*fromemployeeslimit1;--从employees中随机取出一条数据,结果是不确定的+--------+------------+------------+-----------+--------+------------+|emp_no|birth_date|first_name|last_name|gender|......
  • 彻底明白Zigbee术语——群集(Cluster)、端点(EndPoint)等
      在学习zigbee协议栈的时候经常看到应用程序、zigbee设备对象(ZDO)、节点、设备、端点、群集、属性、绑定、寻址等一下zigbee术语,不知道这些zigbee术语是表示什么,是如何定义的,是如何区分的,是如何划分的以及他们之间有什么联系,一切的一切全不知道。网上也有很多zigbee术......