C#分数背包o(n logn)解

Posted

技术标签:

【中文标题】C#分数背包o(n logn)解【英文标题】:C# Fractional knapsack o(n logn) solution 【发布时间】:2016-05-08 02:59:08 【问题描述】:

我正在计算分数背包。它适用于大多数情况,但不适用于某些极端情况。我实现的算法是标准算法。我在 get_optimal_value() 做一些愚蠢的事情,无法弄清楚。请帮忙!

using System;
using System.Collections.Generic;

namespace FractionalKnapsackcsharp

    public class Program
    
        public static void Main(string[] args)
        
            int n;
            int capacity;
            string n1 = Console.ReadLine();
            n = Convert.ToInt32(n1.Split(' ')[0]);
            capacity = Convert.ToInt32(n1.Split(' ')[1]);

            //read the array values
            string[] answer = new string[n];

            double[] values = new double[n];
            int[] weights = new int[n];
            for (int i = 0; i < answer.Length; i++)
            
                answer[i] = Console.ReadLine();
                values[i] = Convert.ToDouble(answer[i].Split(' ')[0]);
                weights[i] = Convert.ToInt32(answer[i].Split(' ')[1]);
            

            double value = get_optimal_value(n, capacity, weights, values);
            Console.WriteLine(Math.Round(value, 4));
        

        public static double get_optimal_value(int n, int capacity, int[] weights, double[] values)
        
            double value = 0.0;

          //There should be a better way to handle this scenario, any idea ?
            if (n == 1)
            
                int a = weights[0] < capacity ? weights[0] : capacity;
                value = value + a * values[0] / weights[0];
                return value;
            

            Array.Sort(weights, values, Comparer<int>.Create((x, y) => y.CompareTo(x)));

            double[] A = new double[n];
            for (int i = 1; i < n; i++)
            
                if (capacity == 0) return value;

                int a = weights[i] < capacity ? weights[i] : capacity;
                value = value + a * values[i] / weights[i];
                weights[i] = weights[i] - a;
                A[i] = A[i] + a;
                capacity = capacity - a;
            
            return value;
        
    

【问题讨论】:

不要在 1 开始最后一个 for 循环? 是的,这是问题的一部分。但实际的大问题是我错过了基于值/权重比的排序并相应地对权重数组进行排序/排列,这使其失败。谢谢! 【参考方案1】:

问题在于排序,这是可行的解决方案:

using System;
using System.Collections.Generic;

namespace FractionalKnapsackcsharp

    public class Program
    
        public static void Main(string[] args)
        
            int n = 0;
            double capacity;
            string n1 = Console.ReadLine();
            n = Convert.ToInt32(n1.Split(' ')[0]);
            capacity = Convert.ToDouble(n1.Split(' ')[1]);

            double[] values = new double[n];
            double[] weights = new double[n];
            for (int i = 0; i < n; i++)
            
                var answer = Console.ReadLine();
                values[i] = Convert.ToDouble(answer.Split(' ')[0]);
                weights[i] = Convert.ToDouble(answer.Split(' ')[1]);
            

            double value = get_optimal_value(n, capacity, values, weights);
            Console.WriteLine(Math.Round(value, 4));
        

        public static double get_optimal_value(int n, double capacity, double[] values, double[] weights)
        
            double value = 0.0;

            Array.Sort(values, weights, Comparer<double>.Create((x, y) => y.CompareTo(x)));

            double[] ratio = new double[n];

            for (int i = 0; i < n; ++i)
            
                ratio[i] = values[i] / weights[i];
            

            Array.Sort(ratio, weights, Comparer<double>.Create((x, y) => y.CompareTo(x)));
            //Array.Sort(ratio, weights, Comparer<double>.Create((x, y) => x.CompareTo(y)));

            //double[] A = new double[n];
            for (int i = 0; i < n; i++)
            
                if (capacity == 0) return value;

                double a = weights[i] < capacity ? weights[i] : capacity;
                //value = value + a * (values[i] / weights[i]);
                value = value + a * ratio[i];
                weights[i] = weights[i] - a;
                //A[i] = A[i] + a;
                capacity = capacity - a;
            
            return value;
        
    

【讨论】:

以上是关于C#分数背包o(n logn)解的主要内容,如果未能解决你的问题,请参考以下文章

1257 背包问题 V3——分数规划

[JSOI 2016] 最佳团体(树形背包+01分数规划)

用最高分做平衡括号

bzoj4753[Jsoi2016]最佳团体 分数规划+树形背包dp

[ARC123F]Insert Addition

03-14考试总结