public WellLabelingSolver(StructurePosition mainStruct,//тот блок, который обязательно должен получить пару IReadOnlyList <StructurePosition> structNearNode, IReadOnlyList <TextPosition> lblsNearNode) { this.mainStruct = mainStruct; //Формирование списков приоритетных соотношений //между блоками колодцев и подписями блоков foreach (StructurePosition str in structNearNode) { StructurePositionWrapper spw = new StructurePositionWrapper(str); spws.Add(str, spw); foreach (TextPosition txt in lblsNearNode) { Relation relation = new Relation(str, txt); spw.RelationsPriority.Add(relation); TextPositionWrapper txtWr = null; txtwrs.TryGetValue(txt, out txtWr); if (txtWr == null) { txtWr = new TextPositionWrapper(txt); txtwrs[txt] = txtWr; } txtWr.RelationsPriority.Add(relation); } spw.RelationsPriority.Sort(); } foreach (KeyValuePair <TextPosition, TextPositionWrapper> kvp in txtwrs) { kvp.Value.RelationsPriority.Sort(); } //Определить количество наиболее вероятных конкурирующих вариантов //Если обнаружено, что 1 текстовая метка является ближайшей к двум колодцам, //то у этих колодцев количество конкурирующих вариантов подписей +1 //Для текстовой метки количество конкурирующих вариантов равно количеству колодцев, //для которых она является ближайшей Dictionary <TextPosition, HashSet <StructurePositionWrapper> > txtPossibleOwners = new Dictionary <TextPosition, HashSet <StructurePositionWrapper> >(); foreach (StructurePositionWrapper spw in spws.Values) { foreach (Relation relation in spw.RelationsPriority) { //принимать как конкурирующие все тексты на определеннном расстоянии, //но не менее 1 if (relation.Distance > WELL_LBL_COMPATITORS_DISTANCE && spw.CompCount > 0) { break; } spw.CompCount++; TextPosition txtKey = relation.TextPosition; HashSet <StructurePositionWrapper> possibleOwners = null; txtPossibleOwners.TryGetValue(txtKey, out possibleOwners); bool hasCompatitors = possibleOwners != null; if (!hasCompatitors) { possibleOwners = new HashSet <StructurePositionWrapper>(); txtPossibleOwners.Add(txtKey, possibleOwners); } if (!possibleOwners.Contains(spw)) { possibleOwners.Add(spw); } if (hasCompatitors) { txtwrs[txtKey].CompCount = possibleOwners.Count; foreach (StructurePositionWrapper comp in possibleOwners) { comp.CompCount++; } } } } //Поиск перебором сопоставления пар колодец-текстовая метка, //которое дает наименьшее суммарное расстояние от текста до колодца if (lblsNearNode.Count > 0 && structNearNode.Count > 0) { if (lblsNearNode.Count >= structNearNode.Count) { List <ISolverWrapper> structTxtSearchSeq = spws.Values.Cast <ISolverWrapper>().ToList(); structTxtSearchSeq.Sort(); //invalidCombinationResults = 0; BruteForceSearch(structTxtSearchSeq, 0, new HashSet <StructurePosition>(), new HashSet <TextPosition>(), new Dictionary <StructurePosition, TextPosition>(), 0); } else { List <ISolverWrapper> txtStructSearchSeq = txtwrs.Values.Cast <ISolverWrapper>().ToList(); txtStructSearchSeq.Sort(); //invalidCombinationResults = 0; BruteForceSearch(txtStructSearchSeq, 0, new HashSet <StructurePosition>(), new HashSet <TextPosition>(), new Dictionary <StructurePosition, TextPosition>(), 0); } } }
public PipeJunctionLabelingSolver2(NetworkNode nn, List <TextPosition> lblsNearNN) { this.nn = nn; this.lblsNearNN = new List <TextPosition>(lblsNearNN); //Формирование списков приоритетных соотношений //между присоединениями к колодцу и подписями присоединений foreach (NetworkEdge ne in nn.AttachedEdges) { bool start = ne.StartNode == nn; NetworkEdgeWrapper newr = new NetworkEdgeWrapper(ne, start); newrs.Add(ne, newr); foreach (TextPosition txt in lblsNearNN) { Relation relation = new Relation(ne, start, txt); newr.RelationsPriority.Add(relation); TextPositionWrapper txtWr = null; txtwrs.TryGetValue(txt, out txtWr); if (txtWr == null) { txtWr = new TextPositionWrapper(txt); txtwrs[txt] = txtWr; } txtWr.RelationsPriority.Add(relation); } newr.RelationsPriority.Sort(); } foreach (KeyValuePair <TextPosition, TextPositionWrapper> kvp in txtwrs) { kvp.Value.RelationsPriority.Sort(); } //Определить количество наиболее вероятных конкурирующих вариантов //Если обнаружено, что 1 текстовая метка является ближайшей к двум присоединениям, //то у этих присоединений количество конкурирующих вариантов подписей +1 //Для текстовой метки количество конкурирующих вариантов равно количеству присоединений, //для которых она является ближайшей Dictionary <TextPosition, HashSet <NetworkEdgeWrapper> > txtPossibleOwners = new Dictionary <TextPosition, HashSet <NetworkEdgeWrapper> >(); foreach (NetworkEdgeWrapper newr in newrs.Values) { //NetworkEdge edge = newr.NetworkEdge; // foreach (Relation relation in newr.RelationsPriority) { //принимать как конкурирующие все тексты на определеннном расстоянии, //но не менее 1 if (relation.Distance > JUNCTION_LBL_COMPATITORS_DISTANCE && newr.CompCount > 0) { break; } newr.CompCount++; TextPosition txtKey = relation.TextPosition; HashSet <NetworkEdgeWrapper> possibleOwners = null; txtPossibleOwners.TryGetValue(txtKey, out possibleOwners); bool hasCompatitors = possibleOwners != null; if (!hasCompatitors) { possibleOwners = new HashSet <NetworkEdgeWrapper>(); txtPossibleOwners.Add(txtKey, possibleOwners); } if (!possibleOwners.Contains(newr)) { possibleOwners.Add(newr); } if (hasCompatitors) { txtwrs[txtKey].CompCount = possibleOwners.Count; foreach (NetworkEdgeWrapper comp in possibleOwners) { comp.CompCount++; } } } } //Поиск перебором сопоставления пар присоединение-текстовая метка, //которое дает наименьшее суммарное расстояние от текста до присоединения if (lblsNearNN.Count >= nn.AttachedEdges.Count)//зависит от того, чего больше: подписей или присоединений { List <ISolverWrapper> edgeTxtSearchSeq = newrs.Values.Cast <ISolverWrapper>().ToList(); edgeTxtSearchSeq.Sort(); invalidNumberCombinationResults = 0; BruteForceSearch(edgeTxtSearchSeq, 0, new HashSet <NetworkEdge>(), new HashSet <TextPosition>(), new HashSet <int>(), new Dictionary <NetworkEdge, TextPosition>(), 0); } else { List <ISolverWrapper> txtEdgeSearchSeq = txtwrs.Values.Cast <ISolverWrapper>().ToList(); txtEdgeSearchSeq.Sort(); invalidNumberCombinationResults = 0; BruteForceSearch(txtEdgeSearchSeq, 0, new HashSet <NetworkEdge>(), new HashSet <TextPosition>(), new HashSet <int>(), new Dictionary <NetworkEdge, TextPosition>(), 0); } }