//YHB: this method find the graph G_plus by deleting given edge-e, its end vertices and edges associated with the end vertices
        private static BipartiteGraph BuildGplus(BipartiteGraph G, Edge e)
        {
            BipartiteGraph Gplus = G.Clone();

            Gplus.Remove(e.FromNode.Value);
            Gplus.Remove(e.ToNode.Value);
            return(Gplus);
        }
Exemple #2
0
        private static BipartiteGraph G_plus_e(BipartiteGraph G, Edge e)
        {//YHB: this method find the graph G_plus by deleting given edge-e, its end vertices and edges associated with the end vertices
            BipartiteGraph G_plus = G;

            foreach (GraphNode item in G.Nodes)
            {
            }

            G_plus.Remove(e.FromNode.Value);
            G_plus.Remove(e.ToNode.Value);

            return(G_plus);
        }
Exemple #3
0
        private static (MatchingDictionary completeMatching, MaximumMatchings2 matches) FindAllMatches(List <Data> inputs, List <Data> allData, List <WorkflowComponent> workflowComponents)
        {
            var inputsHash  = new HashSet <string>(inputs.Select(d => d.Id));
            var outputsHash = new HashSet <string>();

            // 1.0. Check for non-reversible variables that are either only input or output
            var nonReversibleData = allData.Where(d => !(d is DoubleData)).ToList();
            Dictionary <string, IOStatus> nonReversibleStatus = workflowComponents.GetDataStatus(nonReversibleData);

            //var collisionDictionary = new Dictionary<string, char>();
            //foreach (var component in workflowComponents)
            //{
            //	foreach (var input in component.ModelDataInputs)
            //	{
            //		if (!(input is DoubleData))
            //		{
            //			string inName = input.Id;
            //			if (collisionDictionary.ContainsKey(inName))
            //				collisionDictionary[inName] = 'b';
            //			else
            //				collisionDictionary[inName] = 'i';
            //		}
            //	}

            //	foreach (var output in component.ModelDataOutputs)
            //	{
            //		if (!(output is DoubleData))
            //		{
            //			string outName = output.Id;
            //			if (collisionDictionary.ContainsKey(outName))
            //				collisionDictionary[outName] = 'b';
            //			else
            //				collisionDictionary[outName] = 'o';
            //		}
            //	}
            //}

            foreach (string data in nonReversibleStatus.Keys)
            {
                if (nonReversibleStatus[data] == IOStatus.Input)
                {
                    inputsHash.Add(data);
                }
                else if (nonReversibleStatus[data] == IOStatus.Output)
                {
                    outputsHash.Add(data);
                }
            }


            var bipartite = new BipartiteGraph();

            Primes.Reset();
            var outputsDict = new MatchingDictionary(workflowComponents.Select(c => c.Id));

            // 1.1 Add Nodes for the Variables
            // Filter-out the selected inputs and outputs, as they don't belong to the bipartite graph
            foreach (Data data in allData.Where(d => !inputsHash.Contains(d.Id) && !outputsHash.Contains(d.Id)))
            {
                bipartite.AddNode(data.Id, GraphNode.Type.Type1);
            }

            // 1.2 Add Nodes for the Models, and edges between Variables and Nodes
            foreach (WorkflowComponent component in workflowComponents)
            {
                int uniqueNonReversibleOutputs = 0;

                outputsDict.Add(component.Id, new HashSet <string>());

                bipartite.AddNode(CS(component.Id), GraphNode.Type.Type2);
                GraphNode modelNode = bipartite.GetNode(CS(component.Id));

                // Filter-out the selected inputs, as they don't belong to the bipartite graph
                foreach (Data data in component.ModelDataInputs.Where(d => !inputsHash.Contains(d.Id)))
                {
                    if (outputsHash.Contains(data.Id))
                    {
                        // Shouldn't arrive here
                        uniqueNonReversibleOutputs++;
                        outputsDict[component.Id].Add(data.Id);
                    }
                    else
                    {
                        bipartite.AddDirectedEdge(data.Id, modelNode, Primes.Next(), 1);
                    }
                }

                // Filter-out the selected inputs, as they don't belong to the bipartite graph
                foreach (Data data in component.ModelDataOutputs.Where(d => !inputsHash.Contains(d.Id)))
                {
                    if (outputsHash.Contains(data.Id))
                    {
                        uniqueNonReversibleOutputs++;
                        outputsDict[component.Id].Add(data.Id);
                    }
                    else
                    {
                        bipartite.AddDirectedEdge(data.Id, modelNode, Primes.Next(), 0);
                    }
                }
                // How many output the model need
                if (component.ModelDataOutputs.Count - uniqueNonReversibleOutputs > 1)
                {
                    bipartite.modelAndItsOutputs.Add(CS(component.Id), component.ModelDataOutputs.Count - uniqueNonReversibleOutputs);                     //signle output models are not stored
                }
                else if (component.ModelDataOutputs.Count - uniqueNonReversibleOutputs == 0)
                {
                    bipartite.Remove(CS(component.Id));
                }
            }

            // 1.3 Associate matchings to each model, maping models to set of outputs
            var matches = new MaximumMatchings2(bipartite, getAllMatchings: true);

            return(outputsDict, matches);
        }