Информация об изменениях

Сообщение Re[7]: [забыл математику] Оптимизация алгоритма от 16.09.2022 20:34

Изменено 17.09.2022 0:18 xma

Re[7]: [забыл математику] Оптимизация алгоритма
Здравствуйте, Xander Zerge, Вы писали:

XZ>Ты свой туда же подложи, и посмотрим, это код не работает, или ты просто эксплойтишь ограниченное количество знаков после точки в decimal.


я решил задачу (test_optimal2), теперь верно абсолютно всегда — даже когда test_optimal_Serge_Novikoff неверно ..

я красавчег

  source code
проверяй тут,
https://dotnetfiddle.net/

using System;
                    
public class Program
{
    // работоспособный минимум (на конкретных тестах) это (1 / Math.Pow(10, 24))
    public static decimal DecimalEpsilon = (decimal) (1 / Math.Pow(10, 6));
    
    public static void Main()
    {
        Console.WriteLine("Hello World");
        
        /*
        decimal marketBuyPrice = 736.72m, overwriteMinStep = 7.3671999999999999999999999999m;
        
        var ret = test_original(marketBuyPrice, overwriteMinStep);
        var ret_opt2 = test_optimal2(marketBuyPrice, overwriteMinStep);
        var ret_opt_Serge_Novikoff = test_optimal_Serge_Novikoff(marketBuyPrice, overwriteMinStep);
        
        Console.WriteLine("marketBuyPrice = " + marketBuyPrice + ", overwriteMinStep = " + overwriteMinStep);
        
        Console.WriteLine("ret_original = " + ret);
        Console.WriteLine("ret_opt2 = " + ret_opt2);
        Console.WriteLine("ret_opt_Serge_Novikoff = " + ret_opt_Serge_Novikoff);
        
        bool flag_test_optimal2 = Math.Abs(ret - ret_opt2) < DecimalEpsilon ;
        Console.WriteLine("flag_test_optimal2 = " + flag_test_optimal2);
        
        bool flag_test_Serge_Novikoff = Math.Abs(ret - ret_opt_Serge_Novikoff) < DecimalEpsilon ;
        Console.WriteLine("flag_test_Serge_Novikoff = " + flag_test_Serge_Novikoff);
        */
        
        ///*
        Random rand = new Random();
        
        bool flag_test_optimal2 = true;
        bool flag_test_Serge_Novikoff = true;
        
        for (int i=0; i<10000; i++) {
            
            decimal marketBuyPrice = rand.Next(0, 1000000) / 100.0m; 
            decimal overwriteMinStep = rand.Next(1, 10000000) / 100.0m; 
            
            if (marketBuyPrice / overwriteMinStep > 100)
                overwriteMinStep *= marketBuyPrice / (overwriteMinStep * 100.0m);
            
            var ret = test_original(marketBuyPrice, overwriteMinStep);
            var ret_opt2 = test_optimal2(marketBuyPrice, overwriteMinStep);
            
            var ret_opt_Serge_Novikoff = test_optimal_Serge_Novikoff(marketBuyPrice, overwriteMinStep);
            
            bool temp_flag_test_optimal2 = Math.Abs(ret - ret_opt2) < DecimalEpsilon;
            bool temp_flag_test_Serge_Novikoff = Math.Abs(ret - ret_opt_Serge_Novikoff) < DecimalEpsilon;
            
            if ( (false == temp_flag_test_optimal2) || (false == temp_flag_test_Serge_Novikoff) ) {
                
                flag_test_optimal2 &= temp_flag_test_optimal2 ;
                flag_test_Serge_Novikoff &= temp_flag_test_Serge_Novikoff ;
                
                Console.WriteLine("");
                Console.WriteLine("marketBuyPrice = " + marketBuyPrice + ", overwriteMinStep = " + overwriteMinStep);
                
                Console.WriteLine("ret_original = " + ret);
                Console.WriteLine("ret_opt2 = " + ret_opt2);
                
                Console.WriteLine("ret_opt_Serge_Novikoff = " + ret_opt_Serge_Novikoff);
            }
        }
        
        Console.WriteLine("");
        Console.WriteLine("flag_test_optimal2 = " + flag_test_optimal2);
        Console.WriteLine("flag_test_Serge_Novikoff = " + flag_test_Serge_Novikoff);
        //*/
    }
    
    public static decimal test_original(decimal marketBuyPrice, decimal overwriteMinStep)
    {        
        decimal mediumPrice2 = 0;

        do
        {
            mediumPrice2 += overwriteMinStep;
        } while (mediumPrice2 < marketBuyPrice);
        
        return mediumPrice2;
    }

    public static decimal test_optimal2(decimal marketBuyPrice, decimal overwriteMinStep)
    {        
        if (decimal.Zero == marketBuyPrice) // == 0
            return overwriteMinStep;

        decimal mediumPrice2 = (decimal.Floor(marketBuyPrice / overwriteMinStep) + 1) * overwriteMinStep;
        
        //if ( mediumPrice2 == marketBuyPrice + overwriteMinStep )
        //if ( Math.Abs(mediumPrice2 - (marketBuyPrice + overwriteMinStep)) <= 0.0001m )
        if ( Math.Abs(mediumPrice2 - (marketBuyPrice + overwriteMinStep)) < DecimalEpsilon )
            mediumPrice2 -= overwriteMinStep;
            
        return mediumPrice2;
    }
    
    public static decimal test_optimal_Serge_Novikoff(decimal marketBuyPrice, decimal minStep)
    {        
        //if (decimal.Zero == marketBuyPrice) // == 0
        //    return overwriteMinStep;
        
        var imin = (int)(marketBuyPrice / minStep);
        
        if (minStep * imin < marketBuyPrice)
            ++imin;

        decimal mediumPrice2 = minStep * imin;
            
        return mediumPrice2;
    }
}


проверял для overwriteMinStep > 0 и marketBuyPrice >= 0,

P.S.:

если опять возникнут какие либо проблемы, то регулируйте степень (Pow) десятки в DecimalEpsilon — с 6 до нужного большего числа .. (чтобы увеличить делитель единицы), работоспособный минимум на данных тестах 1/(10^24)
Re[7]: [забыл математику] Оптимизация алгоритма
Здравствуйте, Xander Zerge, Вы писали:

XZ>Ты свой туда же подложи, и посмотрим, это код не работает, или ты просто эксплойтишь ограниченное количество знаков после точки в decimal.


я решил задачу (test_optimal2), теперь верно абсолютно всегда — даже когда test_optimal_Serge_Novikoff неверно ..

я красавчег

  source code
проверяй тут,
https://dotnetfiddle.net/

using System;
                    
public class Program
{
    // работоспособный минимум (на конкретных тестах) это (1 / Math.Pow(10, 24))
    public static decimal DecimalEpsilon = (decimal) (1 / Math.Pow(10, 6));
    
    public static void Main()
    {
        Console.WriteLine("Hello World");
        
        /*
        decimal marketBuyPrice = 736.72m, overwriteMinStep = 7.3671999999999999999999999999m;
        
        var ret = test_original(marketBuyPrice, overwriteMinStep);
        var ret_opt2 = test_optimal2(marketBuyPrice, overwriteMinStep);
        var ret_opt_Serge_Novikoff = test_optimal_Serge_Novikoff(marketBuyPrice, overwriteMinStep);
        
        Console.WriteLine("marketBuyPrice = " + marketBuyPrice + ", overwriteMinStep = " + overwriteMinStep);
        
        Console.WriteLine("ret_original = " + ret);
        Console.WriteLine("ret_opt2 = " + ret_opt2);
        Console.WriteLine("ret_opt_Serge_Novikoff = " + ret_opt_Serge_Novikoff);
        
        bool flag_test_optimal2 = Math.Abs(ret - ret_opt2) < DecimalEpsilon ;
        Console.WriteLine("flag_test_optimal2 = " + flag_test_optimal2);
        
        bool flag_test_Serge_Novikoff = Math.Abs(ret - ret_opt_Serge_Novikoff) < DecimalEpsilon ;
        Console.WriteLine("flag_test_Serge_Novikoff = " + flag_test_Serge_Novikoff);
        */
        
        ///*
        Random rand = new Random();
        
        bool flag_test_optimal2 = true;
        bool flag_test_Serge_Novikoff = true;
        
        for (int i=0; i<10000; i++) {
            
            decimal marketBuyPrice = rand.Next(0, 1000000) / 100.0m; 
            decimal overwriteMinStep = rand.Next(1, 10000000) / 100.0m; 
            
            if (marketBuyPrice / overwriteMinStep > 100)
                overwriteMinStep *= marketBuyPrice / (overwriteMinStep * 100.0m);
            
            var ret = test_original(marketBuyPrice, overwriteMinStep);
            var ret_opt2 = test_optimal2(marketBuyPrice, overwriteMinStep);
            
            var ret_opt_Serge_Novikoff = test_optimal_Serge_Novikoff(marketBuyPrice, overwriteMinStep);
            
            bool temp_flag_test_optimal2 = Math.Abs(ret - ret_opt2) < DecimalEpsilon;
            bool temp_flag_test_Serge_Novikoff = Math.Abs(ret - ret_opt_Serge_Novikoff) < DecimalEpsilon;
            
            if ( (false == temp_flag_test_optimal2) || (false == temp_flag_test_Serge_Novikoff) ) {
                
                flag_test_optimal2 &= temp_flag_test_optimal2 ;
                flag_test_Serge_Novikoff &= temp_flag_test_Serge_Novikoff ;
                
                Console.WriteLine("");
                Console.WriteLine("marketBuyPrice = " + marketBuyPrice + ", overwriteMinStep = " + overwriteMinStep);
                
                Console.WriteLine("ret_original = " + ret);
                Console.WriteLine("ret_opt2 = " + ret_opt2);
                
                Console.WriteLine("ret_opt_Serge_Novikoff = " + ret_opt_Serge_Novikoff);
            }
        }
        
        Console.WriteLine("");
        Console.WriteLine("flag_test_optimal2 = " + flag_test_optimal2);
        Console.WriteLine("flag_test_Serge_Novikoff = " + flag_test_Serge_Novikoff);
        //*/
    }
    
    public static decimal test_original(decimal marketBuyPrice, decimal overwriteMinStep)
    {        
        decimal mediumPrice2 = 0;

        do
        {
            mediumPrice2 += overwriteMinStep;
        } while (mediumPrice2 < marketBuyPrice);
        
        return mediumPrice2;
    }

    public static decimal test_optimal2(decimal marketBuyPrice, decimal overwriteMinStep)
    {        
        if (decimal.Zero == marketBuyPrice) // == 0
            return overwriteMinStep;

        decimal mediumPrice2 = (decimal.Floor(marketBuyPrice / overwriteMinStep) + 1) * overwriteMinStep;
        
        //if ( mediumPrice2 == marketBuyPrice + overwriteMinStep )
        //if ( Math.Abs(mediumPrice2 - (marketBuyPrice + overwriteMinStep)) <= 0.0001m )
        if ( Math.Abs(mediumPrice2 - (marketBuyPrice + overwriteMinStep)) < DecimalEpsilon )
            mediumPrice2 -= overwriteMinStep;
            
        return mediumPrice2;
    }
    
    public static decimal test_optimal_Serge_Novikoff(decimal marketBuyPrice, decimal minStep)
    {        
        //if (decimal.Zero == marketBuyPrice) // == 0
        //    return minStep;
        
        var imin = (int)(marketBuyPrice / minStep);
        
        if (minStep * imin < marketBuyPrice)
            ++imin;

        decimal mediumPrice2 = minStep * imin;
            
        return mediumPrice2;
    }
}


проверял для overwriteMinStep > 0 и marketBuyPrice >= 0,

P.S.:

если опять возникнут какие либо проблемы, то регулируйте степень (Pow) десятки в DecimalEpsilon — с 6 до нужного большего числа .. (чтобы увеличить делитель единицы), работоспособный минимум на данных тестах 1/(10^24)