zoukankan      html  css  js  c++  java
  • 没有方法的算法代码

      8月分都过半了,最近两个月对代码的激情是越来越少.一方面是由于自己本来忙装修的事情,更主要的原因是我发现自己对代码越来越冷淡了,没有什么感觉了.而且新东些更新太快,我工作几年了没有在工作中使用过ef,mvc这些东西,刚出来的时候主要是webform,后面就是现在,主要也是一些C#的基本语法算法,然后就是sqlserver数据库,现在还觉得在自己身上的就是一些语法,算法,数据库方面的一些东西了,感觉没有什么大的进步.前段时间对项目管理热了一段时间,不过最近还是慢慢的退烧了,反而对其它的兴趣爱好这些用的时候更多.为毛呢?为毛呢?

      对于算法的热情我认为还是没有减少,每次看到一算法题目,或者有人问到的算法问题,只要时间充足还是会想办法练练手的.今天写了一段简单的算法代码,先把问题列出来.大致是这样的

      枪上有三种值,初始值,X2操作 /2操作(我觉得这个操作可以不要,看了后面就知道了),然后敌人数量N,每个敌人要被消灭所需要的能量余额必须是Xi,这里有点复杂,等会看例子.现在N在[0,10000],Xi[0,10000],后面发贴楼主把范围改大到1000000了.问题:要求设置一个初始值,使得消灭敌人所需的能量最小.看下面例子

      1.比如有两个敌人N=2,余值X1=3,X2=5,解:初始值设置3,那么对第一个敌人用0点能量,然后按X2操作,对第二个敌人就用1点能量.每次打完一个敌人,能量都会变为初始值.最后所消耗1点的能量
      2.N=3,X1=1,X2=3,X3=4,那么初始值为1,消耗分别为0,1,0,总的消耗为1.

      如上面所列出就是要求初始值和总消耗能量.

      目前为至,我没有想到有求最优解的算法.只是一个穷举的方式,一些回复说动态规划等,我完全没有看出这里面可以使用动态规划,动态规划始终要能确定一个公式,一个明确的求最优解的方式才行.其实可以想像就是初始值的不同,引起与敌人余值的差不同,如下图,就是找出这些差当中和最小的

      如图这个就像我们微调以前的电视一样,就像实验证里面什么波仪器调节一样,只是通过调节来找出最优的情况,所以我感觉没有合适的算法来解决,所以写了一个大概还算可以的代码来解决.主要优化到的地方是从余值列表中选择最小的和最大的,在这个范围内来找初始值,下面一坨代码.

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Diagnostics;
      4 using System.IO;
      5 using System.Linq;
      6 using System.Runtime.Serialization;
      7 using System.Runtime.Serialization.Formatters.Binary;
      8 using System.Text;
      9 using System.Threading;
     10 using System.Threading.Tasks;
     11 
     12 namespace ConsoleApplication1
     13 {
     14     class Program
     15     {
     16 
     17 
     18         static void Main(string[] args)
     19         {
     20             A a = new A();
     21             a.Init(10000, 100000);
     22             a.Show();
     23 
     24             Console.WriteLine("k");
     25             Stopwatch sw = new Stopwatch();
     26             sw.Start();
     27             a.Calc();
     28             sw.Stop();
     29 
     30             Console.WriteLine("初始值:{0},总消耗值:{1},耗时:{2}", a.InitValue, a.Total,sw.Elapsed);
     31 
     32             Console.ReadLine();
     33         }
     34 
     35 
     36     }
     37 
     38     public class A
     39     {
     40         public List<int> List = new List<int>();
     41 
     42         public void Init(int n, int max)
     43         {
     44             Random ran = new Random();
     45             while (n > 0)
     46             {
     47                 //生成max以内的整数
     48                 List.Add(ran.Next(max)+1);
     49                 n--;
     50             }
     51         }
     52 
     53         public void Show() {
     54             foreach (int a in List) {
     55                 Console.Write("	 {0}", a);
     56             }
     57             Console.WriteLine();
     58         }
     59 
     60 
     61         public int InitValue = 0;
     62         public int Total = 0;
     63         private List<int> sums = new List<int>();
     64 
     65         public void Calc()
     66         {
     67             //1.找出最小值和最大值 O(n)
     68             int min = List[0];
     69             int max = List[0];
     70             foreach (var a in List)
     71             {
     72                 if (a < min) min = a;
     73                 if (a > max) max = a;
     74             }
     75 
     76             //2.从最小值开始 依次计算出每个数的结果和O(n^3)
     77             for (int i = min; i <= max; i++)
     78             {
     79                 InitValue = i;
     80                 int sum = 0;
     81                 foreach (int a in List)
     82                 {
     83                     sum += FindCeil(a, i)-a;
     84                 }
     85                 sums.Add(sum);
     86             }
     87 
     88             //3.找出最小的O(n)
     89             int minsum = sums[0];
     90             int mini = 0;
     91             for (int i = 0; i < sums.Count; i++)
     92             {
     93                 if (sums[i] < minsum)
     94                 {
     95                     minsum = sums[i];
     96                     mini = i;
     97                 }
     98             }
     99 
    100             InitValue = min + mini;
    101             Total = sums[mini];
    102         }
    103 
    104         //找出初始值为initValue对于num的最近的一个Ceil值
    105         private int FindCeil(int num, int initValue)
    106         {
    107             int v = 0;
    108             for (int i = 0; i < num; i++)
    109             {
    110                 v = initValue * Pow2(i);
    111                 if (v >= num)
    112                 {
    113                     return v;
    114                 }
    115             }
    116             return 0;
    117         }
    118 
    119         //2的n次方
    120         private int Pow2(int y)
    121         {
    122             int a = 1;
    123             if (y == 0) return 1;
    124             else return a << y;
    125         }
    126     }
    127 
    128 }
    View Code

      最后总结一下,算法没有什么总结的,可能在FindCeil这个方法中还有优化的空间. 还有就是从最小值到最大值,是不是还有优化的空间,就是可以不一直找到最大值,找到中间一个值就可以停了,那这里可能就要好一些.


    修正错误 ,代码里面我就不去改了,不应该以min~max范围内找初始值,应该以1~max范围找初始值.

  • 相关阅读:
    JS基础语法
    JS的初步了解
    CSS初步学习
    HTML标签
    初步了解HTML
    LEGB规则
    Python面试题练习
    闭包
    Caché,Cache数据库连接并查询数据
    Caché,Cache数据库下载
  • 原文地址:https://www.cnblogs.com/gw2010/p/3912164.html
Copyright © 2011-2022 走看看