**الگوریتم استینهوس-جانسون-تروتر** (به انگلیسی: Steinhaus–Johnson–Trotter algorithm) الگوریتمی برای یافتن یک شیوه از قرار دادن {\displaystyle n!} جایگشت به طول n پشت سر یکدیگر است به طوری که هر جایگشت در این ترتیب با جابجا کردن دو عنصر مجاور در جایگشت قبلی‌اش به دست می‌آید.  

نام این الگوریتم بر اساس نام سه دانشمند  هوگو استینهوس، سلمر مارتین جانسون و هیل‌فریمن تروتر بوده‌است که تقریباً در زمانی نزدیک و به صورت مجزا از هم به این الگوریتم رسیده بودند.

این الگوریتم برای ساختن ترتیبی از جایگشت‌ها در قرن ۱۷ام شناخته شد و
رابرت سجدویک
نیز به سرعت و سادگی این الگوریتم اشاره کرده‌است.

دیدگاه از منظر گراف‌ها
----------------------

مسیری همیلتونی در این گراف که الگوریتم فوق تولید می‌کند  

ابن مسئله معادل یافتن یک مسیر هامیلتونی در یک گراف است.  
گراف را به این شکل می‌سازیم که برای هر یک از {\displaystyle n!} جایگشت موجود یک راس قرار دهیم و سپس بین دو راس یال می‌گذاریم اگر با **یک‌بار** جابجا کردن دو عنصر مجاور بتوانیم یکی را به دیگری تبدیل کنیم، به این گراف، **گراف جایگشت‌ها** می‌گویند.
  

مثلاً برای {\displaystyle n=4}، جایگشت {\displaystyle <1,2,3,4>} به {\displaystyle <1,3,2,4>} یال دارد ولی به
{\displaystyle <3,2,1,4>} یال ندارد.
  

اکنون اگر بتوانیم مسیری هامیلتونی در این گراف بیابیم، در این صورت ترتیب پیمایش گراف، همان تعریف مطلوب است. الگوریتم مورد بحث نیز یک مسیر معتبر ارائه می‌دهد.

شیوه استقرایی در یافتن دنباله جایگشت‌ها
---------------------------------------

* برای {\displaystyle n=1} که مسئله واضح است و تک جایگشت {\displaystyle <1>} ترتیب مطلوب است.
* اکنون فرض می‌کنیم می‌توانیم ترتیبی از {\displaystyle n!} جایگشت بیابیم و ترتیبی برای جایگشت‌های به طول {\displaystyle n+1} پیدا می‌کنیم.

فرض کنید ترتیب در فرض استقرا {\displaystyle P\_{1},P\_{2},...P\_{n!}} باشد. اکنون {\displaystyle Q\_{i,j}} را به این شکل تعریف می‌کنیم.

* چنان‌چه i زوج باشد، {\displaystyle Q\_{i,j}} جایگشتی است که از اضافه کردن {\displaystyle n+1} به جایگاه jام {\displaystyle P\_{i}} به دست می‌آید.
* چنانچه i فرد باشد، {\displaystyle Q\_{i,j}} جایگشتی است که از اضافه کردن {\displaystyle n+1} به جایگاه {\displaystyle n+2-j} جایگشت {\displaystyle P\_{i}} به دست می‌آید.

  
اکنون ترتیب مطلوب برای جایگشت‌های به طول {\displaystyle n+1} را به این شکل می‌سازیم.
{\displaystyle Q\_{1,1},Q\_{1,2},...Q\_{1,n+1},...Q\_{i,1},Q\_{i,2},...Q\_{i,n+1},...Q\_{n!,1},Q\_{n!,2},...Q\_{n!,n+1}}

برای مثال اگر برای {\displaystyle n=2} ترتیبی که فرض استقرا به ما می‌دهد، {\displaystyle <1,2>,<2,1>} باشد، در این‌صورت {\displaystyle P\_{1}=<1,2>,P\_{2}=<2,1>} و با ساختن {\displaystyle Q\_{i,j}}ها، ترتیب مطلوب برای {\displaystyle n=3} به شکل  

{\displaystyle <1,2,3>}  

{\displaystyle <1,3,2>}  

{\displaystyle <3,1,2>}  

{\displaystyle <3,2,1>}  

{\displaystyle <2,3,1>}  

{\displaystyle <2,1,3>}  

خواهد بود.

### اثبات

اکنون درستی این دنباله را نشان می‌دهیم. دو عنصر متوالی از دنباله را در نظر می‌گیریم و نشان می‌دهیم که با یک عملیات جابجایی دو عنصر مجاور به یکدیگر تبدیل می‌شوند.
فرض کنید دو جایگشت k و {\displaystyle k+1} را در نظر بگیریم دو حالت متصور است.

* اگر این دو جایگشت به شکل {\displaystyle Q\_{i,j},Q\_{i,j+1}} باشند، در این‌صورت اگر {\displaystyle n+1} را از دو جایگشت حذف کنیم جایگشت یکسان {\displaystyle P\_{i}} به دست می‌آید؛ و دو جایگشتی که ما بررسی می‌کنیم از اضافه کردن {\displaystyle n+1} به دو جایگاه متوالی از {\displaystyle P\_{i}} به دست می‌آید. پس با جابجا کردن {\displaystyle n+1} با عنصر کنارش از جایگشت k به جایگشت {\displaystyle k+1} می‌رسیم.
* اگر اگر این دو جایگشت به شکل {\displaystyle Q\_{i,n+1},Q\_{i+1,1}} باشد، در این صورت در تعریف ما، در هر دو این جایگشت‌ها {\displaystyle n+1} در یک سمت جایگشت است و بقیه جایگشت (بدون در نظر گرفتن {\displaystyle n+1}) جایگشت‌های {\displaystyle P\_{i},P\_{i+1}} هستند که طبق فرض استقرا با یک عملیات به یکدیگر تبدیل می‌شوند.

  

برای اینکه اثبات کامل شود، لازم است نشان دهیم که جایگشت‌هایی که تولید می‌کنیم متمایزند. برای مثال {\displaystyle Q\_{i\_{1},j\_{1}},Q\_{i\_{2},j\_{2}}} را در نظر بگیرید.

* اگر {\displaystyle i\_{1}=i\_{2}} در این‌صورت چون {\displaystyle j\_{1}\neq j\_{2}} مکان {\displaystyle n+1} در این دو جایگشت تفاوت می‌کند لذا دو جایگشت متفاوتند.
* اگر {\displaystyle i\_{1}\neq i\_{2}}، در این‌صورت جایگشت‌هایی که با حذف {\displaystyle n+1} به دست می‌آید {\displaystyle P\_{i\_{1}},P\_{i\_{2}}} هستند که طبق فرض استقرا با یکدیگر متفاوتند لذا دو جایگشت {\displaystyle Q\_{i\_{1},j\_{1}},Q\_{i\_{2},j\_{2}}} نیز متفاوتند.

الگوریتم
--------

الگوریتمی که در سال ۱۹۶۳ منتشر شد، دقیقاً ترتیب بالا را تولید می‌کند ولی نیازی به حل مسئله برای مقادیر کمتر و تولید دنباله‌های کوچک‌تر ندارد و به شکلی مستقیم و با شروع از حالت اولیه همه جایگشت‌ها را تولید می‌کند.
  

برای هر عدد در جایگشت یک جهت تعریف می‌شود که یا **به‌راست** است یا **به‌چپ**. در ابتدا جایگشت {\displaystyle <1,2,...n>} است و همه جهت‌ها به چپ هستند.  

سپس در هر گام یک *mobile* تعریف می‌کنیم که به این صورت محاسبه می‌شود.

1. بزرگترین عددی است که از عدد سمت **جهتش**، بزرگتر است (یعنی برای اعدادی که جهتشان به‌چپ است آن را با عدد سمت چپش و برای اعدادی که جهت‌شان به‌راست است آن را با عدد سمت راستش مقایسه می‌کنیم) در میان اعدادی که از عدد مربوطه‌شان بزرگترند، بزرگ‌ترین را در نظر می‌گیریم و این عدد را *mobile* می‌نامیم.
2. سپس این عدد را با عددی که جهتش اشاره می‌کند (یعنی همان عددی که با آن مقایسه شده‌است) جابجا می‌کنیم.
3. در گام آخر، جهت همه اعدادی که از *mobile* بزرگترند را برعکس می‌کنیم. یعنی از به‌چپ به به‌راست و بالعکس.

هنگامی که دیگر *mobile* در جایگشت پیدا نشد، الگوریتم پایان می‌یابد و جایگشت‌های تولید شده در این میان، ترتیب مطلوب ما هستند.

فرایند را برای {\displaystyle n=3} ببینید.  

{\displaystyle <1,<2,<3}  

*mobile* = ۳
  
  

{\displaystyle <1,<3,<2}  

*mobile* = ۳
  
  

{\displaystyle <3,<1,<2}  

*mobile* = ۲
  
  

{\displaystyle >3,<2,<1}  

*mobile* = ۳
  
  

{\displaystyle <2,>3,<1}  

*mobile* = ۳
  
  

{\displaystyle <2,<1,>3}  

دیگری *mobile* وجود ندارد. الگوریتم پایان می‌یابد.
  

مجدداً درستی الگوریتم با استقرا ثابت می‌شود.

### پیچیدگی زمانی الگوریتم

در این الگوریتم {\displaystyle \theta (n!)} جایگشت تولید می‌شود که برای هر کدام {\displaystyle \theta (n)} هزینه برای یافتن *mobile* و جابجایی‌ها و برعکس‌کردن جهت‌ها لازم است؛ لذا هزینه الگوریتم {\displaystyle \theta (n.n!)} خواهد بود.

ارتباط با کد گِرِی
------------------

کدگری در حالت کلی، ترتیبی از اعداد n رقمی در مبنایی دلخواه است، طوری که هر دو عدد مجاور در دقیقاً یک رقم تفاوت داشته باشند.  

اکنون به هر جایگشت یک دنباله متناظر می‌کنیم و ادعا می‌کنیم که دنباله‌های تولید شده توسط الگوریتمِ (که در مبنای فاکتوریل هستند)، خاصیت کدگری را دارند.  

برای هر جایگشت یک دنباله C، تعریف می‌کنیم که به این شکل حساب می‌شود.

* {\displaystyle c\_{i}} را برابر تعداد اعداد کوچکتر از i، در سمت راست i در جایگشت تعریف می‌کنیم.

مثلاً دنباله مربوطه برای {\displaystyle <3,1,2,5,4>} برابر با {\displaystyle C=<0,0,2,0,1>} خواهد بود.
  
ابتدا نشان می‌دهیم که برای جایگشت‌های متفاوت دنباله C نیز متفاوت خواهد بود.  

نشان می‌دهیم دنباله {\displaystyle <c\_{1},c\_{2},...c\_{n}>} جایگشتی یکتا تولید می‌کند.  

{\displaystyle c\_{n}} را در نظر بگیرید، به سادگی می‌توان دریافت که در جایگشت جایگاه عدد n، برابر با {\displaystyle n-c\_{n}} است. اکنون عدد n را حذف کنید و به شکلی بازگشتی بقیه اعداد را به شکل یکتا در جایگاه‌هایشان قرار دهید، تا همه اعداد در جایگشت قرار گیرند، در تمامی مراحل فرایند یکتاست، پس تنها یک جایگشت خاص، دنباله متناظرش C است.  
  

می‌توان نشان داد ترتیبی که الگوریتم جانسون-تروتر تولید می‌کند دنباله‌های C می‌سازد که خاصیت کد گری را دارند، یعنی هر دو دنباله متوالی دقیقاً در یک رقم تفاوت دارند. (برای اثبات می‌توانید نشان دهید که اگر دو عضو متوالی از یک جایگشت را جابجا کنیم دقیقاً یکی از {\displaystyle c\_{i}} تغییر می‌کند)
  
برای {\displaystyle n=3} ،
جایگشت‌ها  

{\displaystyle <1,2,3>,<1,3,2>,<3,1,2>,<3,2,1>,<2,3,1>,<2,1,3>} هستند که دنباله‌های متناظر با آن‌ها برابر با
  

{\displaystyle <0,0,0>,<0,0,1>,<0,0,2>,<0,1,2>,<0,1,1>,<0,1,0>} است
و همان‌طور که مشاهده می‌شود، دنباله تولید شده خاصیت کد گری را دارد.

جستارهای وابسته
---------------

* گراف جایگشت‌ها (Permutohedron)
* کد گری
* مبنای فاکتوریل

منابع
-----

1. 1 2  (Sedgewick, Robert (1977), "Permutation generation methods", ACM Comput. Surv. 9 (2): 137–164 و doi:10.1145/356689.356692).
2. ↑  (Dershowitz, Nachum (1975), "A simplified loop-free algorithm for generating permutations", Nordisk Tidskr. Informationsbehandling (BIT), 15 (2): 158–164. و doi:10.1007/bf01932689, MR 0502206)
3. ↑  (Ehrlich, Gideon (1973), "Loopless algorithms for generating permutations, combinations, and other combinatorial configurations", Journal of the ACM, 20 (3): 500–513. و doi:10.1145/321765.321781)
4. ↑  (Knuth, Donald (2011), "Section 7.2.1.2: Generating All Permutations", he Art of Computer Programm. و volume 4A)
5. ↑  (Dijkstra, Edsger W. (1976), "On a gauntlet thrown by David Gries", Acta Informatica, 6 (4): 357–359, doi:10.1007/BF00268136, MR 0426492. و Although DIjkstra does not cite any prior literature, an earlier draft EWD502 reveals that he knew of Trotter (1962))