/// <summary> /// 総当りで外部結合を試みる /// </summary> /// <param name="target">総当りしてみるリスト。shortageでもsequentiallyでも可</param> /// <param name="shortage">欠けがあるリストを保持するリスト</param> /// <param name="sequentially">欠けがない(以下同文</param> public static void ComplementShortage(List <List <AddrPort> > target, List <List <AddrPort> > shortage, List <List <AddrPort> > sequentially) { if (target.Count <= 1) { return; } start: for (int i = 0; i < target.Count; i++) { for (int j = i + 1; j < target.Count; j++) { var a = target[i]; var b = target[j]; var ret = ProviderAddrPortResolver.OuterJoin(a, b); if (ret.Count() > 0) { if (ret.Contains(null)) { shortage.Add(ret.ToList()); } else { sequentially.Add(ret.ToList()); } target.Remove(a); target.Remove(b); //リストに対して追加したり削除したりと荒らすから処理を継続すると問題が起こりかねない。 //ちょっと無駄が多いけどしょうがないから最初からやり直す。 goto start; } } } }
/// <summary> /// /// </summary> /// <param name="circle"></param> /// <param name="parts"></param> /// <returns></returns> public static CircleAndNotResolved <IEnumerable <IEnumerable <AddrPort> > > Concat(Elem <AddrPort> circle, IEnumerable <IEnumerable <AddrPort> > parts) { var ret0 = circle; var list = parts.ToList(); int before; int after; //listの要素数が変わらなくなるまでひたすら繰り返す。 do { var tmp = new List <IEnumerable <AddrPort> >(); before = list.Count(); for (int i = 0; i < list.Count; i++) { var arr = list[i]; var ret = ProviderAddrPortResolver.Concat(ret0, arr); if (ret.NotResolved.Count() != 0) { tmp.Add(ret.NotResolved); } ret0 = ret.Circle; } list = tmp; after = list.Count(); } while (before != after); return(new CircleAndNotResolved <IEnumerable <IEnumerable <AddrPort> > >(ret0, list)); }
public Task <Elem <AddrPort> > CreateCircle(CancellationToken ct) { return(Task.Factory.StartNew(() => { var circle = ProviderAddrPortResolver.CreateEmptyCircle(); do { var liveContextList = new List <LiveContext>(); var dicList = Settings.Instance.LiveInfoDic.ToList(); for (int i = 0; i < dicList.Count; i++) { liveContextList.Add(dicList[i].Value); } foreach (var liveContext in liveContextList) { var listlist = liveContext.ToList(); foreach (var m in listlist) { if (m.Count == 0) { continue; } if (m.Count == 1) { Settings.Instance.One.Add(m); } else if (m.Where(s => s == null).Count() > 0) { Settings.Instance.Shortage.Add(m); } else { Settings.Instance.Sequentially.Add(m); } } } ProviderAddrPortResolver.Distinct(Settings.Instance.Shortage); ProviderAddrPortResolver.ComplementShortage(Settings.Instance.Shortage, Settings.Instance.Shortage, Settings.Instance.Sequentially); ProviderAddrPortResolver.ComplementShortage(Settings.Instance.Sequentially, Settings.Instance.Shortage, Settings.Instance.Sequentially); //ひと通り済んだら var c = ProviderAddrPortResolver.Concat(circle, Settings.Instance.Shortage); var k = ProviderAddrPortResolver.Concat(circle, Settings.Instance.Sequentially); //面倒だから全部Shortageに入れちゃう。重複もなんのその。 Settings.Instance.Shortage.AddRange(c.NotResolved.Select(b => b.ToList())); Settings.Instance.Shortage.AddRange(k.NotResolved.Select(b => b.ToList())); Console.WriteLine($"circle.count={circle.Count}"); } while (!ProviderAddrPortResolver.IsCompleted(circle)); return circle; }, ct)); }