• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision7a41749a49ff6a165011c5d3a73203b3a07be29c (tree)
Time2015-07-07 22:14:58
Authorkomutan <t_komuta@nift...>
Commiterkomutan

Log Message

PriorityQueueをPairringHeapで実装。キューとしての順序を確保。

Change Summary

Incremental Difference

--- a/src/LibNMeCab/Core/PriorityQueue.cs
+++ b/src/LibNMeCab/Core/PriorityQueue.cs
@@ -7,77 +7,78 @@ namespace NMeCab.Core
77 public class PriorityQueue<T>
88 where T : IComparable<T>
99 {
10- private readonly List<T> heapList = new List<T>();
11-
12- public int Count
10+ private class Node
1311 {
14- get { return this.heapList.Count; }
12+ public T Value;
13+
14+ public LinkedList<Node> Childs = new LinkedList<Node>();
15+
16+ public Node(T value)
17+ {
18+ this.Value = value;
19+ }
1520 }
1621
22+ private Node rootNode = null;
23+
24+ public int Count { get; private set; }
25+
26+ public T First { get { return this.rootNode.Value; } }
27+
1728 public void Clear()
1829 {
19- this.heapList.Clear();
30+ this.rootNode = null;
31+ this.Count = 0;
32+ }
33+
34+ public void RemoveFirst()
35+ {
36+ this.rootNode = this.Unify(this.rootNode.Childs);
37+ this.Count--;
2038 }
2139
2240 public void Push(T item)
2341 {
24- if (item == null) throw new ArgumentNullException("item");
42+ this.rootNode = this.Merge(this.rootNode, new Node(item));
43+ this.Count++;
44+ }
2545
26- //up heap
27- int currentPos = this.heapList.Count; //tail
28- this.heapList.Add(default(T));
29- while (currentPos != 0)
30- {
31- int parentPos = (currentPos - 1) / 2;
32- T parent = this.heapList[parentPos];
46+ public T Pop()
47+ {
48+ T ret = this.First;
49+ this.RemoveFirst();
50+ return ret;
51+ }
3352
34- if (parent.CompareTo(item) <= 0) break;
53+ private Node Merge(Node l, Node r)
54+ {
55+ if (l == null) return r;
56+ if (r == null) return l;
3557
36- this.heapList[currentPos] = parent; //down
37- currentPos = parentPos;
58+ if (l.Value.CompareTo(r.Value) > 0)
59+ {
60+ r.Childs.AddFirst(l);
61+ return r;
62+ }
63+ else
64+ {
65+ l.Childs.AddLast(r);
66+ return l;
3867 }
39- this.heapList[currentPos] = item; //commit
4068 }
4169
42- public T Pop()
70+ private Node Unify(LinkedList<Node> nodes)
4371 {
44- if (this.heapList.Count == 0) throw new InvalidOperationException("Empty");
72+ if (nodes == null || nodes.Count == 0) return null;
4573
46- T root = this.heapList[0];
74+ Node x = nodes.First.Value;
75+ nodes.RemoveFirst();
76+ if (nodes.Count == 0) return x;
4777
48- int tailPos = this.heapList.Count - 1;
49- if (tailPos != 0)
50- {
51- //down heap
52- T tail = this.heapList[tailPos];
53- int currentPos = 0;
54- while (true)
55- {
56- int childPos = currentPos * 2 + 1; //left child
57- if (childPos >= tailPos) break;
58- T child = this.heapList[childPos];
59-
60- int rChiledPos = childPos + 1; //right child
61- if (rChiledPos < tailPos)
62- {
63- T rChiled = this.heapList[rChiledPos];
64- if (child.CompareTo(rChiled) > 0)
65- {
66- child = rChiled;
67- childPos = rChiledPos;
68- }
69- }
70-
71- if (tail.CompareTo(child) < 0) break;
72-
73- this.heapList[currentPos] = child; //up
74- currentPos = childPos;
75- }
76- this.heapList[currentPos] = tail; //commit
77- }
78- this.heapList.RemoveAt(tailPos);
78+ Node y = nodes.First.Value;
79+ nodes.RemoveFirst();
7980
80- return root;
81+ return this.Merge(this.Merge(x, y), this.Unify(nodes));
8182 }
8283 }
8384 }
--- a/src/LibNMeCabTest/LibNMeCabTest.csproj
+++ b/src/LibNMeCabTest/LibNMeCabTest.csproj
@@ -57,9 +57,9 @@
5757 <Compile Include="Properties\AssemblyInfo.cs" />
5858 </ItemGroup>
5959 <ItemGroup>
60- <ProjectReference Include="..\LibNMeCab35\LibNMeCab35.csproj">
61- <Project>{4ffe4221-2f41-446e-be59-d9cfcdf91ac6}</Project>
62- <Name>LibNMeCab35</Name>
60+ <ProjectReference Include="..\LibNMeCab40MMF\LibNMeCab40MMF.csproj">
61+ <Project>{86711194-4c2b-4853-830f-07c57f035283}</Project>
62+ <Name>LibNMeCab40MMF</Name>
6363 </ProjectReference>
6464 </ItemGroup>
6565 <Choose>
--- a/src/LibNMeCabTest/PriorityQueueTest.cs
+++ b/src/LibNMeCabTest/PriorityQueueTest.cs
@@ -1,92 +1,159 @@
11 using System;
22 using Microsoft.VisualStudio.TestTools.UnitTesting;
3+using System.Collections.Generic;
4+using System.Linq;
5+using System.Diagnostics;
36
47 namespace LibNMeCabTest
58 {
9+ public class Element : IComparable<Element>
10+ {
11+ public int Priority { get; set; }
12+
13+ public int Order { get; set; }
14+
15+ public int CompareTo(Element other)
16+ {
17+ return this.Priority.CompareTo(other.Priority);
18+ }
19+
20+ public override int GetHashCode()
21+ {
22+ return this.Priority;
23+ }
24+
25+ public override bool Equals(object obj)
26+ {
27+ var other = obj as Element;
28+ return other != null
29+ && this.Priority == other.Priority
30+ && this.Order == other.Order;
31+ }
32+
33+ public override string ToString()
34+ {
35+ return "priority:" + this.Priority + " order:" + this.Order;
36+ }
37+ }
38+
639 [TestClass]
740 public class PriorityQueueTest
841 {
942 [TestMethod]
1043 public void TestMethod1()
1144 {
12- var target = new NMeCab.Core.PriorityQueue<int>();
45+ var queue = new NMeCab.Core.PriorityQueue<Element>();
46+ var collection = new List<Element>();
1347 var count = 0;
1448
15- for (int i = 0; i < 10; i++)
49+ for (int i = 0; i < 2; i++)
1650 {
17- for (int j = 0; j < 10; j++)
51+ //追加 優先度昇順
52+ for (int j = 0; j < 3; j++)
1853 {
19- target.Push(j);
54+ var item = new Element { Priority = j, Order = count };
55+ queue.Push(item);
56+ collection.Add(item);
2057 count++;
21- Assert.AreEqual(target.Count, count);
58+ Assert.AreEqual(queue.Count, count);
2259 }
2360 }
2461
25- int wrk1 = 0;
26- for (int k = 0; k < count; k++)
62+ //並べ直し
63+ collection = (from e in collection
64+ orderby e.Priority, e.Order
65+ select e).ToList();
66+
67+ //取り出し
68+ foreach (var expected in collection)
2769 {
28- int wrk2 = target.Pop();
70+ var actual = queue.Pop();
2971 count--;
30- Assert.AreEqual(target.Count, count);
31- Assert.IsTrue(wrk1 <= wrk2);
32- wrk1 = wrk2;
72+
73+ Assert.AreEqual(expected, actual);
74+ Assert.AreEqual(count, queue.Count);
3375 }
3476 }
3577
3678 [TestMethod]
3779 public void TestMethod2()
3880 {
39- var target = new NMeCab.Core.PriorityQueue<int>();
81+ var queue = new NMeCab.Core.PriorityQueue<Element>();
82+ var collection = new List<Element>();
4083 var count = 0;
4184
42- for (int i = 0; i < 10; i++)
85+ for (int i = 0; i < 2; i++)
4386 {
44- for (int j = 10; j >= 0; j--)
87+ //追加 優先度降順
88+ for (int j = 3; j >= 0; j--)
4589 {
46- target.Push(j);
90+ var item = new Element { Priority = j, Order = count };
91+ queue.Push(item);
92+ collection.Add(item);
4793 count++;
48- Assert.AreEqual(target.Count, count);
94+
95+ Assert.AreEqual(count, queue.Count);
4996 }
5097 }
5198
52- int wrk1 = 0;
53- for (int k = 0; k < count; k++)
99+ //並べ直し
100+ collection = (from e in collection
101+ orderby e.Priority, e.Order
102+ select e).ToList();
103+
104+ //取り出し
105+ foreach (var expected in collection)
54106 {
55- int wrk2 = target.Pop();
107+ var actual = queue.Pop();
56108 count--;
57- Assert.AreEqual(target.Count, count);
58- Assert.IsTrue(wrk1 <= wrk2);
59- wrk1 = wrk2;
109+
110+ Assert.AreEqual(expected, actual);
111+ Assert.AreEqual(count, queue.Count);
60112 }
61113 }
62114
63115 [TestMethod]
64116 public void TestMethod3()
65117 {
66- var target = new NMeCab.Core.PriorityQueue<int>();
118+ var queue = new NMeCab.Core.PriorityQueue<Element>();
119+ var collection = new List<Element>();
120+ var order = 0;
67121 var count = 0;
68122 var rnd = new Random();
69123
124+ //追加と取り出しを一定数繰り返す
70125 for (int i = 0; i < 1000; i++)
71126 {
127+ //ランダム優先度でランダム個追加
72128 int repeat = rnd.Next(10);
73129 for (int j = 0; j < repeat; j++)
74130 {
75- target.Push(rnd.Next(10));
131+ var item = new Element { Priority = rnd.Next(10), Order = order };
132+ collection.Add(item);
133+ queue.Push(item);
134+ order++;
76135 count++;
77- Assert.AreEqual(target.Count, count);
136+
137+ Assert.AreEqual(count, queue.Count);
78138 }
79139
80- repeat = rnd.Next(target.Count);
81- int wrk1 = 0;
82- for (int k = 0; k < repeat; k++)
140+ //並べ直し
141+ collection = (from e in collection
142+ orderby e.Priority, e.Order
143+ select e).ToList();
144+
145+ //ランダム個取り出し
146+ repeat = rnd.Next(collection.Count);
147+ for (int j = 0; j < repeat; j++)
83148 {
84- int wrk2 = target.Pop();
149+ var actual = queue.Pop();
150+ var expected = collection[j];
85151 count--;
86- Assert.AreEqual(target.Count, count);
87- Assert.IsTrue(wrk1 <= wrk2);
88- wrk1 = wrk2;
152+
153+ Assert.AreEqual(expected, actual);
154+ Assert.AreEqual(count, queue.Count);
89155 }
156+ collection.RemoveRange(0, repeat);
90157 }
91158 }
92159 }