public async Task <Responce> GlobalTestGraphAsync([FromBody] InputGraph input)
        {
            var converted = await GraphToMatrixAsync(input);

            return(await Task.Run(() =>
            {
                try
                {
                    // Проверка аргумента на null
                    _ = input ?? throw new ArgumentNullException(nameof(input));

                    // Значение глобального теста
                    IBalanceSolver solver = new AccordBalanceSolver();
                    var output = solver.GlobalTest(converted.X0, converted.A, converted.Measurability,
                                                   converted.Tolerance);

                    return new Responce
                    {
                        Type = "result",
                        Data = output
                    };
                }
                catch (Exception e)
                {
                    return new Responce
                    {
                        Type = "error",
                        Data = e.Message
                    };
                }
            }));
        }
Beispiel #2
0
        public async Task <Responce> PostGenerateAsync([FromQuery] int nodesCount, [FromQuery] int flowsCount,
                                                       [FromQuery] double min = -100, [FromQuery] double max = 100)
        {
            return(await Task.Run(() =>
            {
                var rand = new Random();

                var nodes = new List <string>();
                for (var i = 0; i < nodesCount; i++)
                {
                    nodes.Add(Guid.NewGuid().ToString());
                }

                var result = new InputGraph
                {
                    BalanceSettings = new BalanceSettings(),
                    Dependencies = null,
                    Variables = new List <Variable>()
                };

                for (var i = 0; i < flowsCount; i++)
                {
                    var destination = rand.Next(-1, nodesCount);
                    var source = rand.Next(-1, nodesCount);

                    var variable = new Variable
                    {
                        Id = Guid.NewGuid().ToString(),
                        Name = $"Variable {i}",
                        DestinationId = destination != -1 ? nodes[destination] : null,
                        SourceId = source != -1 ? nodes[source] : null,
                        Measured = min + rand.NextDouble() * (max - min),
                        Tolerance = (min + rand.NextDouble() * (max - min)) / 10.0,
                        MetrologicRange = new Models.Range
                        {
                            Min = min + rand.NextDouble() * (max - min) / 2.0,
                            Max = max - rand.NextDouble() * (max - min) / 2.0,
                        },
                        TechnologicRange = new Models.Range
                        {
                            Min = min + rand.NextDouble() * (max - min) / 2.0,
                            Max = max - rand.NextDouble() * (max - min) / 2.0,
                        },
                        IsMeasured = true,
                        InService = true,
                        VarType = "FLOW"
                    };

                    result.Variables.Add(variable);
                }

                return new Responce
                {
                    Type = "result",
                    Data = result
                };
            }));
        }
        /*
         *
         *
         */

        public override int MaxCut()
        {
            var currentCut = 0;
            var set        = new Set <int>();

            var setPrime = new Set <int>(Enumerable.Range(0, InputGraph.N));

            var any = true;

            while (any)
            {
                any = false;

                foreach (var v in setPrime)
                {
                    var candidateCut = InputGraph.CutSize(set + v, setPrime - v);

                    if (candidateCut <= currentCut)
                    {
                        continue;
                    }

                    currentCut = candidateCut;
                    set.Add(setPrime.Remove(v));
                    any = true;
                    break;
                }

                if (any)
                {
                    continue;
                }
                foreach (var v in set)
                {
                    var candidateCut = InputGraph.CutSize(set - v, setPrime + v);

                    if (candidateCut <= currentCut)
                    {
                        continue;
                    }

                    currentCut = candidateCut;
                    setPrime.Add(set.Remove(v));
                    any = true;
                    break;
                }
            }

            OutputSet = set;
            CutSize   = currentCut;
            return(currentCut);
        }
 private static InputGraphModel MakeInputGraphModel(
     string graphId,
     InputGraph graph,
     string proxiedUri)
 {
     return(new InputGraphModel(
                graphId,
                graph.Title,
                graph.SubTitle,
                proxiedUri,
                "/REST/getData",
                graph.Median,
                graph.Dispersion,
                graph.Skew));
 }
        public async Task <Responce> PostGraphAsync([FromBody] InputGraph input)
        {
            var converted = await GraphToMatrixAsync(input);

            return(await Task.Run(() =>
            {
                try
                {
                    // Проверка аргумента на null
                    _ = input ?? throw new ArgumentNullException(nameof(input));

                    // Решение задачи
                    IBalanceSolver solver = new AccordBalanceSolver();

                    var output = new OutputData
                    {
                        X = solver.Solve(converted.X0, converted.A, converted.B, converted.Measurability,
                                         converted.Tolerance,
                                         converted.UseTechnologic
                                ? converted.LowerTechnologic
                                : converted.LowerMetrologic,
                                         converted.UseTechnologic
                                ? converted.UpperTechnologic
                                : converted.UpperMetrologic),
                        DisbalanceOriginal = solver.DisbalanceOriginal,
                        Disbalance = solver.Disbalance,
                        Time = solver.TimeAll.TotalSeconds,
                        TimeMatrix = solver.Time.TotalSeconds
                    };

                    return new Responce
                    {
                        Type = "result",
                        Data = output
                    };
                }
                catch (Exception e)
                {
                    return new Responce
                    {
                        Type = "error",
                        Data = e.Message
                    };
                }
            }));
        }
Beispiel #6
0
        public override int MaxCut()
        {
            // Thread.Sleep(InputGraph.N*2);
            //throw new NotImplementedException();
            //return Utility.Random(0, InputGraph.N);

            //brute force instead of branch and bound cause I dont know how:

            var       optimalCut = 0;
            Set <int> optimalSet = null;

            //var setPrime = new Set<int>();

            var set = new Set <int>(Enumerable.Range(0, InputGraph.N));

            for (var removeIndicesCount = 1; removeIndicesCount < InputGraph.N; removeIndicesCount++)
            {
                var possibleSets = set.Combinations(removeIndicesCount); //takes most time

                foreach (var possibleSet in possibleSets)
                {
                    var currentSetPrime = new Set <int>(possibleSet);
                    var currentSet      = new Set <int>(Enumerable.Range(0, InputGraph.N).Except(currentSetPrime));
                    var currentCut      = InputGraph.CutSize(currentSet, currentSetPrime);

                    if (currentCut > optimalCut)
                    {
                        optimalCut = currentCut;
                        optimalSet = currentSet;
                    }
                }
            }


            OutputSet = optimalSet;
            CutSize   = optimalCut;
            return(optimalCut);
        }
Beispiel #7
0
        /// <summary>
        /// Преобразование графа к матричному виду
        /// </summary>
        /// <param name="graph">Граф</param>
        public static async Task <InputData> GraphToMatrixAsync(InputGraph graph)
        {
            return(await Task.Run(() =>
            {
                //Заполняем список узлов
                var nodes = new List <string>();
                foreach (var variable in graph.Variables)
                {
                    if ((variable.DestinationId != null) && (!nodes.Contains(variable.DestinationId)))
                    {
                        nodes.Add(variable.DestinationId);
                    }

                    if ((variable.SourceId != null) && (!nodes.Contains(variable.SourceId)))
                    {
                        nodes.Add(variable.SourceId);
                    }
                }

                var inputData = new InputData
                {
                    X0 = new double[graph.Variables.Count],
                    A = new double[nodes.Count, graph.Variables.Count],
                    B = new double[nodes.Count],
                    Measurability = new double[graph.Variables.Count],
                    Tolerance = new double[graph.Variables.Count],
                    LowerMetrologic = new double[graph.Variables.Count],
                    UpperMetrologic = new double[graph.Variables.Count],
                    LowerTechnologic = new double[graph.Variables.Count],
                    UpperTechnologic = new double[graph.Variables.Count],
                    Names = new string[graph.Variables.Count],
                    Guids = new string[graph.Variables.Count],
                    NodesGuids = nodes.ToArray(),
                    UseTechnologic = graph.BalanceSettings.BoundsType != "METROLOGY_ONLY"
                };

                for (var i = 0; i < graph.Variables.Count; i++)
                {
                    //X0
                    inputData.X0[i] = graph.Variables[i].Measured;

                    //Names
                    inputData.Names[i] = graph.Variables[i].Name;

                    //Guids
                    inputData.Guids[i] = graph.Variables[i].Id;

                    //A
                    if (graph.Variables[i].DestinationId != null)
                    {
                        inputData.A[nodes.IndexOf(graph.Variables[i].DestinationId), i] = 1;
                    }

                    if (graph.Variables[i].SourceId != null)
                    {
                        inputData.A[nodes.IndexOf(graph.Variables[i].SourceId), i] = -1;
                    }

                    //Measurability
                    inputData.Measurability[i] = graph.Variables[i].IsMeasured ? 1 : 0;

                    //Tolerance
                    inputData.Tolerance[i] = Math.Abs(graph.Variables[i].Tolerance) > 0.000000001 ? graph.Variables[i].Tolerance : 0.000000001;

                    //LowerMetrologic
                    inputData.LowerMetrologic[i] = graph.Variables[i].MetrologicRange.Min;

                    //UpperMetrologic
                    inputData.UpperMetrologic[i] = graph.Variables[i].MetrologicRange.Max;

                    //LowerTechnologic
                    inputData.LowerTechnologic[i] = graph.Variables[i].TechnologicRange.Min;

                    //UpperTechnologic
                    inputData.UpperTechnologic[i] = graph.Variables[i].TechnologicRange.Max;
                }

                return inputData;
            }));
        }
Beispiel #8
0
        public async Task <Responce> PostGraphAsync([FromBody] InputGraph input)
        {
            var converted = await GraphHelpers.GraphToMatrixAsync(input);

            return(await PostAsync(converted));
        }
Beispiel #9
0
 public async Task <Responce> GlrTestBestGraphAsync([FromBody] InputGraph input)
 {
     return(await GlrTestGraphAsync(input, 1));
 }
Beispiel #10
0
        public async Task <Responce> GlrTestGraphAsync([FromBody] InputGraph input, int maxSubNodesCount = 3, int maxTreeDepth = 5)
        {
            var converted = await GraphHelpers.GraphToMatrixAsync(input);

            return(await GlrTestAsync(converted, maxSubNodesCount, maxTreeDepth));
        }
        public async Task <Responce> GlrTestBestGraphAsync([FromBody] InputGraph input)
        {
            var converted = await GraphToMatrixAsync(input);

            return(await Task.Run(() =>
            {
                try
                {
                    // Проверка аргумента на null
                    _ = converted ?? throw new ArgumentNullException(nameof(converted));

                    IBalanceSolver solver = new AccordBalanceSolver();

                    var flows = solver.GetFlows(converted.A).ToList();

                    var globalTest = solver.GlobalTest(converted.X0, converted.A, converted.Measurability,
                                                       converted.Tolerance);

                    var nodesCount = converted.A.GetLength(0);
                    var glr = solver.GlrTest(converted.X0, converted.A, converted.Measurability,
                                             converted.Tolerance, flows, globalTest);

                    var results = new List <GlrOutputFlow>();

                    while (globalTest >= 1)
                    {
                        // Находим максимальное значение GLR теста в массиве
                        var(i, j) = glr.ArgMax();

                        // Если у нас не осталось значений больше нуля, то выходим
                        if (glr[i, j] <= 0)
                        {
                            break;
                        }

                        // Добавляем новый поток
                        var aColumn = new double[nodesCount];
                        aColumn[i] = 1;
                        aColumn[j] = -1;

                        converted.A = converted.A.InsertColumn(aColumn);
                        converted.X0 = converted.X0.Append(0).ToArray();
                        converted.Measurability = converted.Measurability.Append(0).ToArray();
                        converted.Tolerance = converted.Tolerance.Append(0).ToArray();

                        var newFlow = new GlrOutputFlow
                        {
                            Id = Guid.NewGuid().ToString(),
                            Name = "New flow",
                            Number = converted.A.Length - 1,
                            Info = $"{i} -> {j}"
                        };

                        // Если у нас есть существующий поток, то выводим информацию о нем
                        var existingFlowIdx = flows.FindIndex(x => x.Item1 == i && x.Item2 == j);
                        if (existingFlowIdx != -1)
                        {
                            var(_, _, existingFlow) = flows[existingFlowIdx];

                            newFlow.Id = converted.Guids[existingFlow];
                            newFlow.Name = converted.Names[existingFlow];
                            newFlow.Number = existingFlow;
                        }

                        results.Add(newFlow);

                        // Считаем новое значение глобального теста
                        globalTest = solver.GlobalTest(converted.X0, converted.A, converted.Measurability,
                                                       converted.Tolerance);

                        // Считаем новое значение GLR теста
                        glr = solver.GlrTest(converted.X0, converted.A, converted.Measurability,
                                             converted.Tolerance, flows, globalTest);
                    }

                    return new Responce
                    {
                        Type = "result",
                        Data = results
                    };
                }
                catch (Exception e)
                {
                    return new Responce
                    {
                        Type = "error",
                        Data = e.Message
                    };
                }
            }));
        }
        public async Task <Responce> GlrTestGraphAsync([FromBody] InputGraph input)
        {
            var converted = await GraphToMatrixAsync(input);

            return(await Task.Run(() =>
            {
                try
                {
                    _ = converted ?? throw new ArgumentNullException(nameof(converted));

                    IBalanceSolver solver = new AccordBalanceSolver();

                    const int maxSubNodesCount = 3;
                    const int maxTreeDepth = 5;

                    var flows = solver.GetFlows(converted.A).ToList();
                    var nodesCount = converted.A.GetLength(0);

                    var root = new MutableEntityTreeNode <Guid, TreeElement>(x => x.Id, new TreeElement());
                    var currentNode = root;

                    while (currentNode != null)
                    {
                        var newA = converted.A;
                        var newX0 = converted.X0;
                        var newMeasurability = converted.Measurability;
                        var newTolerance = converted.Tolerance;

                        foreach (var(fi, fj) in currentNode.Item.Flows)
                        {
                            var aColumn = new double[nodesCount];
                            aColumn[fi] = 1;
                            aColumn[fj] = -1;

                            newA = newA.InsertColumn(aColumn);
                            newX0 = newX0.Append(0).ToArray();
                            newMeasurability = newMeasurability.Append(0).ToArray();
                            newTolerance = newTolerance.Append(0).ToArray();
                        }

                        var globalTest = solver.GlobalTest(newX0, newA, newMeasurability,
                                                           newTolerance);

                        var glr = solver.GlrTest(newX0, newA, newMeasurability,
                                                 newTolerance, flows, globalTest);

                        // Поиск следующего максимума
                        var(i, j) = (0, 0);
                        for (var k = 0; k < currentNode.Children.Count + 1; k++)
                        {
                            (i, j) = glr.ArgMax();

                            if (glr[i, j] <= 0)
                            {
                                break;
                            }

                            // Если итерация не последняя, сбрасываем значение
                            if (k != currentNode.Children.Count)
                            {
                                glr[i, j] = 0.0;
                            }
                        }

                        // Проверяем можно ли добавить дочерний узел в дерево
                        if (currentNode.Children.Count < maxSubNodesCount &&
                            currentNode.Level < maxTreeDepth && glr[i, j] > 0 && globalTest >= 1)
                        {
                            var node = new TreeElement(new List <(int, int)>(currentNode.Item.Flows), globalTest - glr[i, j]);
                            node.Flows.Add((i, j));

                            currentNode = currentNode.AddChild(node);
                        }
                        else
                        {
                            currentNode = currentNode.Parent;
                        }
                    }

                    //Находим все листья и выводим их
                    var leafs = root.Where(x => x.IsLeaf);
                    var results = new List <GlrOutput>();

                    foreach (var leaf in leafs)
                    {
                        var result = new List <GlrOutputFlow>();
                        var flowsToAdd = new List <Variable>();

                        foreach (var flow in leaf.Item.Flows)
                        {
                            var(i, j) = flow;

                            var newFlow = new GlrOutputFlow
                            {
                                Id = Guid.NewGuid().ToString(),
                                Name = "New flow",
                                Number = -1,
                                Info = $"{i} -> {j}"
                            };

                            // Если у нас есть существующий поток, то выводим информацию о нем
                            var existingFlowIdx = flows.FindIndex(x => x.Item1 == i && x.Item2 == j);
                            if (existingFlowIdx != -1)
                            {
                                var(_, _, existingFlow) = flows[existingFlowIdx];

                                newFlow.Id = converted.Guids[existingFlow];
                                newFlow.Name = converted.Names[existingFlow];
                                newFlow.Number = existingFlow;

                                // Формируем информацию о добавляемом потоке
                                var variable = new Variable
                                {
                                    Id = Guid.NewGuid().ToString(),
                                    SourceId = converted.NodesGuids[i],
                                    DestinationId = converted.NodesGuids[j],
                                    Name = converted.Names[existingFlow] + " (additional)",
                                    MetrologicRange = new Models.Range
                                    {
                                        Min = converted.LowerMetrologic[existingFlow] - converted.X0[existingFlow],
                                        Max = converted.UpperMetrologic[existingFlow] - converted.X0[existingFlow]
                                    },
                                    TechnologicRange = new Models.Range
                                    {
                                        Min = converted.LowerTechnologic[existingFlow] - converted.X0[existingFlow],
                                        Max = converted.UpperTechnologic[existingFlow] - converted.X0[existingFlow]
                                    },
                                    Tolerance = converted.Tolerance[existingFlow],
                                    IsMeasured = true,
                                    VarType = "FLOW"
                                };

                                flowsToAdd.Add(variable);
                            }

                            result.Add(newFlow);
                        }

                        results.Add(new GlrOutput
                        {
                            FlowsInfo = result,
                            FlowsToAdd = flowsToAdd,
                            TestValue = leaf.Item.TestValue
                        });
                    }

                    return new Responce
                    {
                        Type = "result",
                        Data = results.OrderBy(x => x.TestValue)
                    };
                }
                catch (Exception e)
                {
                    return new Responce
                    {
                        Type = "error",
                        Data = e.Message
                    };
                }
            }));
        }