From 8f6d2b48f22b695574bd4a6c4ac91b1ac9f780b1 Mon Sep 17 00:00:00 2001
From: ningshuxia <ningshuxia0927@outlook.com>
Date: 星期一, 06 五月 2024 17:28:35 +0800
Subject: [PATCH] 调度算法 大致完成

---
 Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs            |    3 
 Schedule/IStation.Client/Form1.cs                                |  111 ++
 Schedule/IStation.Algorithm/Schedule/SchedulingHelper - 复制(6).cs |  380 +++++++++
 Schedule/IStation.Client/Form1.Designer.cs                       |  165 +++-
 Schedule/IStation.Algorithm/DAL/ScheduleConclusion_bak.cs        |  272 ++++++
 Schedule/IStation.Algorithm/Helper/StringListHelper.cs           |   46 +
 Schedule/IStation.Algorithm/DAL/ScheduleCombine.cs               |   92 --
 Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs      |    2 
 /dev/null                                                        |   13 
 Schedule/IStation.Algorithm/DAL/DbInitial.cs                     |    2 
 Schedule/IStation.Algorithm/Schedule/SchedulingHelper - 复制(7).cs |  512 +++++++++++++
 Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs         |  268 +++++-
 Schedule/IStation.Algorithm/DAL/ScheduleCombine_bak.cs           |  241 ++++++
 Schedule/IStation.Algorithm/Expand/ListExpand.cs                 |  107 ++
 Schedule/IStation.Algorithm/IStation.Algorithm.csproj            |    2 
 Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs            |  123 ---
 16 files changed, 1,978 insertions(+), 361 deletions(-)

diff --git a/Schedule/IStation.Algorithm/DAL/DbInitial.cs b/Schedule/IStation.Algorithm/DAL/DbInitial.cs
index 2edf4a8..80f7d98 100644
--- a/Schedule/IStation.Algorithm/DAL/DbInitial.cs
+++ b/Schedule/IStation.Algorithm/DAL/DbInitial.cs
@@ -16,7 +16,7 @@
                 return false;
 
             Type[] types = new Type[] {
-                      // typeof(Entity.ScheduleCombine),
+                   //    typeof(Entity.ScheduleCombine),
                     //   typeof(Entity.ScheduleCombineLog),
                        typeof(Entity.ScheduleAnaLog),
 
diff --git a/Schedule/IStation.Algorithm/DAL/ScheduleCombine.cs b/Schedule/IStation.Algorithm/DAL/ScheduleCombine.cs
index eb57faa..1517966 100644
--- a/Schedule/IStation.Algorithm/DAL/ScheduleCombine.cs
+++ b/Schedule/IStation.Algorithm/DAL/ScheduleCombine.cs
@@ -20,6 +20,8 @@
             return $"{_tableNamePrefix}{runFlag}";
         }
 
+        private readonly string _createTable = "(\r\n    ID        BIGINT        NOT NULL\r\n                            PRIMARY KEY,\r\n    RunFlag   VARCHAR (255),\r\n    RunCount  INTEGER,\r\n    Pump1     REAL,\r\n    Pump2     REAL,\r\n    Pump3     REAL,\r\n    CurveQH   VARCHAR (255),\r\n    CurveQP   VARCHAR (255),\r\n    MaxFlow   REAL,\r\n    MinFlow   REAL,\r\n    MaxHead   REAL,\r\n    MinHead   REAL,\r\n    AnaStatus BIT\r\n);";
+
         /// <summary>
         /// 鑾峰彇鍏ㄩ儴琛ㄥ悕
         /// </summary>
@@ -60,52 +62,6 @@
         }
 
 
-        /// <summary>
-        /// 澶ф壒閲忔彃鍏�
-        /// </summary>
-        public bool BulkInserts_SplitTable(List<Entity.ScheduleCombine> list)
-        {
-            if (list == null || list.Count < 1)
-                return default;
-            using (SqlSugarClient db = Connection)
-            {
-                ///鑷繁鏉ュ埗瀹氬畾涔夌殑瑙勫垯
-                db.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = new Entity.ScheduleCombineSubTableService();
-                db.CodeFirst
-                    .SplitTables()//鏍囪瘑鍒嗚〃
-                    .InitTables<Entity.ScheduleCombine>(); //绋嬪簭鍚姩鏃跺姞杩欎竴琛�,濡傛灉涓�寮犺〃娌℃湁浼氬垵濮嬪寲涓�寮�
-
-                //澶ф暟鎹啓鍏�+琛ㄤ笉瀛樺湪浼氬缓琛�
-                //鑷姩鎵捐〃澶ф暟鎹啓鍏� 
-                return db.Fastest<Entity.ScheduleCombine>().SplitTable().BulkCopy(list) > 0;
-            }
-        }
-
-
-
-        /// <summary>
-        /// 澶ф壒閲忔彃鍏�
-        /// </summary>
-        public async Task<bool> BulkInserts_Create_Async(string runFlag, List<Entity.ScheduleCombine> list)
-        {
-            if (list == null || list.Count < 1)
-                return default;
-            var tableName = GetTableName(runFlag);
-            using (SqlSugarClient db = Connection)
-            {
-                var exist_sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}' ;";
-                if (db.Ado.GetInt(exist_sql) < 1)
-                {
-                    var sql_create_table = $"CREATE TABLE {tableName} (\r\n ID   BIGINT NOT NULL\r\n    PRIMARY KEY,\r\n    RunFlag VARCHAR (255),\r\n  RunCount    INTEGER,\r\n    Pump1   REAL,\r\n   Pump2  REAL,\r\n    Pump3   REAL,\r\n   CurveQH    VARCHAR (255),\r\n    CurveQP    VARCHAR (255),\r\n   AnaStatus BIT\r\n);";
-                    if (db.Ado.ExecuteCommand(sql_create_table) < 1)
-                    {
-                        return false;
-                    }
-                }
-                return await db.Fastest<Entity.ScheduleCombine>().AS(tableName).BulkCopyAsync(list) > 0;
-            }
-        }
-
 
         /// <summary>
         /// 澶ф壒閲忔彃鍏�
@@ -118,54 +74,14 @@
             using (SqlSugarClient db = Connection)
             {
                 var exist_sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
-                if (db.Ado.ExecuteCommand(exist_sql) < 1)
+                if (db.Ado.GetInt(exist_sql) < 1)
                 {
-                    var sql_create_table = $"CREATE TABLE {tableName} (\r\n ID   BIGINT NOT NULL\r\n    PRIMARY KEY,\r\n    RunFlag VARCHAR (255),\r\n  RunCount    INTEGER,\r\n    Pump1   REAL,\r\n   Pump2  REAL,\r\n    Pump3   REAL,\r\n   CurveQH    VARCHAR (255),\r\n    CurveQP    VARCHAR (255),\r\n   AnaStatus BIT\r\n);";
+                    var sql_create_table = $"CREATE TABLE {tableName} {_createTable}";
                     db.Ado.ExecuteCommand(sql_create_table);
                 }
                 //澶ф暟鎹啓鍏�
                 return db.Fastest<Entity.ScheduleCombine>().AS(tableName).BulkCopy(list) > 0;
             }
-        }
-
-        /// <summary>
-        /// 澶ф壒閲忔彃鍏�
-        /// </summary> 
-        public bool BulkInserts_NativeSql(string runFlag, List<Entity.ScheduleCombine> list)
-        {
-            var tableName = GetTableName(runFlag);
-            var connect = ConfigHelper.ConnectionString;
-            SQLiteConnection connection = new SQLiteConnection(connect);//杩炴帴瀵硅薄鍒濆鍖� 
-            connection.Open();//鎵撳紑杩炴帴
-
-            SQLiteCommand command = new SQLiteCommand(connection);//鍛戒护瀵硅薄鍒濆鍖� 
-            command.CommandText = $"VACUUM;";//鎵цVACUUM鍛戒护鏀剁缉鏁版嵁搴�
-            command.ExecuteNonQuery();
-
-            SQLiteTransaction transaction = connection.BeginTransaction();//寮�濮嬩簨鍔� 
-            var sql_exist_table = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
-            command.CommandText = sql_exist_table;
-            if (command.ExecuteNonQuery() < 1)//娌℃湁琛ㄥ氨鍒涘缓琛�
-            {
-                var sql_create_table = $"CREATE TABLE {tableName} (\r\n    ID        BIGINT        NOT NULL\r\n                            PRIMARY KEY,\r\n    RunFlag   VARCHAR (255),\r\n    RunCount  INTEGER,\r\n    Pump1     REAL,\r\n    Pump2     REAL,\r\n    Pump3     REAL,\r\n    CurveQH   VARCHAR (255),\r\n    CurveQP   VARCHAR (255),\r\n    AnaStatus BIT\r\n);";
-                command.CommandText = sql_create_table;
-                command.ExecuteNonQuery();
-            }
-
-            var group = list.GroupBy(x => x.ID).Where(x => x.Count() > 1).Count();
-
-            for (int i = 0; i < list.Count; i++) //[---浣跨敤浜嬪姟---]鎵цINSERT鍛戒护
-            {
-                var item = list[i];
-                var sql_insert = $"INSERT INTO {tableName}(ID, RunFlag, RunCount, Pump1, Pump2, Pump3, CurveQH, CurveQP, AnaStatus) " +
-                    $"VALUES ('{item.ID}','{item.RunFlag}','{item.RunCount}','{item.Pump1}','{item.Pump2}','{item.Pump3}','{item.CurveQH}','{item.CurveQP}','{item.AnaStatus}')";
-                command.CommandText = sql_insert;
-                command.ExecuteNonQuery();
-            }
-            // var result = command.ExecuteScalar();
-            transaction.Commit();//鎻愪氦浜嬪姟
-            connection.Close();//鍏抽棴杩炴帴 
-            return true;
         }
 
 
diff --git a/Schedule/IStation.Algorithm/DAL/ScheduleCombineLog.cs b/Schedule/IStation.Algorithm/DAL/ScheduleCombineLog.cs
deleted file mode 100644
index a96401b..0000000
--- a/Schedule/IStation.Algorithm/DAL/ScheduleCombineLog.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-锘縩amespace IStation.DAL
-{
-    /// <summary>
-    ///   
-    /// </summary>
-    public class ScheduleCombineLog : BaseDAL<Entity.ScheduleCombineLog>
-    {
-        public override SqlSugarClient Connection
-        {
-            get { return ConfigHelper.GetSqlSugarClient(); }
-        }
-    }
-}
diff --git a/Schedule/IStation.Algorithm/DAL/ScheduleCombine_bak.cs b/Schedule/IStation.Algorithm/DAL/ScheduleCombine_bak.cs
new file mode 100644
index 0000000..f931277
--- /dev/null
+++ b/Schedule/IStation.Algorithm/DAL/ScheduleCombine_bak.cs
@@ -0,0 +1,241 @@
+锘縰sing System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace IStation.DAL
+{
+    /// <summary>
+    ///   
+    /// </summary>
+    public class ScheduleCombine_bak
+    {
+        public SqlSugarClient Connection
+        {
+            get { return ConfigHelper.GetSqlSugarClient(); }
+        }
+
+        private readonly string _tableNamePrefix = "ScheduleCombine_Cb_";
+
+        private string GetTableName(string runFlag)
+        {
+            return $"{_tableNamePrefix}{runFlag}";
+        }
+
+        private readonly string _createTable = "(\r\n    ID        BIGINT        NOT NULL\r\n                            PRIMARY KEY,\r\n    RunFlag   VARCHAR (255),\r\n    RunCount  INTEGER,\r\n    Pump1     REAL,\r\n    Pump2     REAL,\r\n    Pump3     REAL,\r\n    CurveQH   VARCHAR (255),\r\n    CurveQP   VARCHAR (255),\r\n    MaxFlow   REAL,\r\n    MinFlow   REAL,\r\n    MaxHead   REAL,\r\n    MinHead   REAL,\r\n    AnaStatus BIT\r\n);";
+
+        /// <summary>
+        /// 鑾峰彇鍏ㄩ儴琛ㄥ悕
+        /// </summary>
+        public List<string> GetAllTableName()
+        {
+            var tables = new List<string>();
+            using (var connection = new SQLiteConnection(ConfigHelper.ConnectionString))
+            {
+                connection.Open();
+                var sql = $"select name from sqlite_master where type='table' and name like '%{_tableNamePrefix}%';";
+                using (var command = new SQLiteCommand(sql, connection))
+                {
+                    using (var reader = command.ExecuteReader())
+                    {
+                        while (reader.Read())
+                        {
+                            var tableName = reader["name"].ToString();
+                            tables.Add(tableName);
+                        }
+                    }
+                }
+            }
+            return tables;
+        }
+
+
+        /// <summary>
+        /// 閫氳繃琛ㄥ悕鑾峰彇鎵�鏈夋湭鍒嗘瀽缁勫悎
+        /// </summary>
+        public List<Entity.ScheduleCombine> GetAllUnanalyzedAnaByTableName(string tableName)
+        {
+            using (SqlSugarClient db = Connection)
+            {
+                var sql = $"select * from {tableName} where AnaStatus=False";
+                var list = db.Ado.SqlQuery<Entity.ScheduleCombine>(sql);
+                return list;
+            }
+        }
+
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary>
+        public bool BulkInserts_SplitTable(List<Entity.ScheduleCombine> list)
+        {
+            if (list == null || list.Count < 1)
+                return default;
+            using (SqlSugarClient db = Connection)
+            {
+                ///鑷繁鏉ュ埗瀹氬畾涔夌殑瑙勫垯
+                db.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = new Entity.ScheduleCombineSubTableService();
+                db.CodeFirst
+                    .SplitTables()//鏍囪瘑鍒嗚〃
+                    .InitTables<Entity.ScheduleCombine>(); //绋嬪簭鍚姩鏃跺姞杩欎竴琛�,濡傛灉涓�寮犺〃娌℃湁浼氬垵濮嬪寲涓�寮�
+
+                //澶ф暟鎹啓鍏�+琛ㄤ笉瀛樺湪浼氬缓琛�
+                //鑷姩鎵捐〃澶ф暟鎹啓鍏� 
+                return db.Fastest<Entity.ScheduleCombine>().SplitTable().BulkCopy(list) > 0;
+            }
+        }
+
+
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary>
+        public async Task<bool> BulkInserts_Create_Async(string runFlag, List<Entity.ScheduleCombine> list)
+        {
+            if (list == null || list.Count < 1)
+                return default;
+            var tableName = GetTableName(runFlag);
+            using (SqlSugarClient db = Connection)
+            {
+                var exist_sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}' ;";
+                if (db.Ado.GetInt(exist_sql) < 1)
+                {
+                    var sql_create_table = $"CREATE TABLE {tableName} {_createTable}";
+                    if (db.Ado.ExecuteCommand(sql_create_table) < 1)
+                    {
+                        return false;
+                    }
+                }
+                return await db.Fastest<Entity.ScheduleCombine>().AS(tableName).BulkCopyAsync(list) > 0;
+            }
+        }
+
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary>
+        public bool BulkInserts_Create(string runFlag, List<Entity.ScheduleCombine> list)
+        {
+            if (list == null || list.Count < 1)
+                return default;
+            var tableName = GetTableName(runFlag);
+            using (SqlSugarClient db = Connection)
+            {
+                var exist_sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
+                if (db.Ado.ExecuteCommand(exist_sql) < 1)
+                {
+                    var sql_create_table = $"CREATE TABLE {tableName} {_createTable}";
+                    db.Ado.ExecuteCommand(sql_create_table);
+                }
+                //澶ф暟鎹啓鍏�
+                return db.Fastest<Entity.ScheduleCombine>().AS(tableName).BulkCopy(list) > 0;
+            }
+        }
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary> 
+        public bool BulkInserts_NativeSql(string runFlag, List<Entity.ScheduleCombine> list)
+        {
+            var tableName = GetTableName(runFlag);
+            var connect = ConfigHelper.ConnectionString;
+            SQLiteConnection connection = new SQLiteConnection(connect);//杩炴帴瀵硅薄鍒濆鍖� 
+            connection.Open();//鎵撳紑杩炴帴
+
+            SQLiteCommand command = new SQLiteCommand(connection);//鍛戒护瀵硅薄鍒濆鍖� 
+            command.CommandText = $"VACUUM;";//鎵цVACUUM鍛戒护鏀剁缉鏁版嵁搴�
+            command.ExecuteNonQuery();
+
+            SQLiteTransaction transaction = connection.BeginTransaction();//寮�濮嬩簨鍔� 
+            var sql_exist_table = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
+            command.CommandText = sql_exist_table;
+            if (command.ExecuteNonQuery() < 1)//娌℃湁琛ㄥ氨鍒涘缓琛�
+            {
+                var sql_create_table = $"CREATE TABLE {tableName} (\r\n    ID        BIGINT        NOT NULL\r\n                            PRIMARY KEY,\r\n    RunFlag   VARCHAR (255),\r\n    RunCount  INTEGER,\r\n    Pump1     REAL,\r\n    Pump2     REAL,\r\n    Pump3     REAL,\r\n    CurveQH   VARCHAR (255),\r\n    CurveQP   VARCHAR (255),\r\n    AnaStatus BIT\r\n);";
+                command.CommandText = sql_create_table;
+                command.ExecuteNonQuery();
+            }
+
+            var group = list.GroupBy(x => x.ID).Where(x => x.Count() > 1).Count();
+
+            for (int i = 0; i < list.Count; i++) //[---浣跨敤浜嬪姟---]鎵цINSERT鍛戒护
+            {
+                var item = list[i];
+                var sql_insert = $"INSERT INTO {tableName}(ID, RunFlag, RunCount, Pump1, Pump2, Pump3, CurveQH, CurveQP, AnaStatus) " +
+                    $"VALUES ('{item.ID}','{item.RunFlag}','{item.RunCount}','{item.Pump1}','{item.Pump2}','{item.Pump3}','{item.CurveQH}','{item.CurveQP}','{item.AnaStatus}')";
+                command.CommandText = sql_insert;
+                command.ExecuteNonQuery();
+            }
+            // var result = command.ExecuteScalar();
+            transaction.Commit();//鎻愪氦浜嬪姟
+            connection.Close();//鍏抽棴杩炴帴 
+            return true;
+        }
+
+
+        /// <summary>
+        /// 璁剧疆宸插垎鏋愮姸鎬�
+        /// </summary>
+        public bool SetAnaStatus(string tableName, long id)
+        {
+            using (SqlSugarClient db = Connection)
+            {
+                var sql = $"update {tableName} set AnaStatus=True where ID={id}";
+                var bol = db.Ado.ExecuteCommand(sql) > 0;
+                return bol;
+            }
+        }
+
+
+        /// <summary>
+        /// 璁剧疆宸插垎鏋愮姸鎬�
+        /// </summary>
+        public bool SetAnaStatus(string tableName, List<long> ids)
+        {
+            using (SqlSugarClient db = Connection)
+            {
+                var sql = $"update {tableName} set AnaStatus=True where ID in(@ids)";
+                var obj = new { ids = ids.ToArray() };
+                var bol = db.Ado.ExecuteCommand(sql, obj) > 0;
+                return bol;
+            }
+        }
+
+
+        /// <summary>
+        /// 鍒ゆ柇鏁版嵁搴撴槸鍚﹀瓨鍦ㄨ〃
+        /// </summary> 
+        public bool ExistTable(string runFlag)
+        {
+            using (SqlSugarClient db = Connection)
+            {
+                var sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{GetTableName(runFlag)}';";
+                var bol = db.Ado.ExecuteCommand(sql) > 0;
+                return bol;
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍏ㄩ儴琛ㄥ悕
+        /// </summary>
+        public bool DeleteAllTable()
+        {
+            var tables = GetAllTableName();
+            if (tables == null || !tables.Any())
+                return false;
+
+            using (SqlSugarClient db = Connection)
+            {
+                db.BeginTran();
+
+                foreach (var table in tables)
+                {
+                    var sql = $"drop table {table};";
+                    db.Ado.ExecuteCommand(sql);
+                }
+                db.CommitTran();
+            }
+            return true;
+        }
+
+
+    }
+}
diff --git a/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs b/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs
index f1c8372..6f4bf3f 100644
--- a/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs
+++ b/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs
@@ -100,65 +100,6 @@
 
         #endregion
 
-        #region BulkInserts
-
-        /// <summary>
-        /// 澶ф壒閲忔彃鍏�
-        /// </summary>
-        public bool BulkInserts(string runFlag, List<Entity.ScheduleConclusion> list)
-        {
-            if (list == null || list.Count < 1)
-                return default;
-            var tableName = GetTableName(runFlag);
-            using (SqlSugarClient db = Connection)
-            {
-                return db.Fastest<Entity.ScheduleConclusion>().AS(tableName).BulkCopy(list) > 0;
-            }
-        }
-
-        /// <summary>
-        /// 澶ф壒閲忔彃鍏�
-        /// </summary>
-        public async Task<bool> BulkInserts_Create_Async(string runFlag, List<Entity.ScheduleConclusion> list)
-        {
-            if (list == null || list.Count < 1)
-                return default;
-            var tableName = GetTableName(runFlag);
-            using (SqlSugarClient db = Connection)
-            {
-                var exist_sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}' ;";
-                if (db.Ado.GetInt(exist_sql) < 1)
-                {
-                    var sql_create_table = $"CREATE TABLE  {tableName}  (\r\n   ID BIGINT  NOT NULL\r\n PRIMARY KEY,\r\n    ScheduleCombineID BIGINT,\r\n   RunFlag    VARCHAR (255),\r\n   Pump1   REAL,\r\n   Pump2   REAL,\r\n   Pump3   REAL,\r\n   Head   REAL,\r\n    Flow    REAL,\r\n   Power  REAL,\r\n    WP  REAL,\r\n   UWP    REAL\r\n);";
-                    if (db.Ado.ExecuteCommand(sql_create_table) < 1)
-                    {
-                        return false;
-                    }
-                }
-                return await db.Fastest<Entity.ScheduleConclusion>().AS(tableName).BulkCopyAsync(list) > 0;
-            }
-        }
-
-        /// <summary>
-        /// 澶ф壒閲忔彃鍏�
-        /// </summary>
-        public bool BulkInserts_SplitTable(List<Entity.ScheduleConclusion> list)
-        {
-            if (list == null || list.Count < 1)
-                return default;
-            using (SqlSugarClient db = Connection)
-            {
-                ///鑷繁鏉ュ埗瀹氬畾涔夌殑瑙勫垯
-                db.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = new Entity.ScheduleConclusionSubTableService();
-                db.CodeFirst
-                    .SplitTables()//鏍囪瘑鍒嗚〃
-                    .InitTables<Entity.ScheduleConclusion>(); //绋嬪簭鍚姩鏃跺姞杩欎竴琛�,濡傛灉涓�寮犺〃娌℃湁浼氬垵濮嬪寲涓�寮�
-
-                //澶ф暟鎹啓鍏�+琛ㄤ笉瀛樺湪浼氬缓琛�
-                //鑷姩鎵捐〃澶ф暟鎹啓鍏� 
-                return db.Fastest<Entity.ScheduleConclusion>().SplitTable().BulkCopy(list) > 0;
-            }
-        }
 
         /// <summary>
         /// 澶ф壒閲忔彃鍏�
@@ -181,47 +122,6 @@
             }
         }
 
-        /// <summary>
-        /// 澶ф壒閲忔彃鍏�
-        /// </summary> 
-        public bool BulkInserts_NativeSql(string runFlag, List<Entity.ScheduleConclusion> list)
-        {
-            var tableName = GetTableName(runFlag);
-            var connect = ConfigHelper.ConnectionString;
-            SQLiteConnection connection = new SQLiteConnection(connect);//杩炴帴瀵硅薄鍒濆鍖� 
-            connection.Open();//鎵撳紑杩炴帴
-
-            SQLiteCommand command = new SQLiteCommand(connection);//鍛戒护瀵硅薄鍒濆鍖� 
-            command.CommandText = $"VACUUM;";//鎵цVACUUM鍛戒护鏀剁缉鏁版嵁搴�
-            command.ExecuteNonQuery();
-
-            SQLiteTransaction transaction = connection.BeginTransaction();//寮�濮嬩簨鍔� 
-
-            var sql_exist_table = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
-            command.CommandText = sql_exist_table;
-            if (command.ExecuteNonQuery() < 1)//娌℃湁琛ㄥ氨鍒涘缓琛�
-            {
-                var sql_create_table = $"CREATE TABLE  {tableName}  (\r\n    ID                BIGINT        NOT NULL\r\n                                    PRIMARY KEY,\r\n    ScheduleCombineID BIGINT,\r\n    RunFlag           VARCHAR (255),\r\n    Pump1             REAL,\r\n    Pump2             REAL,\r\n    Pump3             REAL,\r\n    Head              REAL,\r\n    Flow              REAL,\r\n    Power             REAL,\r\n    WP                REAL,\r\n    UWP               REAL\r\n);\r\n";
-                command.CommandText = sql_create_table;
-                command.ExecuteNonQuery();
-            }
-
-            for (int i = 0; i < list.Count; i++) //[---浣跨敤浜嬪姟---]鎵цINSERT鍛戒护
-            {
-                var sql_insert = $"INSERT INTO {tableName}(ID, ScheduleCombineID, RunFlag, Pump1, Pump2, Pump3, Head, Flow, Power, WP, UWP) " +
-                    $"VALUES ('{list[i].ID}','{list[i].ScheduleCombineID}','{list[i].RunFlag}','{list[i].Pump1}','{list[i].Pump2}','{list[i].Pump3}','{list[i].Head}','{list[i].Flow}','{list[i].Power}','{list[i].WP}','{list[i].UWP}')";
-                command.CommandText = sql_insert;
-                command.ExecuteNonQuery();
-            }
-            command.ExecuteScalar();
-            transaction.Commit();//鎻愪氦浜嬪姟
-            connection.Close();//鍏抽棴杩炴帴 
-            return true;
-        }
-
-        #endregion
-
-
 
         /// <summary>
         /// 鏌ヨ
@@ -239,29 +139,6 @@
                 var list = db.Queryable<Entity.ScheduleConclusion>().AS(tableName)
                       .Where(x => x.Head == targetHead)
                       .OrderBy(x => x.Power)
-                      .ToList();
-                return list;
-            }
-
-        }
-
-        /// <summary>
-        /// 鏌ヨ
-        /// </summary>
-        public List<Entity.ScheduleConclusion> GetList(string runFlag, double targetFlow, double targetHead, int takeCount)
-        {
-            var tableName = GetTableName(runFlag);
-            using (SqlSugarClient db = Connection)
-            {
-                var sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
-                if (db.Ado.GetInt(sql) < 1)
-                {
-                    return default;
-                }
-                var list = db.Queryable<Entity.ScheduleConclusion>().AS(tableName)
-                      .Where(x => x.Head >= targetHead && x.Head <= targetHead * 1.01 && x.Flow > targetFlow)
-                      .OrderBy(x => x.Power)
-                      .Take(takeCount)
                       .ToList();
                 return list;
             }
diff --git a/Schedule/IStation.Algorithm/DAL/ScheduleConclusion_bak.cs b/Schedule/IStation.Algorithm/DAL/ScheduleConclusion_bak.cs
new file mode 100644
index 0000000..63a478c
--- /dev/null
+++ b/Schedule/IStation.Algorithm/DAL/ScheduleConclusion_bak.cs
@@ -0,0 +1,272 @@
+锘縩amespace IStation.DAL
+{
+    /// <summary>
+    ///   
+    /// </summary>
+    public class ScheduleConclusion_bak
+    {
+        public SqlSugarClient Connection
+        {
+            get { return ConfigHelper.GetSqlSugarClient(); }
+        }
+
+        private readonly string _tableNamePrefix = "ScheduleConclusion_Cl_";
+
+        private string GetTableName(string runFlag)
+        {
+            return $"{_tableNamePrefix}{runFlag}";
+        }
+
+        #region Table
+
+        /// <summary>
+        /// 鑾峰彇鍏ㄩ儴琛ㄥ悕
+        /// </summary>
+        public List<string> GetAllTableName()
+        {
+            var tables = new List<string>();
+            using (var connection = new SQLiteConnection(ConfigHelper.ConnectionString))
+            {
+                connection.Open();
+                var sql = $"select name from sqlite_master where type='table' and name like '%{_tableNamePrefix}%';";
+                using (var command = new SQLiteCommand(sql, connection))
+                {
+                    using (var reader = command.ExecuteReader())
+                    {
+                        while (reader.Read())
+                        {
+                            var tableName = reader["name"].ToString();
+                            tables.Add(tableName);
+                        }
+                    }
+                }
+            }
+            return tables;
+        }
+
+        /// <summary>
+        /// 鍒ゆ柇鏁版嵁搴撴槸鍚﹀瓨鍦ㄨ〃
+        /// </summary> 
+        public bool ExistTable(string runFlag)
+        {
+            using (SqlSugarClient db = Connection)
+            {
+                var sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{GetTableName(runFlag)}';";
+                var bol = db.Ado.GetInt(sql) > 0;
+                return bol;
+            }
+        }
+
+        /// <summary>
+        /// 鏁版嵁搴撳垱寤鸿〃
+        /// </summary> 
+        public bool CreateTable(string runFlag)
+        {
+            using (SqlSugarClient db = Connection)
+            {
+                var tableName = GetTableName(runFlag);
+                var sql_exist = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
+                if (db.Ado.GetInt(sql_exist) > 0)
+                    return true;
+                var sql_create_table = $"CREATE TABLE  {tableName}  (\r\n   ID BIGINT  NOT NULL\r\n PRIMARY KEY,\r\n    ScheduleCombineID BIGINT,\r\n   RunFlag    VARCHAR (255),\r\n   Pump1   REAL,\r\n   Pump2   REAL,\r\n   Pump3   REAL,\r\n   Head   REAL,\r\n    Flow    REAL,\r\n   Power  REAL,\r\n    WP  REAL,\r\n   UWP    REAL\r\n);";
+                var bol = db.Ado.ExecuteCommand(sql_create_table) > 0;
+                return bol;
+            }
+        }
+
+        /// <summary>
+        //  鍒犻櫎鎵�鏈夎〃
+        /// </summary>
+        public bool DeleteAllTable()
+        {
+            var tables = GetAllTableName();
+            if (tables == null || !tables.Any())
+                return false;
+
+            using (SqlSugarClient db = Connection)
+            {
+                db.BeginTran();
+
+                foreach (var table in tables)
+                {
+                    var sql = $"drop table {table};";
+                    db.Ado.ExecuteCommand(sql);
+                }
+                db.CommitTran();
+            }
+            return true;
+        }
+
+
+        #endregion
+
+        #region BulkInserts
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary>
+        public bool BulkInserts(string runFlag, List<Entity.ScheduleConclusion> list)
+        {
+            if (list == null || list.Count < 1)
+                return default;
+            var tableName = GetTableName(runFlag);
+            using (SqlSugarClient db = Connection)
+            {
+                return db.Fastest<Entity.ScheduleConclusion>().AS(tableName).BulkCopy(list) > 0;
+            }
+        }
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary>
+        public async Task<bool> BulkInserts_Create_Async(string runFlag, List<Entity.ScheduleConclusion> list)
+        {
+            if (list == null || list.Count < 1)
+                return default;
+            var tableName = GetTableName(runFlag);
+            using (SqlSugarClient db = Connection)
+            {
+                var exist_sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}' ;";
+                if (db.Ado.GetInt(exist_sql) < 1)
+                {
+                    var sql_create_table = $"CREATE TABLE  {tableName}  (\r\n   ID BIGINT  NOT NULL\r\n PRIMARY KEY,\r\n    ScheduleCombineID BIGINT,\r\n   RunFlag    VARCHAR (255),\r\n   Pump1   REAL,\r\n   Pump2   REAL,\r\n   Pump3   REAL,\r\n   Head   REAL,\r\n    Flow    REAL,\r\n   Power  REAL,\r\n    WP  REAL,\r\n   UWP    REAL\r\n);";
+                    if (db.Ado.ExecuteCommand(sql_create_table) < 1)
+                    {
+                        return false;
+                    }
+                }
+                return await db.Fastest<Entity.ScheduleConclusion>().AS(tableName).BulkCopyAsync(list) > 0;
+            }
+        }
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary>
+        public bool BulkInserts_SplitTable(List<Entity.ScheduleConclusion> list)
+        {
+            if (list == null || list.Count < 1)
+                return default;
+            using (SqlSugarClient db = Connection)
+            {
+                ///鑷繁鏉ュ埗瀹氬畾涔夌殑瑙勫垯
+                db.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = new Entity.ScheduleConclusionSubTableService();
+                db.CodeFirst
+                    .SplitTables()//鏍囪瘑鍒嗚〃
+                    .InitTables<Entity.ScheduleConclusion>(); //绋嬪簭鍚姩鏃跺姞杩欎竴琛�,濡傛灉涓�寮犺〃娌℃湁浼氬垵濮嬪寲涓�寮�
+
+                //澶ф暟鎹啓鍏�+琛ㄤ笉瀛樺湪浼氬缓琛�
+                //鑷姩鎵捐〃澶ф暟鎹啓鍏� 
+                return db.Fastest<Entity.ScheduleConclusion>().SplitTable().BulkCopy(list) > 0;
+            }
+        }
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary>
+        public bool BulkInserts_Create(string runFlag, List<Entity.ScheduleConclusion> list)
+        {
+            if (list == null || list.Count < 1)
+                return default;
+            var tableName = GetTableName(runFlag);
+            using (SqlSugarClient db = Connection)
+            {
+                var exist_sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}' ;";
+                if (db.Ado.GetInt(exist_sql) < 1)
+                {
+                    var sql_create_table = $"CREATE TABLE  {tableName}  (\r\n   ID BIGINT  NOT NULL\r\n PRIMARY KEY,\r\n    ScheduleCombineID BIGINT,\r\n   RunFlag    VARCHAR (255),\r\n   Pump1   REAL,\r\n   Pump2   REAL,\r\n   Pump3   REAL,\r\n   Head   REAL,\r\n    Flow    REAL,\r\n   Power  REAL,\r\n    WP  REAL,\r\n   UWP    REAL\r\n);";
+                    db.Ado.ExecuteCommand(sql_create_table);
+                }
+                //澶ф暟鎹啓鍏�
+                return db.Fastest<Entity.ScheduleConclusion>().AS(tableName).BulkCopy(list) > 0;
+            }
+        }
+
+        /// <summary>
+        /// 澶ф壒閲忔彃鍏�
+        /// </summary> 
+        public bool BulkInserts_NativeSql(string runFlag, List<Entity.ScheduleConclusion> list)
+        {
+            var tableName = GetTableName(runFlag);
+            var connect = ConfigHelper.ConnectionString;
+            SQLiteConnection connection = new SQLiteConnection(connect);//杩炴帴瀵硅薄鍒濆鍖� 
+            connection.Open();//鎵撳紑杩炴帴
+
+            SQLiteCommand command = new SQLiteCommand(connection);//鍛戒护瀵硅薄鍒濆鍖� 
+            command.CommandText = $"VACUUM;";//鎵цVACUUM鍛戒护鏀剁缉鏁版嵁搴�
+            command.ExecuteNonQuery();
+
+            SQLiteTransaction transaction = connection.BeginTransaction();//寮�濮嬩簨鍔� 
+
+            var sql_exist_table = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
+            command.CommandText = sql_exist_table;
+            if (command.ExecuteNonQuery() < 1)//娌℃湁琛ㄥ氨鍒涘缓琛�
+            {
+                var sql_create_table = $"CREATE TABLE  {tableName}  (\r\n    ID                BIGINT        NOT NULL\r\n                                    PRIMARY KEY,\r\n    ScheduleCombineID BIGINT,\r\n    RunFlag           VARCHAR (255),\r\n    Pump1             REAL,\r\n    Pump2             REAL,\r\n    Pump3             REAL,\r\n    Head              REAL,\r\n    Flow              REAL,\r\n    Power             REAL,\r\n    WP                REAL,\r\n    UWP               REAL\r\n);\r\n";
+                command.CommandText = sql_create_table;
+                command.ExecuteNonQuery();
+            }
+
+            for (int i = 0; i < list.Count; i++) //[---浣跨敤浜嬪姟---]鎵цINSERT鍛戒护
+            {
+                var sql_insert = $"INSERT INTO {tableName}(ID, ScheduleCombineID, RunFlag, Pump1, Pump2, Pump3, Head, Flow, Power, WP, UWP) " +
+                    $"VALUES ('{list[i].ID}','{list[i].ScheduleCombineID}','{list[i].RunFlag}','{list[i].Pump1}','{list[i].Pump2}','{list[i].Pump3}','{list[i].Head}','{list[i].Flow}','{list[i].Power}','{list[i].WP}','{list[i].UWP}')";
+                command.CommandText = sql_insert;
+                command.ExecuteNonQuery();
+            }
+            command.ExecuteScalar();
+            transaction.Commit();//鎻愪氦浜嬪姟
+            connection.Close();//鍏抽棴杩炴帴 
+            return true;
+        }
+
+        #endregion
+
+
+
+        /// <summary>
+        /// 鏌ヨ
+        /// </summary>
+        public List<Entity.ScheduleConclusion> GetList(string runFlag, double targetHead)
+        {
+            var tableName = GetTableName(runFlag);
+            using (SqlSugarClient db = Connection)
+            {
+                var sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
+                if (db.Ado.GetInt(sql) < 1)
+                {
+                    return default;
+                }
+                var list = db.Queryable<Entity.ScheduleConclusion>().AS(tableName)
+                      .Where(x => x.Head == targetHead)
+                      .OrderBy(x => x.Power)
+                      .ToList();
+                return list;
+            }
+
+        }
+
+        /// <summary>
+        /// 鏌ヨ
+        /// </summary>
+        public List<Entity.ScheduleConclusion> GetList(string runFlag, double targetFlow, double targetHead, int takeCount)
+        {
+            var tableName = GetTableName(runFlag);
+            using (SqlSugarClient db = Connection)
+            {
+                var sql = $"select count(*)  from sqlite_master where type = 'table' and name = '{tableName}';";
+                if (db.Ado.GetInt(sql) < 1)
+                {
+                    return default;
+                }
+                var list = db.Queryable<Entity.ScheduleConclusion>().AS(tableName)
+                      .Where(x => x.Head >= targetHead && x.Head <= targetHead * 1.01 && x.Flow > targetFlow)
+                      .OrderBy(x => x.Power)
+                      .Take(takeCount)
+                      .ToList();
+                return list;
+            }
+
+        }
+
+    }
+}
diff --git a/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs b/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs
index 798692e..8763d5e 100644
--- a/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs
+++ b/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs
@@ -2,8 +2,7 @@
 {
     /// <summary>
     /// 璋冨害缁勫悎
-    /// </summary>  
-    [SplitTable(SplitType._Custom01)]
+    /// </summary>   
     public class ScheduleCombine
     {
         public ScheduleCombine()
diff --git a/Schedule/IStation.Algorithm/Expand/ListExpand.cs b/Schedule/IStation.Algorithm/Expand/ListExpand.cs
new file mode 100644
index 0000000..c3349fa
--- /dev/null
+++ b/Schedule/IStation.Algorithm/Expand/ListExpand.cs
@@ -0,0 +1,107 @@
+锘縩amespace IStation
+{
+    public static class ListExpand
+    {
+        /// <summary>
+        /// 鍒ゆ柇涓や釜闆嗗悎鏄惁鏄浉绛夌殑(鎵�鏈夌殑鍏冪礌鍙婃暟閲忛兘鐩哥瓑)
+        /// </summary>
+        /// <typeparam name="T">闆嗗悎鍏冪礌绫诲瀷</typeparam>
+        /// <param name="sourceCollection">婧愰泦鍚堝垪琛�</param>
+        /// <param name="targetCollection">鐩爣闆嗗悎鍒楄〃</param>
+        /// <returns>涓や釜闆嗗悎鐩哥瓑鍒欒繑鍥濼rue,鍚﹀垯杩斿洖False</returns>
+        public static bool EqualList<T>(this IList<T> sourceCollection, IList<T> targetCollection) where T : IEquatable<T>
+        {
+            //绌洪泦鍚堢洿鎺ヨ繑鍥濬alse,鍗充娇鏄袱涓兘鏄┖闆嗗悎,涔熻繑鍥濬alse
+            if (sourceCollection == null || targetCollection == null)
+            {
+                return false;
+            }
+
+            if (object.ReferenceEquals(sourceCollection, targetCollection))
+            {
+                return true;
+            }
+
+            if (sourceCollection.Count != targetCollection.Count)
+            {
+                return false;
+            }
+
+            var sourceCollectionStaticsDict = sourceCollection.StatisticRepetition();
+            var targetCollectionStaticsDict = targetCollection.StatisticRepetition();
+
+            return sourceCollectionStaticsDict.EqualDictionary(targetCollectionStaticsDict);
+        }
+
+        /// <summary>
+        /// 鍒ゆ柇涓や釜瀛楀吀鏄惁鏄浉绛夌殑(鎵�鏈夌殑瀛楀吀椤瑰搴旂殑鍊奸兘鐩哥瓑)
+        /// </summary>
+        /// <typeparam name="TKey">瀛楀吀椤圭被鍨�</typeparam>
+        /// <typeparam name="TValue">瀛楀吀鍊肩被鍨�</typeparam>
+        /// <param name="sourceDictionary">婧愬瓧鍏�</param>
+        /// <param name="targetDictionary">鐩爣瀛楀吀</param>
+        /// <returns>涓や釜瀛楀吀鐩哥瓑鍒欒繑鍥濼rue,鍚﹀垯杩斿洖False</returns>
+        public static bool EqualDictionary<TKey, TValue>(this Dictionary<TKey, TValue> sourceDictionary, Dictionary<TKey, TValue> targetDictionary)
+            where TKey : IEquatable<TKey>
+            where TValue : IEquatable<TValue>
+        {
+            //绌哄瓧鍏哥洿鎺ヨ繑鍥濬alse,鍗充娇鏄袱涓兘鏄┖瀛楀吀,涔熻繑鍥濬alse
+            if (sourceDictionary == null || targetDictionary == null)
+            {
+                return false;
+            }
+
+            if (object.ReferenceEquals(sourceDictionary, targetDictionary))
+            {
+                return true;
+            }
+
+            if (sourceDictionary.Count != targetDictionary.Count)
+            {
+                return false;
+            }
+
+            //姣旇緝涓や釜瀛楀吀鐨凨ey涓嶸alue
+            foreach (KeyValuePair<TKey, TValue> item in sourceDictionary)
+            {
+                //濡傛灉鐩爣瀛楀吀涓嶅寘鍚簮瀛楀吀浠绘剰涓�椤�,鍒欎笉鐩哥瓑
+                if (!targetDictionary.ContainsKey(item.Key))
+                {
+                    return false;
+                }
+
+                //濡傛灉鍚屼竴涓瓧鍏搁」鐨勫�间笉鐩哥瓑,鍒欎笉鐩哥瓑
+                if (!targetDictionary[item.Key].Equals(item.Value))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// 缁熻闆嗗悎鐨勯噸澶嶉」,骞惰繑鍥炰竴涓瓧鍏�
+        /// </summary>
+        /// <typeparam name="T">闆嗗悎鍏冪礌绫诲瀷</typeparam>
+        /// <param name="sourceCollection">缁熻闆嗗悎鍒楄〃</param>
+        /// <returns>杩斿洖涓�涓泦鍚堝厓绱犲強閲嶅鏁伴噺鐨勫瓧鍏�</returns>
+        private static Dictionary<T, int> StatisticRepetition<T>(this IEnumerable<T> sourceCollection) where T : IEquatable<T>
+        {
+            var collectionStaticsDict = new Dictionary<T, int>();
+            foreach (var item in sourceCollection)
+            {
+                if (collectionStaticsDict.ContainsKey(item))
+                {
+                    collectionStaticsDict[item]++;
+                }
+                else
+                {
+                    collectionStaticsDict.Add(item, 1);
+                }
+            }
+
+            return collectionStaticsDict;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Schedule/IStation.Algorithm/Helper/StringListHelper.cs b/Schedule/IStation.Algorithm/Helper/StringListHelper.cs
new file mode 100644
index 0000000..e1fe317
--- /dev/null
+++ b/Schedule/IStation.Algorithm/Helper/StringListHelper.cs
@@ -0,0 +1,46 @@
+锘縩amespace IStation
+{
+    /// <summary>
+    /// 瀛楃鍒楄〃杈呭姪绫�
+    /// </summary>
+    public class StringListHelper
+    {
+        //鍒嗗壊瀛楃
+        private const string _split = ",";
+
+        /// <summary>
+        /// 杞寲涓哄瓧绗︿覆
+        /// </summary>
+        public static string ToString(IEnumerable<string> list)
+        {
+            if (list == null || list.Count() < 1)
+                return string.Empty;
+            return string.Join(_split, list);
+        }
+
+        /// <summary>
+        /// 杞寲涓哄垪琛�
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public static List<string> ToList(string str)
+        {
+            if (string.IsNullOrEmpty(str))
+                return new List<string>();
+            try
+            {
+                var list = str.Split(new string[] { _split }, StringSplitOptions.RemoveEmptyEntries);
+                if (list.Count() < 1)
+                    return new List<string>();
+                return list.Select(x => x).ToList();
+            }
+            catch
+            {
+                return new List<string>();
+            }
+
+        }
+
+
+    }
+}
diff --git a/Schedule/IStation.Algorithm/IStation.Algorithm.csproj b/Schedule/IStation.Algorithm/IStation.Algorithm.csproj
index 381f4a8..0e9b876 100644
--- a/Schedule/IStation.Algorithm/IStation.Algorithm.csproj
+++ b/Schedule/IStation.Algorithm/IStation.Algorithm.csproj
@@ -39,6 +39,8 @@
 	  <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%283%29.cs" />
 	  <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%284%29.cs" />
 	  <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%285%29.cs" />
+	  <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%286%29.cs" />
+	  <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%287%29.cs" />
 	  <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗.cs" />
 	</ItemGroup>
 
diff --git a/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs b/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs
index fa8d83e..7535f20 100644
--- a/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs
+++ b/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs
@@ -162,7 +162,7 @@
 
             string runFlag;
             List<AnaPumpFreItem> pump1, pump2, pump3;
-            var maxPumpCount = 2;
+            var maxPumpCount = 1;
             var anaPumpItemsArray = anaPumpItems.ToArray();
             var parallelHelper = new ParallelConnectionHelper();
             for (int pumpCount = 1; pumpCount <= maxPumpCount; pumpCount++)
diff --git "a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0506\051.cs" "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0506\051.cs"
new file mode 100644
index 0000000..39c2cd5
--- /dev/null
+++ "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0506\051.cs"
@@ -0,0 +1,380 @@
+锘縩amespace IStation.Algorithm
+{
+
+    #region ViewModel
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class FreCombine
+    {
+        public FreCombine() { }
+        public List<int> Flags { get; set; }
+        public int RunCount { get; set; }
+        public double Frequency { get; set; }
+        public double Flow { get; set; }
+        public double Power { get; set; }
+    }
+
+
+
+    /// <summary>
+    /// 鍒嗘瀽娉甸」
+    /// </summary>
+    public class OptimalCombine
+    {
+        public OptimalCombine() { }
+        public List<int> Flags { get; set; }
+        public double Flow { get; set; }
+        public double Head { get; set; }
+        public double Power { get; set; }
+        public List<FreCombine> Combines { get; set; }
+        public string Remark { get; set; }
+        public double Scale { get; set; }
+    }
+
+    #endregion
+
+    /// <summary>
+    /// 璋冨害鍒嗘瀽杈呭姪绫�
+    /// </summary>
+    public class SchedulingHelper
+    {
+        double _frequency_def = 50;
+        decimal _frequency_min = 25;
+        decimal _frequency_max = 50;
+        decimal _frequency_space = 0.1m;//棰戠巼闂撮殧  
+
+        double _head_space = 0.1;//鎵▼闂撮殧
+
+        #region RunFlag
+        string _falgFrePumpTag = "B";
+        string _falgFixPumpTag = "G";
+        string _falgSpaceMark = "_";
+
+
+        string GetRunFlag(int[] flags)
+        {
+            var runFlag = string.Empty;
+            var index = 0;
+            var count = flags.Length;
+            foreach (var flag in flags)
+            {
+                runFlag += GetGFlag(flag);
+                index++;
+                if (index != count)
+                {
+                    runFlag += _falgSpaceMark;
+                }
+            }
+            return runFlag;
+        }
+
+        string GetRunFlag(List<int> flags)
+        {
+            var runFlag = string.Empty;
+            var index = 0;
+            var count = flags.Count;
+            foreach (var flag in flags)
+            {
+                runFlag += GetGFlag(flag);
+                index++;
+                if (index != count)
+                {
+                    runFlag += _falgSpaceMark;
+                }
+            }
+            return runFlag;
+        }
+
+        string GetGFlag(int flag)
+        {
+            return _falgFrePumpTag + flag;
+        }
+
+        #endregion
+
+        DAL.ScheduleCombine _dal = new DAL.ScheduleCombine();
+        DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion();
+        DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog();
+
+
+        private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 };
+        private List<int> _combineFlags2 = new List<int>() { 15 };
+
+        public string Ana(List<Pump> pumps, double taget_flow, double taget_head, List<int> must_open_pump_flags, List<int> must_not_open_pump_flags)
+        {
+            taget_flow = Math.Round(taget_head, 1);
+            taget_head = Math.Round(taget_head, 1);
+
+            #region 蹇呭紑娉靛垪琛�
+            var must_open_pump_flags_remark = string.Empty;
+            var exist_must_open_pump_flags = must_open_pump_flags != null && must_open_pump_flags.Count > 0;
+            if (exist_must_open_pump_flags)
+            {
+                must_open_pump_flags = must_open_pump_flags.OrderBy(x => x).ToList();
+                must_open_pump_flags_remark = IntListHelper.ToString(must_open_pump_flags);
+            }
+            #endregion
+
+            #region 蹇呬笉鑳藉紑娉靛垪琛�
+
+            var exist_must_not_open_pump_flags = must_not_open_pump_flags != null && must_not_open_pump_flags.Count > 0;
+
+            #endregion
+
+            var pump_flag_list = pumps.Select(x => x.ID).ToList();
+            var optimal_combine_list = new List<OptimalCombine>();
+            for (int pumpCount = 1; pumpCount <= pumps.Count; pumpCount++)
+            {
+                var combine_list = PermutationAndCombination<int>.GetCombination(pump_flag_list.ToArray(), pumpCount);
+                foreach (var combine in combine_list)
+                {
+                    List<int> combine_flag_list_part1 = new List<int>();
+                    List<int> combine_flag_list_part2 = new List<int>();
+
+                    foreach (var pump in combine)
+                    {
+                        if (_combineFlags1.Contains(pump))
+                        {
+                            combine_flag_list_part1.Add(pump);
+                        }
+                        else
+                        {
+                            combine_flag_list_part2.Add(pump);
+                        }
+                    }
+
+                    List<FreCombine> fre_combine_list_part1 = new List<FreCombine>();
+                    List<FreCombine> fre_combine_list_part2 = new List<FreCombine>();
+
+                    if (combine_flag_list_part1.Count > 0)
+                    {
+                        var conclusion_list_dic = new Dictionary<int, List<Entity.ScheduleConclusion>>();
+                        foreach (var flag in combine_flag_list_part1)
+                        {
+                            var runFlag = GetGFlag(flag);
+                            if (conclusion_list_dic.ContainsKey(flag))
+                                continue;
+                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, taget_head);
+                            conclusion_list_dic[flag] = conclusionList;
+                        }
+
+                        if (conclusion_list_dic.Count < 1)
+                        {
+                            continue;
+                        }
+
+                        for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space)
+                        {
+                            var freCombine = new FreCombine();
+                            freCombine.Frequency = (double)fre;
+                            freCombine.Flags = new List<int>();
+                            foreach (var item in conclusion_list_dic)
+                            {
+                                var conclusion = item.Value.Find(x => x.Pump1 == (double)fre);
+                                if (conclusion != null)
+                                {
+                                    freCombine.Flags.Add(item.Key);
+                                    freCombine.Flow += conclusion.Flow;
+                                    freCombine.Power += conclusion.Power;
+                                    freCombine.RunCount++;
+                                }
+                            }
+                            if (freCombine.Flags.Count < 1)
+                                continue;
+                            fre_combine_list_part1.Add(freCombine);
+                        }
+                    }
+                    if (combine_flag_list_part2.Count > 0)
+                    {
+                        var conclusion_list_dic = new Dictionary<int, List<Entity.ScheduleConclusion>>();
+                        foreach (var flag in combine_flag_list_part2)
+                        {
+                            var runFlag = GetGFlag(flag);
+                            if (conclusion_list_dic.ContainsKey(flag))
+                                continue;
+                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, taget_head);
+                            conclusion_list_dic[flag] = conclusionList;
+                        }
+
+                        if (conclusion_list_dic.Count < 1)
+                        {
+                            continue;
+                        }
+
+                        for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space)
+                        {
+                            var freCombine = new FreCombine();
+                            freCombine.Frequency = (double)fre;
+                            freCombine.Flags = new List<int>();
+                            foreach (var item in conclusion_list_dic)
+                            {
+                                var conclusion = item.Value.Find(x => x.Pump1 == (double)fre);
+                                if (conclusion != null)
+                                {
+                                    freCombine.Flags.Add(item.Key);
+                                    freCombine.Flow += conclusion.Flow;
+                                    freCombine.Power += conclusion.Power;
+                                    freCombine.RunCount++;
+                                }
+                            }
+                            if (freCombine.Flags.Count < 1)
+                                continue;
+                            fre_combine_list_part2.Add(freCombine);
+                        }
+                    }
+
+                    if (fre_combine_list_part1.Count == 0 && fre_combine_list_part2.Count == 0)
+                        continue;
+
+                    var optimal_combine = AnaOptimalCombine(taget_flow, fre_combine_list_part1, fre_combine_list_part2, must_open_pump_flags, must_not_open_pump_flags);
+                    if (optimal_combine == null)
+                        continue;
+                    if (exist_must_open_pump_flags)
+                    {
+                        if (!optimal_combine.Remark.Contains(must_open_pump_flags_remark))
+                        {
+                            optimal_combine.Scale *= 0.8;
+                        }
+                        else
+                        {
+                            if (optimal_combine.Flags.Count == must_open_pump_flags.Count)
+                            {
+                                optimal_combine.Scale *= 1.1;
+                            }
+                        }
+                    }
+                    optimal_combine.Head = taget_head;
+                    optimal_combine_list.Add(optimal_combine);
+                }
+            }
+
+            if (optimal_combine_list.Count < 1)
+                return "鏃犳柟妗�";
+
+            var sb = new StringBuilder();
+            optimal_combine_list = optimal_combine_list.OrderByDescending(x => x.Scale).ToList();
+            foreach (var opt in optimal_combine_list)
+            {
+                sb.AppendLine($"Scale:{opt.Scale},Flow:{opt.Flow.ToString("N1")},Power:{opt.Power.ToString("N1")}," +
+                    $"Flags:{opt.Remark};FlowDeviation:{(opt.Flow - taget_flow).ToString("N1")}");
+            }
+            return sb.ToString();
+
+        }
+
+
+        private OptimalCombine AnaOptimalCombine(double target_flow, List<FreCombine> fre_combine_list_part1, List<FreCombine> fre_combine_list_part2, List<int> must_open_pump_flags, List<int> must_not_open_pump_flags)
+        {
+            double flow_deviation = target_flow;
+            double total_power = double.MaxValue;
+            double total_flow = double.MaxValue;
+
+            FreCombine optimal_combine_part1 = null;
+            FreCombine optimal_combine_part2 = null;
+            if (fre_combine_list_part1.Count < 1 || fre_combine_list_part2.Count < 1)
+            {
+                for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                {
+                    var fre_combine1 = fre_combine_list_part1[Index_part1];
+
+                    var current_flow = fre_combine1.Flow;
+                    var current_power = fre_combine1.Power;
+
+                    var diff_flow = Math.Abs(current_flow - target_flow);
+                    if (diff_flow < flow_deviation)
+                    {
+                        optimal_combine_part1 = fre_combine1;
+                        total_power = fre_combine1.Power;
+                        total_flow = current_flow;
+                        flow_deviation = diff_flow;
+                    }
+
+                    if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                    {
+                        optimal_combine_part1 = fre_combine1;
+                        total_power = fre_combine1.Power;
+                        total_flow = current_flow;
+                    }
+                }
+            }
+            else
+            {
+                for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                {
+                    for (int Index_part2 = 0; Index_part2 < fre_combine_list_part2.Count; Index_part2++)
+                    {
+                        var fre_combine1 = fre_combine_list_part1[Index_part1];
+                        var fre_combine2 = fre_combine_list_part2[Index_part2];
+
+                        var current_flow = fre_combine1.Flow + fre_combine2.Flow;
+                        var current_power = fre_combine1.Power + fre_combine2.Power;
+
+                        var diff_flow = Math.Abs(current_flow - target_flow);
+                        if (diff_flow < flow_deviation)
+                        {
+                            optimal_combine_part1 = fre_combine1;
+                            optimal_combine_part2 = fre_combine2;
+                            total_power = fre_combine1.Power + fre_combine2.Power;
+                            total_flow = current_flow;
+                            flow_deviation = diff_flow;
+                        }
+
+                        if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                        {
+                            optimal_combine_part1 = fre_combine1;
+                            optimal_combine_part2 = fre_combine2;
+                            total_power = fre_combine1.Power + fre_combine2.Power;
+                            total_flow = current_flow;
+                        }
+
+                    }
+                }
+            }
+
+            if (optimal_combine_part1 == null && optimal_combine_part2 == null)
+                return default;
+
+            var optimal_combine = new OptimalCombine();
+            optimal_combine.Combines = new List<FreCombine>();
+            optimal_combine.Flags = new List<int>();
+            if (optimal_combine_part1 != null)
+            {
+                optimal_combine.Combines.Add(optimal_combine_part1);
+                optimal_combine.Flags.AddRange(optimal_combine_part1.Flags);
+            }
+            if (optimal_combine_part2 != null)
+            {
+                optimal_combine.Combines.Add(optimal_combine_part2);
+                optimal_combine.Flags.AddRange(optimal_combine_part2.Flags);
+            }
+
+            optimal_combine.Flow = total_flow;
+            optimal_combine.Power = total_power;
+            optimal_combine.Flags = optimal_combine.Flags.OrderBy(x => x).ToList();
+            optimal_combine.Remark = IntListHelper.ToString(optimal_combine.Flags);
+            optimal_combine.Scale = 1 * Math.Abs((total_flow / target_flow));
+            return optimal_combine;
+        }
+
+        /// <summary>
+        /// 鎻掑叆鍒嗘瀽鏃ュ織
+        /// </summary> 
+        private void InsertAnaLog(string info)
+        {
+            var entity = new Entity.ScheduleAnaLog(info);
+            _dalAnaLog.Insert(entity);
+        }
+
+
+        /// <summary>
+        /// 鍒ゆ柇琛ㄦ槸鍚﹀瓨鍦�
+        /// </summary>
+        public bool ExistTable(string runFlag)
+        {
+            return _dal.ExistTable(runFlag);
+        }
+
+    }
+}
diff --git "a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0507\051.cs" "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0507\051.cs"
new file mode 100644
index 0000000..ae771ca
--- /dev/null
+++ "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0507\051.cs"
@@ -0,0 +1,512 @@
+锘縩amespace IStation.Algorithm
+{
+
+    #region ViewModel
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class FreCombine
+    {
+        public FreCombine() { }
+        public List<int> Flags { get; set; }
+        public int RunCount { get; set; }
+        public double Frequency { get; set; }
+        public double Flow { get; set; }
+        public double Power { get; set; }
+    }
+
+
+
+    /// <summary>
+    /// 鍒嗘瀽娉甸」
+    /// </summary>
+    public class OptimalCombine
+    {
+        public OptimalCombine() { }
+        public double Flow { get; set; }
+        public double Head { get; set; }
+        public double Power { get; set; }
+        public List<FreCombine> Combines { get; set; }
+        public List<int> Flags { get; set; }
+        public int FlagCount { get; set; }
+        public string Remark { get; set; }
+        public double Scale { get; set; }
+        public double OpenPumpRatio { get; set; }
+    }
+
+    #endregion
+
+    /// <summary>
+    /// 璋冨害鍒嗘瀽杈呭姪绫�
+    /// </summary>
+    public class SchedulingHelper
+    {
+        decimal _frequency_min = 25;
+        decimal _frequency_max = 50;
+        decimal _frequency_space = 0.1m;//棰戠巼闂撮殧  
+
+        double _start_stop_loss_coefficient = 0.95;//娉靛惎鍋滄崯澶辩郴鏁�
+
+
+        #region RunFlag
+        string _falgFrePumpTag = "B";
+        string _falgFixPumpTag = "G";
+        string _falgSpaceMark = "_";
+
+
+        string GetRunFlag(int[] flags)
+        {
+            var runFlag = string.Empty;
+            var index = 0;
+            var count = flags.Length;
+            foreach (var flag in flags)
+            {
+                runFlag += GetGFlag(flag);
+                index++;
+                if (index != count)
+                {
+                    runFlag += _falgSpaceMark;
+                }
+            }
+            return runFlag;
+        }
+
+        string GetRunFlag(List<int> flags)
+        {
+            var runFlag = string.Empty;
+            var index = 0;
+            var count = flags.Count;
+            foreach (var flag in flags)
+            {
+                runFlag += GetGFlag(flag);
+                index++;
+                if (index != count)
+                {
+                    runFlag += _falgSpaceMark;
+                }
+            }
+            return runFlag;
+        }
+
+        string GetGFlag(int flag)
+        {
+            return _falgFrePumpTag + flag;
+        }
+
+        #endregion
+
+        DAL.ScheduleCombine _dal = new DAL.ScheduleCombine();
+        DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion();
+        DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog();
+
+
+        private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 };
+        private List<int> _combineFlags2 = new List<int>() { 15 };
+
+        public string Ana(List<Pump> pumps, double target_flow, double target_head, List<int> current_open_pump_flags, List<int> must_open_pump_flags, List<int> must_not_open_pump_flags)
+        {
+            if (pumps == null || !pumps.Any())
+            {
+                return "鏃犳柟妗�:pumps is null";
+            }
+            target_flow = Math.Round(target_flow, 1);
+            target_head = Math.Round(target_head, 1);
+
+            var open_pump_factor = 1 / pumps.Count;
+
+            #region 瀛樺湪-褰撳墠寮�娉靛垪琛�
+
+            var exist_current_open_pump_flags = current_open_pump_flags != null && current_open_pump_flags.Count > 0;
+
+            #endregion
+
+            #region 瀛樺湪-蹇呭紑娉靛垪琛�
+
+            var must_open_pump_flags_remark = string.Empty;
+            var exist_must_open_pump_flags = must_open_pump_flags != null && must_open_pump_flags.Count > 0;
+            if (exist_must_open_pump_flags)
+            {
+                must_open_pump_flags = must_open_pump_flags.OrderBy(x => x).ToList();
+                must_open_pump_flags_remark = IntListHelper.ToString(must_open_pump_flags);
+            }
+
+            #endregion
+
+            #region 瀛樺湪-蹇呬笉鑳藉紑娉靛垪琛�
+
+            var exist_must_not_open_pump_flags = must_not_open_pump_flags != null && must_not_open_pump_flags.Count > 0;
+
+            #endregion
+
+            var pump_flag_list = pumps.Select(x => x.ID).ToList();
+            var optimal_combine_list = new List<OptimalCombine>();
+            for (int pumpCount = 1; pumpCount <= pumps.Count; pumpCount++)
+            {
+                if (pumpCount == 1)
+                {
+                    var max_total_flow = pumps.Max(x => x.Qr);
+                    if (max_total_flow < target_flow)
+                        continue;
+                }
+                var combine_list = PermutationAndCombination<int>.GetCombination(pump_flag_list.ToArray(), pumpCount);//鎺掑垪缁勫悎
+                foreach (var combine in combine_list)
+                {
+                    double combine_merit_ratio = 1;//缁勫悎鎷╀紭鐜�
+                    if (exist_must_open_pump_flags)
+                    {
+                        var combine_remark = IntListHelper.ToString(combine.OrderBy(x => x));
+                        if (!combine_remark.Contains(must_open_pump_flags_remark))
+                            continue;
+                    }
+                    if (exist_must_not_open_pump_flags)
+                    {
+                        var exist_intersected = combine.Intersect(must_not_open_pump_flags).Count() > 0;
+                        if (exist_intersected)
+                            continue;
+                    }
+                    if (exist_current_open_pump_flags)
+                    {
+                        var start_pump_count = combine.Except(current_open_pump_flags).Count();
+                        var close_pump_count = current_open_pump_flags.Except(combine).Count();
+                        var start_stop_count = start_pump_count + close_pump_count;//鍚仠鏁伴噺
+                        var total_loss_ratio = Math.Pow(_start_stop_loss_coefficient, start_stop_count);//鍚仠涓�娆℃崯澶变簺鑳借��
+                        combine_merit_ratio *= total_loss_ratio;
+                    }
+
+                    List<int> combine_flag_list_part1 = new List<int>();
+                    List<int> combine_flag_list_part2 = new List<int>();
+                    foreach (var pump in combine)
+                    {
+                        if (_combineFlags1.Contains(pump))
+                        {
+                            combine_flag_list_part1.Add(pump);
+                        }
+                        else
+                        {
+                            combine_flag_list_part2.Add(pump);
+                        }
+                    }
+
+                    //鍖哄垎鍚屽瀷鍙锋车
+                    List<FreCombine> fre_combine_list_part1 = new List<FreCombine>();
+                    List<FreCombine> fre_combine_list_part2 = new List<FreCombine>();
+
+                    if (combine_flag_list_part1.Count > 0)
+                    {
+                        var conclusion_list_dic = new Dictionary<int, List<Entity.ScheduleConclusion>>();
+                        foreach (var flag in combine_flag_list_part1)
+                        {
+                            var runFlag = GetGFlag(flag);
+                            if (conclusion_list_dic.ContainsKey(flag))
+                                continue;
+                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, target_head);
+                            conclusion_list_dic[flag] = conclusionList;
+                        }
+
+                        if (conclusion_list_dic.Count < 1)
+                        {
+                            continue;
+                        }
+
+                        for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space)
+                        {
+                            var freCombine = new FreCombine();
+                            freCombine.Frequency = (double)fre;
+                            freCombine.Flags = new List<int>();
+                            foreach (var item in conclusion_list_dic)
+                            {
+                                var conclusion = item.Value.Find(x => x.Pump1 == (double)fre);
+                                if (conclusion != null)
+                                {
+                                    freCombine.Flags.Add(item.Key);
+                                    freCombine.Flow += conclusion.Flow;
+                                    freCombine.Power += conclusion.Power;
+                                    freCombine.RunCount++;
+                                }
+                            }
+                            if (freCombine.Flags.Count < 1)
+                                continue;
+                            fre_combine_list_part1.Add(freCombine);
+                        }
+                    }
+                    if (combine_flag_list_part2.Count > 0)
+                    {
+                        var conclusion_list_dic = new Dictionary<int, List<Entity.ScheduleConclusion>>();
+                        foreach (var flag in combine_flag_list_part2)
+                        {
+                            var runFlag = GetGFlag(flag);
+                            if (conclusion_list_dic.ContainsKey(flag))
+                                continue;
+                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, target_head);
+                            conclusion_list_dic[flag] = conclusionList;
+                        }
+
+                        if (conclusion_list_dic.Count < 1)
+                        {
+                            continue;
+                        }
+
+                        for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space)
+                        {
+                            var freCombine = new FreCombine();
+                            freCombine.Frequency = (double)fre;
+                            freCombine.Flags = new List<int>();
+                            foreach (var item in conclusion_list_dic)
+                            {
+                                var conclusion = item.Value.Find(x => x.Pump1 == (double)fre);
+                                if (conclusion != null)
+                                {
+                                    freCombine.Flags.Add(item.Key);
+                                    freCombine.Flow += conclusion.Flow;
+                                    freCombine.Power += conclusion.Power;
+                                    freCombine.RunCount++;
+                                }
+                            }
+                            if (freCombine.Flags.Count < 1)
+                                continue;
+                            fre_combine_list_part2.Add(freCombine);
+                        }
+                    }
+
+                    if (fre_combine_list_part1.Count == 0 && fre_combine_list_part2.Count == 0)
+                        continue;
+
+                    double flow_deviation = target_flow;//娴侀噺鍋忓樊
+                    double total_power = double.MaxValue;//鎬诲姛鐜�
+                    double total_flow = double.MaxValue;//鎬绘祦閲�
+
+                    FreCombine optimal_combine_part1 = null;
+                    FreCombine optimal_combine_part2 = null;
+                    if (fre_combine_list_part1.Count < 1 || fre_combine_list_part2.Count < 1)
+                    {
+                        if (fre_combine_list_part1.Count < 1)
+                        {
+                            fre_combine_list_part1 = fre_combine_list_part2;
+                        }
+                        for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                        {
+                            var fre_combine1 = fre_combine_list_part1[Index_part1];
+                            var current_flow = fre_combine1.Flow;
+                            var current_power = fre_combine1.Power;
+
+                            var diff_flow = Math.Abs(current_flow - target_flow);
+                            if (diff_flow < flow_deviation)
+                            {
+                                optimal_combine_part1 = fre_combine1;
+                                total_power = fre_combine1.Power;
+                                total_flow = current_flow;
+                                flow_deviation = diff_flow;
+                            }
+
+                            if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                            {
+                                optimal_combine_part1 = fre_combine1;
+                                total_power = fre_combine1.Power;
+                                total_flow = current_flow;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                        {
+                            for (int Index_part2 = 0; Index_part2 < fre_combine_list_part2.Count; Index_part2++)
+                            {
+                                var fre_combine1 = fre_combine_list_part1[Index_part1];
+                                var fre_combine2 = fre_combine_list_part2[Index_part2];
+
+                                var current_flow = fre_combine1.Flow + fre_combine2.Flow;
+                                var current_power = fre_combine1.Power + fre_combine2.Power;
+
+                                var diff_flow = Math.Abs(current_flow - target_flow);
+                                if (diff_flow < flow_deviation)
+                                {
+                                    optimal_combine_part1 = fre_combine1;
+                                    optimal_combine_part2 = fre_combine2;
+                                    total_power = fre_combine1.Power + fre_combine2.Power;
+                                    total_flow = current_flow;
+                                    flow_deviation = diff_flow;
+                                }
+
+                                if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                                {
+                                    optimal_combine_part1 = fre_combine1;
+                                    optimal_combine_part2 = fre_combine2;
+                                    total_power = fre_combine1.Power + fre_combine2.Power;
+                                    total_flow = current_flow;
+                                }
+
+                            }
+                        }
+                    }
+
+                    if (optimal_combine_part1 == null && optimal_combine_part2 == null)
+                        return default;
+
+                    #region 鍒嗘瀽鏈�浼樼粍鍚堟柟妗�
+
+                    var optimal_combine = new OptimalCombine();
+                    optimal_combine.Combines = new List<FreCombine>();
+                    optimal_combine.Flags = new List<int>();
+                    if (optimal_combine_part1 != null)
+                    {
+                        optimal_combine.Combines.Add(optimal_combine_part1);
+                        optimal_combine.Flags.AddRange(optimal_combine_part1.Flags);
+                    }
+                    if (optimal_combine_part2 != null)
+                    {
+                        optimal_combine.Combines.Add(optimal_combine_part2);
+                        optimal_combine.Flags.AddRange(optimal_combine_part2.Flags);
+                    }
+                    optimal_combine.OpenPumpRatio = optimal_combine.Flags.Count * open_pump_factor;
+                    optimal_combine.Flow = total_flow;
+                    optimal_combine.Power = total_power;
+                    optimal_combine.Flags = optimal_combine.Flags.OrderBy(x => x).ToList();
+                    optimal_combine.FlagCount = optimal_combine.Flags.Count;
+                    optimal_combine.Remark = IntListHelper.ToString(optimal_combine.Flags);
+                    optimal_combine.Scale = combine_merit_ratio - Math.Abs((1 - Math.Abs((total_flow / target_flow))));
+
+                    //if (exist_must_open_pump_flags)
+                    //{
+                    //    var optimal_combine_flag_count = optimal_combine.FlagCount;
+                    //    var must_open_pump_flag_count = must_open_pump_flags.Count;
+
+                    //    var open_pump_excess_count = optimal_combine_flag_count - must_open_pump_flag_count;
+                    //    optimal_combine.Scale *= (1 - (open_pump_excess_count * open_pump_factor));
+                    //}
+                    optimal_combine.Head = target_head;
+                    optimal_combine_list.Add(optimal_combine);
+
+                    #endregion
+                }
+            }
+
+            if (optimal_combine_list.Count < 1)
+                return "鏃犳柟妗�";
+
+            var sb = new StringBuilder();
+            optimal_combine_list = optimal_combine_list.OrderByDescending(x => x.Scale).ToList();
+            foreach (var opt in optimal_combine_list)
+            {
+                sb.AppendLine($"Scale:{opt.Scale.ToString("N5")},Flow:{opt.Flow.ToString("N1")},Power:{opt.Power.ToString("N1")}," +
+                    $"Flags:{opt.Remark};FlowDeviation:{(opt.Flow - target_flow).ToString("N1")}");
+            }
+            return sb.ToString();
+
+        }
+
+
+        private OptimalCombine AnaOptimalCombine(double target_flow, List<FreCombine> fre_combine_list_part1, List<FreCombine> fre_combine_list_part2, List<int> must_open_pump_flags, List<int> must_not_open_pump_flags)
+        {
+            double flow_deviation = target_flow;
+            double total_power = double.MaxValue;
+            double total_flow = double.MaxValue;
+
+            FreCombine optimal_combine_part1 = null;
+            FreCombine optimal_combine_part2 = null;
+            if (fre_combine_list_part1.Count < 1 || fre_combine_list_part2.Count < 1)
+            {
+                for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                {
+                    var fre_combine1 = fre_combine_list_part1[Index_part1];
+
+                    var current_flow = fre_combine1.Flow;
+                    var current_power = fre_combine1.Power;
+
+                    var diff_flow = Math.Abs(current_flow - target_flow);
+                    if (diff_flow < flow_deviation)
+                    {
+                        optimal_combine_part1 = fre_combine1;
+                        total_power = fre_combine1.Power;
+                        total_flow = current_flow;
+                        flow_deviation = diff_flow;
+                    }
+
+                    if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                    {
+                        optimal_combine_part1 = fre_combine1;
+                        total_power = fre_combine1.Power;
+                        total_flow = current_flow;
+                    }
+                }
+            }
+            else
+            {
+                for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                {
+                    for (int Index_part2 = 0; Index_part2 < fre_combine_list_part2.Count; Index_part2++)
+                    {
+                        var fre_combine1 = fre_combine_list_part1[Index_part1];
+                        var fre_combine2 = fre_combine_list_part2[Index_part2];
+
+                        var current_flow = fre_combine1.Flow + fre_combine2.Flow;
+                        var current_power = fre_combine1.Power + fre_combine2.Power;
+
+                        var diff_flow = Math.Abs(current_flow - target_flow);
+                        if (diff_flow < flow_deviation)
+                        {
+                            optimal_combine_part1 = fre_combine1;
+                            optimal_combine_part2 = fre_combine2;
+                            total_power = fre_combine1.Power + fre_combine2.Power;
+                            total_flow = current_flow;
+                            flow_deviation = diff_flow;
+                        }
+
+                        if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                        {
+                            optimal_combine_part1 = fre_combine1;
+                            optimal_combine_part2 = fre_combine2;
+                            total_power = fre_combine1.Power + fre_combine2.Power;
+                            total_flow = current_flow;
+                        }
+
+                    }
+                }
+            }
+
+            if (optimal_combine_part1 == null && optimal_combine_part2 == null)
+                return default;
+
+            var optimal_combine = new OptimalCombine();
+            optimal_combine.Combines = new List<FreCombine>();
+            optimal_combine.Flags = new List<int>();
+            if (optimal_combine_part1 != null)
+            {
+                optimal_combine.Combines.Add(optimal_combine_part1);
+                optimal_combine.Flags.AddRange(optimal_combine_part1.Flags);
+            }
+            if (optimal_combine_part2 != null)
+            {
+                optimal_combine.Combines.Add(optimal_combine_part2);
+                optimal_combine.Flags.AddRange(optimal_combine_part2.Flags);
+            }
+
+            optimal_combine.Flow = total_flow;
+            optimal_combine.Power = total_power;
+            optimal_combine.Flags = optimal_combine.Flags.OrderBy(x => x).ToList();
+            optimal_combine.Remark = IntListHelper.ToString(optimal_combine.Flags);
+            optimal_combine.Scale = 1 * Math.Abs((total_flow / target_flow));
+            return optimal_combine;
+        }
+
+        /// <summary>
+        /// 鎻掑叆鍒嗘瀽鏃ュ織
+        /// </summary> 
+        private void InsertAnaLog(string info)
+        {
+            var entity = new Entity.ScheduleAnaLog(info);
+            _dalAnaLog.Insert(entity);
+        }
+
+
+        /// <summary>
+        /// 鍒ゆ柇琛ㄦ槸鍚﹀瓨鍦�
+        /// </summary>
+        public bool ExistTable(string runFlag)
+        {
+            return _dal.ExistTable(runFlag);
+        }
+
+    }
+}
diff --git a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs
index 0e9e97c..c3af6bc 100644
--- a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs
+++ b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs
@@ -24,11 +24,14 @@
     public class OptimalCombine
     {
         public OptimalCombine() { }
-        public List<int> Flags { get; set; }
         public double Flow { get; set; }
         public double Head { get; set; }
         public double Power { get; set; }
         public List<FreCombine> Combines { get; set; }
+        public List<int> Flags { get; set; }
+        public int FlagCount { get; set; }
+        public string Remark { get; set; }
+        public double MeritRatio { get; set; }
     }
 
     #endregion
@@ -38,12 +41,15 @@
     /// </summary>
     public class SchedulingHelper
     {
-        double _frequency_def = 50;
         decimal _frequency_min = 25;
         decimal _frequency_max = 50;
         decimal _frequency_space = 0.1m;//棰戠巼闂撮殧  
 
-        double _head_space = 0.1;//鎵▼闂撮殧
+        double _start_stop_loss_coefficient = 0.95;//娉靛惎鍋滄崯澶辩郴鏁�
+
+        double _sel_opt_flow_deviation_ratio = 0.05;//鍙�夋柟妗堢殑娴侀噺鍋忓樊姣�
+        double _sel_opt_reasonable_flow_deviation_ratio = 0.005;//鍚堢悊鐨勬柟妗堢殑娴侀噺鍋忓樊姣�
+
 
         #region RunFlag
         string _falgFrePumpTag = "B";
@@ -97,24 +103,92 @@
         DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog();
 
 
-        private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 };
-        private List<int> _combineFlags2 = new List<int>() { 15 };
+        /* private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 };
+         private List<int> _combineFlags2 = new List<int>() { 15 };*/
 
-        public void Ana(List<Pump> pumps, double taget_flow, double tagetHead)
+        public string Ana(List<Pump> pumps, List<int> flags_part1, List<int> flags_part2, double target_flow, double target_head, List<int> current_open_pump_flags, List<int> must_open_pump_flags, List<int> must_not_open_pump_flags)
         {
-            tagetHead = Math.Round(tagetHead);
+            if (pumps == null || !pumps.Any())
+            {
+                return "鏃犳柟妗�:pumps is null";
+            }
+            target_flow = Math.Round(target_flow, 1);
+            target_head = Math.Round(target_head, 1);
+
+            #region 瀛樺湪-褰撳墠寮�娉靛垪琛�
+
+            var exist_current_open_pump_flags = current_open_pump_flags != null && current_open_pump_flags.Count > 0;
+
+            #endregion
+
+            #region 瀛樺湪-蹇呭紑娉靛垪琛�
+
+            var must_open_pump_flags_remark = string.Empty;
+            var exist_must_open_pump_flags = must_open_pump_flags != null && must_open_pump_flags.Count > 0;
+            if (exist_must_open_pump_flags)
+            {
+                must_open_pump_flags = must_open_pump_flags.OrderBy(x => x).ToList();
+                must_open_pump_flags_remark = IntListHelper.ToString(must_open_pump_flags);
+            }
+
+            #endregion
+
+            #region 瀛樺湪-蹇呬笉鑳藉紑娉靛垪琛�
+
+            var exist_must_not_open_pump_flags = must_not_open_pump_flags != null && must_not_open_pump_flags.Count > 0;
+
+            #endregion
+
             var pump_flag_list = pumps.Select(x => x.ID).ToList();
+            var optimal_combine_list = new List<OptimalCombine>();
             for (int pumpCount = 1; pumpCount <= pumps.Count; pumpCount++)
             {
-                var combine_list = PermutationAndCombination<int>.GetCombination(pump_flag_list.ToArray(), pumpCount);
+                if (pumpCount == 1)
+                {
+                    var max_total_flow = pumps.Max(x => x.Qr);
+                    if (max_total_flow < target_flow)
+                        continue;
+                }
+                var combine_list = PermutationAndCombination<int>.GetCombination(pump_flag_list.ToArray(), pumpCount);//鎺掑垪缁勫悎
                 foreach (var combine in combine_list)
                 {
+                    double combine_merit_ratio = 1;//缁勫悎鎷╀紭鐜�
+                    if (exist_must_open_pump_flags)
+                    {
+                        var combine_remark = IntListHelper.ToString(combine.OrderBy(x => x));
+                        if (!combine_remark.Contains(must_open_pump_flags_remark))
+                            continue;
+                    }
+                    if (exist_must_not_open_pump_flags)
+                    {
+                        var exist_intersected = combine.Intersect(must_not_open_pump_flags).Count() > 0;
+                        if (exist_intersected)
+                            continue;
+                    }
+
+                    int start_stop_count = 0;//鍚仠鏁伴噺
+                    if (exist_current_open_pump_flags)
+                    {
+                        var start_pump_count = combine.Except(current_open_pump_flags).Count();
+                        var close_pump_count = current_open_pump_flags.Except(combine).Count();
+                        start_stop_count = start_pump_count + close_pump_count;//鍚仠鏁伴噺 
+                    }
+                    else
+                    {
+                        start_stop_count = combine.Count();
+                        if (exist_must_open_pump_flags)
+                        {
+                            start_stop_count = combine.Except(must_open_pump_flags).Count();
+                        }
+                    }
+                    var total_loss_ratio = Math.Pow(_start_stop_loss_coefficient, start_stop_count);//鍚仠涓�娆℃崯澶变簺鑳借��
+                    combine_merit_ratio *= total_loss_ratio;
+
                     List<int> combine_flag_list_part1 = new List<int>();
                     List<int> combine_flag_list_part2 = new List<int>();
-
                     foreach (var pump in combine)
                     {
-                        if (_combineFlags1.Contains(pump))
+                        if (flags_part1.Contains(pump))
                         {
                             combine_flag_list_part1.Add(pump);
                         }
@@ -124,7 +198,7 @@
                         }
                     }
 
-
+                    //鍖哄垎鍚屽瀷鍙锋车
                     List<FreCombine> fre_combine_list_part1 = new List<FreCombine>();
                     List<FreCombine> fre_combine_list_part2 = new List<FreCombine>();
 
@@ -136,7 +210,7 @@
                             var runFlag = GetGFlag(flag);
                             if (conclusion_list_dic.ContainsKey(flag))
                                 continue;
-                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, tagetHead);
+                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, target_head);
                             conclusion_list_dic[flag] = conclusionList;
                         }
 
@@ -165,12 +239,7 @@
                                 continue;
                             fre_combine_list_part1.Add(freCombine);
                         }
-
-
-
-
                     }
-
                     if (combine_flag_list_part2.Count > 0)
                     {
                         var conclusion_list_dic = new Dictionary<int, List<Entity.ScheduleConclusion>>();
@@ -179,7 +248,7 @@
                             var runFlag = GetGFlag(flag);
                             if (conclusion_list_dic.ContainsKey(flag))
                                 continue;
-                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, tagetHead);
+                            var conclusionList = _dalScheduleConclusion.GetList(runFlag, target_head);
                             conclusion_list_dic[flag] = conclusionList;
                         }
 
@@ -210,68 +279,131 @@
                         }
                     }
 
+                    if (fre_combine_list_part1.Count == 0 && fre_combine_list_part2.Count == 0)
+                        continue;
 
-                    var optimalCombine = AnaOptimalCombine(fre_combine_list_part1, fre_combine_list_part2, taget_flow);
-                }
+                    double total_flow_deviation = target_flow;//鎬绘祦閲忓亸宸�
+                    double total_power = double.MaxValue;//鎬诲姛鐜�
+                    double total_flow = double.MaxValue;//鎬绘祦閲�
 
-            }
-
-        }
-
-
-        private OptimalCombine AnaOptimalCombine(List<FreCombine> fre_combine_list_part1, List<FreCombine> fre_combine_list_part2, double target_flow)
-        {
-            double flow_deviation = target_flow;
-            double total_power = double.MaxValue;
-            double total_flow = double.MaxValue;
-
-            FreCombine optimal_combine_part1 = null;
-            FreCombine optimal_combine_part2 = null;
-            for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
-            {
-                for (int Index_part2 = 0; Index_part2 < fre_combine_list_part2.Count; Index_part2++)
-                {
-                    var fre_combine1 = fre_combine_list_part1[Index_part1];
-                    var fre_combine2 = fre_combine_list_part2[Index_part2];
-
-                    var current_flow = fre_combine1.Flow + fre_combine2.Flow;
-                    var current_power = fre_combine1.Power + fre_combine2.Power;
-
-                    var diff_flow = Math.Abs(current_flow - target_flow);
-                    if (diff_flow < flow_deviation)
+                    FreCombine optimal_combine_part1 = null;
+                    FreCombine optimal_combine_part2 = null;
+                    if (fre_combine_list_part1.Count < 1 || fre_combine_list_part2.Count < 1)
                     {
-                        optimal_combine_part1 = fre_combine1;
-                        optimal_combine_part2 = fre_combine2;
-                        total_power = fre_combine1.Power + fre_combine2.Power;
-                        total_flow = current_flow;
-                        flow_deviation = diff_flow;
+                        if (fre_combine_list_part1.Count < 1)
+                        {
+                            fre_combine_list_part1 = fre_combine_list_part2;
+                        }
+                        for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                        {
+                            var fre_combine1 = fre_combine_list_part1[Index_part1];
+                            var current_flow = fre_combine1.Flow;
+                            var current_power = fre_combine1.Power;
+
+                            var diff_flow = Math.Abs(current_flow - target_flow);
+                            if (diff_flow < total_flow_deviation)
+                            {
+                                optimal_combine_part1 = fre_combine1;
+                                total_power = fre_combine1.Power;
+                                total_flow = current_flow;
+                                total_flow_deviation = diff_flow;
+                            }
+
+                            if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                            {
+                                optimal_combine_part1 = fre_combine1;
+                                total_power = fre_combine1.Power;
+                                total_flow = current_flow;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
+                        {
+                            for (int Index_part2 = 0; Index_part2 < fre_combine_list_part2.Count; Index_part2++)
+                            {
+                                var fre_combine1 = fre_combine_list_part1[Index_part1];
+                                var fre_combine2 = fre_combine_list_part2[Index_part2];
+
+                                var current_flow = fre_combine1.Flow + fre_combine2.Flow;
+                                var current_power = fre_combine1.Power + fre_combine2.Power;
+
+                                var diff_flow = Math.Abs(current_flow - target_flow);
+                                if (diff_flow < total_flow_deviation)
+                                {
+                                    optimal_combine_part1 = fre_combine1;
+                                    optimal_combine_part2 = fre_combine2;
+                                    total_power = fre_combine1.Power + fre_combine2.Power;
+                                    total_flow = current_flow;
+                                    total_flow_deviation = diff_flow;
+                                }
+
+                                if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                                {
+                                    optimal_combine_part1 = fre_combine1;
+                                    optimal_combine_part2 = fre_combine2;
+                                    total_power = fre_combine1.Power + fre_combine2.Power;
+                                    total_flow = current_flow;
+                                }
+
+                            }
+                        }
                     }
 
-                    if (diff_flow < target_flow * 0.01 && current_power < total_power)
+                    if (optimal_combine_part1 == null && optimal_combine_part2 == null)
+                        continue;
+
+                    var total_flow_deviation_ratio = Math.Abs((1 - Math.Abs((total_flow / target_flow))));
+                    if (total_flow_deviation_ratio > _sel_opt_flow_deviation_ratio)
+                        continue;
+                    if (total_flow_deviation_ratio > _sel_opt_reasonable_flow_deviation_ratio)
                     {
-                        optimal_combine_part1 = fre_combine1;
-                        optimal_combine_part2 = fre_combine2;
-                        total_power = fre_combine1.Power + fre_combine2.Power;
-                        total_flow = current_flow;
+                        combine_merit_ratio -= total_flow_deviation_ratio;
                     }
 
+
+                    #region 鍒嗘瀽鏈�浼樼粍鍚堟柟妗�
+
+                    var optimal_combine = new OptimalCombine();
+                    optimal_combine.Combines = new List<FreCombine>();
+                    optimal_combine.Flags = new List<int>();
+                    if (optimal_combine_part1 != null)
+                    {
+                        optimal_combine.Combines.Add(optimal_combine_part1);
+                        optimal_combine.Flags.AddRange(optimal_combine_part1.Flags);
+                    }
+                    if (optimal_combine_part2 != null)
+                    {
+                        optimal_combine.Combines.Add(optimal_combine_part2);
+                        optimal_combine.Flags.AddRange(optimal_combine_part2.Flags);
+                    }
+                    optimal_combine.Flow = total_flow;
+                    optimal_combine.Power = total_power;
+                    optimal_combine.Flags = optimal_combine.Flags.OrderBy(x => x).ToList();
+                    optimal_combine.FlagCount = optimal_combine.Flags.Count;
+                    optimal_combine.Remark = IntListHelper.ToString(optimal_combine.Flags);
+
+                    optimal_combine.MeritRatio = combine_merit_ratio;
+                    optimal_combine.Head = target_head;
+                    optimal_combine_list.Add(optimal_combine);
+
+                    #endregion
                 }
             }
-            if (optimal_combine_part1 == null && optimal_combine_part2 == null)
-                return default;
-            var optimal_combine = new OptimalCombine();
-            optimal_combine.Combines = new List<FreCombine>();
-            if (optimal_combine_part1 != null)
+
+            if (optimal_combine_list.Count < 1)
+                return "鏃犳柟妗�";
+
+            var sb = new StringBuilder();
+            optimal_combine_list = optimal_combine_list.OrderByDescending(x => x.MeritRatio).ToList();
+            foreach (var opt in optimal_combine_list)
             {
-                optimal_combine.Combines.Add(optimal_combine_part1);
+                sb.AppendLine($"MeritRatio:{opt.MeritRatio.ToString("N5")},Flow:{opt.Flow.ToString("N1")},Power:{opt.Power.ToString("N1")}," +
+                    $"Flags:{opt.Remark};FlowDeviation:{(opt.Flow - target_flow).ToString("N1")}");
             }
-            if (optimal_combine_part2 != null)
-            {
-                optimal_combine.Combines.Add(optimal_combine_part2);
-            }
-            optimal_combine.Flow = total_flow;
-            optimal_combine.Power = total_power;
-            return optimal_combine;
+            return sb.ToString();
+
         }
 
         /// <summary>
diff --git a/Schedule/IStation.Client/Form1.Designer.cs b/Schedule/IStation.Client/Form1.Designer.cs
index 589fd7a..a8adc26 100644
--- a/Schedule/IStation.Client/Form1.Designer.cs
+++ b/Schedule/IStation.Client/Form1.Designer.cs
@@ -29,42 +29,52 @@
         private void InitializeComponent()
         {
             btnAnaCh1Combine = new Button();
-            richTextBox1 = new RichTextBox();
+            txtInfo = new RichTextBox();
             btnAnaChConclusion = new Button();
             tableLayoutPanel1 = new TableLayoutPanel();
-            btnAnaCh2Combine = new Button();
             tableLayoutPanel2 = new TableLayoutPanel();
             txtFlow = new TextBox();
             txtHead = new TextBox();
             btnAna = new Button();
-            txtOpenCombineList = new RichTextBox();
+            splitContainer1 = new SplitContainer();
+            btnAnaCh2Combine = new Button();
+            tableLayoutPanel3 = new TableLayoutPanel();
+            txtMustOpen = new RichTextBox();
+            txtMustNotOpen = new RichTextBox();
+            txtCurrentOpen = new RichTextBox();
+            cmbStation = new ComboBox();
             tableLayoutPanel1.SuspendLayout();
             tableLayoutPanel2.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
+            splitContainer1.Panel1.SuspendLayout();
+            splitContainer1.Panel2.SuspendLayout();
+            splitContainer1.SuspendLayout();
+            tableLayoutPanel3.SuspendLayout();
             SuspendLayout();
             // 
             // btnAnaCh1Combine
             // 
             btnAnaCh1Combine.Dock = DockStyle.Fill;
-            btnAnaCh1Combine.Location = new Point(3, 3);
+            btnAnaCh1Combine.Location = new Point(0, 0);
             btnAnaCh1Combine.Name = "btnAnaCh1Combine";
-            btnAnaCh1Combine.Size = new Size(512, 104);
+            btnAnaCh1Combine.Size = new Size(257, 104);
             btnAnaCh1Combine.TabIndex = 0;
             btnAnaCh1Combine.Text = "鍒嗘瀽1杈撴按娉电粍鍚�";
             btnAnaCh1Combine.UseVisualStyleBackColor = true;
             btnAnaCh1Combine.Click += btnAnaCh1Combine_Click;
             // 
-            // richTextBox1
+            // txtInfo
             // 
-            richTextBox1.Dock = DockStyle.Bottom;
-            richTextBox1.Location = new Point(0, 221);
-            richTextBox1.Name = "richTextBox1";
-            richTextBox1.Size = new Size(1036, 416);
-            richTextBox1.TabIndex = 1;
-            richTextBox1.Text = "";
+            txtInfo.Dock = DockStyle.Bottom;
+            txtInfo.Location = new Point(0, 221);
+            txtInfo.Name = "txtInfo";
+            txtInfo.Size = new Size(1036, 416);
+            txtInfo.TabIndex = 1;
+            txtInfo.Text = "";
             // 
             // btnAnaChConclusion
             // 
-            btnAnaChConclusion.Location = new Point(3, 113);
+            btnAnaChConclusion.Location = new Point(521, 3);
             btnAnaChConclusion.Name = "btnAnaChConclusion";
             btnAnaChConclusion.Size = new Size(512, 104);
             btnAnaChConclusion.TabIndex = 2;
@@ -77,10 +87,10 @@
             tableLayoutPanel1.ColumnCount = 2;
             tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
             tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
-            tableLayoutPanel1.Controls.Add(btnAnaCh1Combine, 0, 0);
-            tableLayoutPanel1.Controls.Add(btnAnaChConclusion, 0, 1);
-            tableLayoutPanel1.Controls.Add(btnAnaCh2Combine, 1, 0);
             tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 1, 1);
+            tableLayoutPanel1.Controls.Add(splitContainer1, 0, 0);
+            tableLayoutPanel1.Controls.Add(btnAnaChConclusion, 1, 0);
+            tableLayoutPanel1.Controls.Add(tableLayoutPanel3, 0, 1);
             tableLayoutPanel1.Dock = DockStyle.Fill;
             tableLayoutPanel1.Location = new Point(0, 0);
             tableLayoutPanel1.Name = "tableLayoutPanel1";
@@ -90,16 +100,6 @@
             tableLayoutPanel1.Size = new Size(1036, 221);
             tableLayoutPanel1.TabIndex = 3;
             // 
-            // btnAnaCh2Combine
-            // 
-            btnAnaCh2Combine.Location = new Point(521, 3);
-            btnAnaCh2Combine.Name = "btnAnaCh2Combine";
-            btnAnaCh2Combine.Size = new Size(512, 104);
-            btnAnaCh2Combine.TabIndex = 3;
-            btnAnaCh2Combine.Text = "鍒嗘瀽2杈撴按娉电粍鍚�";
-            btnAnaCh2Combine.UseVisualStyleBackColor = true;
-            btnAnaCh2Combine.Click += btnAnaCh2Combine_Click;
-            // 
             // tableLayoutPanel2
             // 
             tableLayoutPanel2.ColumnCount = 2;
@@ -107,14 +107,14 @@
             tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
             tableLayoutPanel2.Controls.Add(txtFlow, 0, 0);
             tableLayoutPanel2.Controls.Add(txtHead, 1, 0);
-            tableLayoutPanel2.Controls.Add(btnAna, 1, 1);
-            tableLayoutPanel2.Controls.Add(txtOpenCombineList, 0, 1);
+            tableLayoutPanel2.Controls.Add(btnAna, 0, 1);
             tableLayoutPanel2.Dock = DockStyle.Fill;
             tableLayoutPanel2.Location = new Point(521, 113);
             tableLayoutPanel2.Name = "tableLayoutPanel2";
             tableLayoutPanel2.RowCount = 2;
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 34.2857132F));
             tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 65.71429F));
+            tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
             tableLayoutPanel2.Size = new Size(512, 105);
             tableLayoutPanel2.TabIndex = 4;
             // 
@@ -138,23 +138,98 @@
             // 
             // btnAna
             // 
+            tableLayoutPanel2.SetColumnSpan(btnAna, 2);
             btnAna.Dock = DockStyle.Fill;
-            btnAna.Location = new Point(259, 39);
+            btnAna.Location = new Point(3, 39);
             btnAna.Name = "btnAna";
-            btnAna.Size = new Size(250, 63);
+            btnAna.Size = new Size(506, 63);
             btnAna.TabIndex = 3;
             btnAna.Text = "鍒嗘瀽";
             btnAna.UseVisualStyleBackColor = true;
             btnAna.Click += btnAna_Click;
             // 
-            // txtOpenCombineList
+            // splitContainer1
             // 
-            txtOpenCombineList.Dock = DockStyle.Fill;
-            txtOpenCombineList.Location = new Point(3, 39);
-            txtOpenCombineList.Name = "txtOpenCombineList";
-            txtOpenCombineList.Size = new Size(250, 63);
-            txtOpenCombineList.TabIndex = 4;
-            txtOpenCombineList.Text = "11,12,13,17";
+            splitContainer1.Dock = DockStyle.Fill;
+            splitContainer1.Location = new Point(3, 3);
+            splitContainer1.Name = "splitContainer1";
+            // 
+            // splitContainer1.Panel1
+            // 
+            splitContainer1.Panel1.Controls.Add(btnAnaCh1Combine);
+            // 
+            // splitContainer1.Panel2
+            // 
+            splitContainer1.Panel2.Controls.Add(btnAnaCh2Combine);
+            splitContainer1.Size = new Size(512, 104);
+            splitContainer1.SplitterDistance = 257;
+            splitContainer1.TabIndex = 5;
+            // 
+            // btnAnaCh2Combine
+            // 
+            btnAnaCh2Combine.Dock = DockStyle.Fill;
+            btnAnaCh2Combine.Location = new Point(0, 0);
+            btnAnaCh2Combine.Name = "btnAnaCh2Combine";
+            btnAnaCh2Combine.Size = new Size(251, 104);
+            btnAnaCh2Combine.TabIndex = 3;
+            btnAnaCh2Combine.Text = "鍒嗘瀽2杈撴按娉电粍鍚�";
+            btnAnaCh2Combine.UseVisualStyleBackColor = true;
+            btnAnaCh2Combine.Click += btnAnaCh2Combine_Click;
+            // 
+            // tableLayoutPanel3
+            // 
+            tableLayoutPanel3.ColumnCount = 2;
+            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
+            tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
+            tableLayoutPanel3.Controls.Add(txtMustOpen, 0, 0);
+            tableLayoutPanel3.Controls.Add(txtMustNotOpen, 1, 0);
+            tableLayoutPanel3.Controls.Add(txtCurrentOpen, 0, 1);
+            tableLayoutPanel3.Controls.Add(cmbStation, 1, 1);
+            tableLayoutPanel3.Dock = DockStyle.Fill;
+            tableLayoutPanel3.Location = new Point(3, 113);
+            tableLayoutPanel3.Name = "tableLayoutPanel3";
+            tableLayoutPanel3.RowCount = 2;
+            tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
+            tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
+            tableLayoutPanel3.Size = new Size(512, 105);
+            tableLayoutPanel3.TabIndex = 6;
+            // 
+            // txtMustOpen
+            // 
+            txtMustOpen.Dock = DockStyle.Fill;
+            txtMustOpen.Location = new Point(3, 3);
+            txtMustOpen.Name = "txtMustOpen";
+            txtMustOpen.Size = new Size(250, 46);
+            txtMustOpen.TabIndex = 5;
+            txtMustOpen.Text = "";
+            // 
+            // txtMustNotOpen
+            // 
+            txtMustNotOpen.Dock = DockStyle.Fill;
+            txtMustNotOpen.Location = new Point(259, 3);
+            txtMustNotOpen.Name = "txtMustNotOpen";
+            txtMustNotOpen.Size = new Size(250, 46);
+            txtMustNotOpen.TabIndex = 6;
+            txtMustNotOpen.Text = "";
+            // 
+            // txtCurrentOpen
+            // 
+            txtCurrentOpen.Location = new Point(3, 55);
+            txtCurrentOpen.Name = "txtCurrentOpen";
+            txtCurrentOpen.Size = new Size(250, 47);
+            txtCurrentOpen.TabIndex = 4;
+            txtCurrentOpen.Text = "11,12,13,17";
+            // 
+            // cmbStation
+            // 
+            cmbStation.Dock = DockStyle.Fill;
+            cmbStation.FormattingEnabled = true;
+            cmbStation.Items.AddRange(new object[] { "涓�杈撴按", "浜岃緭姘�" });
+            cmbStation.Location = new Point(259, 55);
+            cmbStation.Name = "cmbStation";
+            cmbStation.Size = new Size(250, 32);
+            cmbStation.TabIndex = 7;
+            cmbStation.SelectedIndexChanged += cmbStation_SelectedIndexChanged;
             // 
             // Form1
             // 
@@ -162,20 +237,25 @@
             AutoScaleMode = AutoScaleMode.Font;
             ClientSize = new Size(1036, 637);
             Controls.Add(tableLayoutPanel1);
-            Controls.Add(richTextBox1);
+            Controls.Add(txtInfo);
             Name = "Form1";
             StartPosition = FormStartPosition.CenterScreen;
             Text = "Form1";
             tableLayoutPanel1.ResumeLayout(false);
             tableLayoutPanel2.ResumeLayout(false);
             tableLayoutPanel2.PerformLayout();
+            splitContainer1.Panel1.ResumeLayout(false);
+            splitContainer1.Panel2.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
+            splitContainer1.ResumeLayout(false);
+            tableLayoutPanel3.ResumeLayout(false);
             ResumeLayout(false);
         }
 
         #endregion
 
         private Button btnAnaCh1Combine;
-        private RichTextBox richTextBox1;
+        private RichTextBox txtInfo;
         private Button btnAnaChConclusion;
         private TableLayoutPanel tableLayoutPanel1;
         private Button btnAnaCh2Combine;
@@ -183,6 +263,11 @@
         private TextBox txtFlow;
         private TextBox txtHead;
         private Button btnAna;
-        private RichTextBox txtOpenCombineList;
+        private RichTextBox txtCurrentOpen;
+        private SplitContainer splitContainer1;
+        private TableLayoutPanel tableLayoutPanel3;
+        private RichTextBox txtMustOpen;
+        private RichTextBox txtMustNotOpen;
+        private ComboBox cmbStation;
     }
 }
\ No newline at end of file
diff --git a/Schedule/IStation.Client/Form1.cs b/Schedule/IStation.Client/Form1.cs
index ddd2388..c3aea03 100644
--- a/Schedule/IStation.Client/Form1.cs
+++ b/Schedule/IStation.Client/Form1.cs
@@ -10,13 +10,33 @@
             {
                 System.Diagnostics.Process.GetCurrentProcess().Kill();
             };
+            this.cmbStation.SelectedIndex = 0;
         }
 
+        int _stationIndex = 0;
         string _floder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data");
+
+        private void cmbStation_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            _stationIndex = cmbStation.SelectedIndex;
+            if (_stationIndex == 0)
+            {
+                this.txtFlow.Text = "16406";
+                this.txtHead.Text = "15.92";
+                this.txtCurrentOpen.Text = "11,12,13,17";
+            }
+            else
+            {
+                this.txtFlow.Text = "39,460";
+                this.txtHead.Text = "19.65";
+                this.txtCurrentOpen.Text = "22,23,25,26";
+            }
+
+        }
 
         private void btnAnaCombine_Click(object sender, EventArgs e)
         {
-            this.richTextBox1.Text += "\r\n正在分析泵组合";
+            this.txtInfo.Text += "\r\n正在分析泵组合";
             var ch1 = _floder + "\\" + "陈行一输.json";
             var ch1_json = File.ReadAllText(ch1);
             var ch1Pumps = JsonHelper.Json2Object<List<Model.Pump>>(ch1_json);
@@ -31,31 +51,27 @@
                 helper.AnaCombine(ch1Pumps);
                 this.Invoke(() =>
                 {
-                    this.richTextBox1.Text += "\r\n分析泵组合完毕";
+                    this.txtInfo.Text += "\r\n分析泵组合完毕";
                 });
             });
         }
-
-
-
 
         private void btnAnaCh1Combine_Click(object sender, EventArgs e)
         {
             var ch1 = _floder + "\\" + "陈行一输.json";
             var ch1_json = File.ReadAllText(ch1);
             var ch1Pumps = JsonHelper.Json2Object<List<Model.Pump>>(ch1_json);
-            this.richTextBox1.Text += "\r\n正在分析1输水泵组合";
+            this.txtInfo.Text += "\r\n正在分析1输水泵组合";
             Task.Run(() =>
             {
                 var helper = new Algorithm.SchedulingAnaHelper();
                 helper.AnaCombine(ch1Pumps);
                 this.Invoke(() =>
                 {
-                    this.richTextBox1.Text += "\r\n分析1输水泵组合完毕";
+                    this.txtInfo.Text += "\r\n分析1输水泵组合完毕";
                 });
             });
         }
-
 
         private void btnAnaCh2Combine_Click(object sender, EventArgs e)
         {
@@ -63,35 +79,35 @@
             var ch2_json = File.ReadAllText(ch2);
             var ch2Pumps = JsonHelper.Json2Object<List<Model.Pump>>(ch2_json);
 
-            this.richTextBox1.Text += "\r\n正在分析2输水泵组合";
+            this.txtInfo.Text += "\r\n正在分析2输水泵组合";
             Task.Run(() =>
             {
                 var helper = new Algorithm.SchedulingAnaHelper();
                 helper.AnaCombine(ch2Pumps);
                 this.Invoke(() =>
                 {
-                    this.richTextBox1.Text += "\r\n分析2输水泵组合完毕";
+                    this.txtInfo.Text += "\r\n分析2输水泵组合完毕";
                 });
             });
         }
 
-
         private void btnAnaChConclusion_Click(object sender, EventArgs e)
         {
-            this.richTextBox1.Text += "\r\n正在分析全部泵组合结论";
+            this.txtInfo.Text += "\r\n正在分析全部泵组合结论";
             Task.Run(() =>
             {
                 var helper = new Algorithm.SchedulingAnaHelper();
                 helper.AnaConclusion();
                 this.Invoke(() =>
                 {
-                    this.richTextBox1.Text += "\r\n全部泵组合分析完毕";
+                    this.txtInfo.Text += "\r\n全部泵组合分析完毕";
                 });
             });
         }
 
         private void btnAna_Click(object sender, EventArgs e)
         {
+            this.txtInfo.Text = string.Empty;
             if (!double.TryParse(this.txtFlow.Text, out double targetFlow))
             {
                 MessageBox.Show("请输入流量!");
@@ -102,24 +118,69 @@
                 MessageBox.Show("请输入压力!");
                 return;
             }
-            var combine = this.txtOpenCombineList.Text.Trim();
-            if (string.IsNullOrEmpty(combine))
+            List<int> current_open_pump_list = new List<int>();
+            List<int> must_open_pump_list = new List<int>();
+            List<int> must_not_open_pump_list = new List<int>();
+
+            var current_open_pump_list_txt = this.txtCurrentOpen.Text.Trim();
+            if (!string.IsNullOrEmpty(current_open_pump_list_txt))
             {
-                MessageBox.Show("请输入泵组合!");
-                return;
+                current_open_pump_list = IntListHelper.ToList(current_open_pump_list_txt);
+                if (current_open_pump_list == null || current_open_pump_list.Count < 1)
+                {
+                    MessageBox.Show("请输入有效泵组合!\r\n','号间隔!");
+                    return;
+                }
             }
-            var combineList = IntListHelper.ToList(combine);
-            if (combineList == null || combineList.Count < 1)
+
+            var must_open_pump_list_txt = this.txtMustOpen.Text.Trim();
+            if (!string.IsNullOrEmpty(must_open_pump_list_txt))
             {
-                MessageBox.Show("请输入有效泵组合!\r\n','号间隔!");
-                return;
+                must_open_pump_list = IntListHelper.ToList(must_open_pump_list_txt);
+                if (must_open_pump_list == null || must_open_pump_list.Count < 1)
+                {
+                    MessageBox.Show("请输入有效泵组合!\r\n','号间隔!");
+                    return;
+                }
             }
-            var ch1 = _floder + "\\" + "陈行一输.json";
-            var ch1_json = File.ReadAllText(ch1);
-            var ch1Pumps = JsonHelper.Json2Object<List<Model.Pump>>(ch1_json);
+
+            var must_not_open_pump_list_txt = this.txtMustNotOpen.Text.Trim();
+            if (!string.IsNullOrEmpty(must_not_open_pump_list_txt))
+            {
+                must_not_open_pump_list = IntListHelper.ToList(must_not_open_pump_list_txt);
+                if (must_not_open_pump_list == null || must_not_open_pump_list.Count < 1)
+                {
+                    MessageBox.Show("请输入有效泵组合!\r\n','号间隔!");
+                    return;
+                }
+            }
+
+            List<Model.Pump> pumps;
+            List<int> flags_part1, flags_part2;
+            if (_stationIndex == 0)
+            {
+                var filePath = _floder + "\\" + "陈行一输.json";
+                var jsonInfo = File.ReadAllText(filePath);
+                pumps = JsonHelper.Json2Object<List<Model.Pump>>(jsonInfo);
+
+                flags_part1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 };
+                flags_part2 = new List<int>() { 15 };
+            }
+            else
+            {
+                var filePath = _floder + "\\" + "陈行二输.json";
+                var jsonInfo = File.ReadAllText(filePath);
+                pumps = JsonHelper.Json2Object<List<Model.Pump>>(jsonInfo);
+
+                flags_part1 = new List<int>() { 22, 23, 24, 25, 26 };
+                flags_part2 = new List<int>() { 21, 27 };
+            }
 
             var helper = new Algorithm.SchedulingHelper();
-            helper.Ana(ch1Pumps, targetFlow, targetHead);
+            var info = helper.Ana(pumps, flags_part1, flags_part2, targetFlow, targetHead, current_open_pump_list, must_open_pump_list, must_not_open_pump_list);
+
+            this.txtInfo.Text = info;
         }
+
     }
 }
\ No newline at end of file

--
Gitblit v1.9.3