首位交易循环机制(TTCM)的Python实现

Xc.Li
Feb.2016

算法原理

首位交易循环机制的算法,略。

Python实现

学校和学生的数据结构

  • 学校 class School

    • counter:计数器
    • pointer:指向
    • preference:偏好向量
    • available:学校是未满员
    • 函数:refresh
      用于每次刷新学校的指向和偏好向量
  • 学生 class Student

    • preference:偏好向量
    • pointer:指向
    • available:学生是否已经找到学校
    • result:保存学生最终去的学校
    • 函数:refresh
      用于每次刷新学生的指向和偏好向量

学校

class School(object):
def __init__(self, quantity, preference):
    self.counter = quantity
    self.pointer = preference[0]
    self.preference = preference
    self.available = True
    print self.counter, self.pointer, preference

学生

class Student(object):
def __init__(self, preference):
    self.preference = preference
    self.pointer = preference[0]
    self.available = True
    self.result = None

学校和学生的刷新

学校

class School 里的函数:

def refresh(self):
original_preference = self.preference
self.preference = []
for item in original_preference:
    if student_list[item].available is True:
        self.preference.append(item)
try:
    self.pointer = self.preference[0]
except:
    print 'ok'

学生

class Student 里的函数:

def refresh(self):
original_preference = self.preference
self.preference = []
for item in original_preference:
    if school_list[item].available is True:
        self.preference.append(item)
self.pointer = self.preference[0]

穷举构环

从学校出发,根据学校和学生的指向向circle列表中添加元素。
判断方式:

  1. 如果某元素和起始元素相同则终止程序,找到一个完整的环
    处理方式是调用School.refresh和Student.refresh刷新状态,调用Handle(circle)处理环。

  2. 如果环的长度大于10(仅举例),则认为是死循环(例如s2-i1-s1-i1-s1-....),也终止程序。

    while True:

    count = 0
    for j in range(1, student_num + 1, 1): #careful
    if student_list['i' + str(j)].available is False:
    count += 1
    if count == student_num:
    break

    i = 1
    circle = []
    while i <= school_num:
    school_name = 's' + str(i)
    if school_list[school_name].available is False:
    continue
    # circle.append(school_name)
    while True:
    student_name = school_list[school_name].pointer
    circle.append(student_name)
    school_name = student_list[student_name].pointer
    circle.append(school_name)
    if school_name == 's' + str(i):
    flag = 1
    break
    if len(circle) > 10:
    flag = 0
    circle = 'Error'
    break
    if flag == 1:
    handle(circle)
    for j in range(1, school_num + 1, 1): # careful
    school_list['s' + str(j)].refresh()
    for j in range(1, student_num + 1, 1): # careful
    student_list['i' + str(j)].refresh()
    print circle
    circle = []
    i += 1

环的处理

对于每个环内的学生i,将目前指向pointer赋值给结果result保存,把available赋值为False,以示退出。
对于每个环内的学校s,counter减1。判断counter是否为0,如果是则把available赋值为False,以示退出。

def handle(circle):
for item in circle:
    if item[0] == 'i':
        student_list[item].available = False
        student_list[item].result = student_list[item].pointer
    if item[0] == 's':
        school_list[item].counter -= 1
        if school_list[item].counter == 0:
            school_list[item].available = False
            print 'school out!'

运行

测试

number of schools:输入0
演示:

C:\Python27\python.exe D:/OneDrive/Python/TTCM.py
number of schools:0 #这里输入0
test
2 i1 ['i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8']
2 i3 ['i3', 'i5', 'i4', 'i8', 'i7', 'i2', 'i1', 'i6']
3 i5 ['i5', 'i3', 'i1', 'i7', 'i2', 'i8', 'i6', 'i4']
3 i6 ['i6', 'i8', 'i7', 'i4', 'i2', 'i3', 'i5', 'i1']
['i1', 's2', 'i3', 's3', 'i5', 's1']
Error #表示找不到环
Error
['i6', 's4']
school out!
['i2', 's1']
school out!
['i4', 's3', 'i7', 's2']
Error
ok #学校满员
ok
ok
ok
['i8', 's4']
1 s2
2 s1
3 s3
4 s3
5 s1
6 s4
7 s2
8 s4

数据输入

number of schools:学校个数(整数)
number of students:学生个数(整数)
quantity of school:学校招生人数(整数)
enter the preference of school:学校偏好,例如i1,i2,i3
enter the preference of student:学生偏好,例如s1,s2,s3

完整代码

基于Python2.7

# -*- encoding:utf-8 -*-
# 首位交易循环机制
# Designed By Xc.Li @ Feb.2015


class School(object):
    def __init__(self, quantity, preference):
        self.counter = quantity
        self.pointer = preference[0]
        self.preference = preference
        self.available = True
        print self.counter, self.pointer, preference

    def refresh(self):
        original_preference = self.preference
        self.preference = []
        for item in original_preference:
            if student_list[item].available is True:
                self.preference.append(item)
        try:
            self.pointer = self.preference[0]
        except:
            print 'ok'


class Student(object):
    def __init__(self, preference):
        self.preference = preference
        self.pointer = preference[0]
        self.available = True
        self.result = None

    def refresh(self):
        original_preference = self.preference
        self.preference = []
        for item in original_preference:
            if school_list[item].available is True:
                self.preference.append(item)
        self.pointer = self.preference[0]

# input and initialize

school_num = int(raw_input("number of schools:"))
if school_num == 0:
    print 'test'
    school_num = 4
    school_list = {
        's1': School(2, ['i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8']),
        's2': School(2, ['i3', 'i5', 'i4', 'i8', 'i7', 'i2', 'i1', 'i6']),
        's3': School(3, ['i5', 'i3', 'i1', 'i7', 'i2', 'i8', 'i6', 'i4']),
        's4': School(3, ['i6', 'i8', 'i7', 'i4', 'i2', 'i3', 'i5', 'i1'])
    }
    student_num = 8
    student_list = {
        'i1': Student(['s2', 's1', 's3', 's4']),
        'i2': Student(['s1', 's2', 's3', 's4']),
        'i3': Student(['s3', 's2', 's1', 's4']),
        'i4': Student(['s3', 's4', 's1', 's2']),
        'i5': Student(['s1', 's3', 's4', 's2']),
        'i6': Student(['s4', 's1', 's2', 's3']),
        'i7': Student(['s1', 's2', 's3', 's4']),
        'i8': Student(['s1', 's2', 's4', 's3'])
    }

else:
    student_num = int(raw_input("number of students:"))
    # school initialize
    i = 1
    school_list = {}
    while i <= school_num:
        school_name = 's' + str(i)
        print school_name
        quantity = int(raw_input("quantity of school:"))
        preference = raw_input("enter the preference of school:")
        preference = preference.split(",")
        school_list[school_name] = School(quantity, preference)
        i += 1

    # student initialize
    i = 1
    student_list = {}
    while i <= student_num:
        student_name = 'i' + str(i)
        print student_name
        preference = raw_input("enter the preference of student:")
        preference = preference.split(",")
        student_list[student_name] = Student(preference)
        i += 1


def handle(circle):
    for item in circle:
        if item[0] == 'i':
            student_list[item].available = False
            student_list[item].result = student_list[item].pointer
        if item[0] == 's':
            school_list[item].counter -= 1
            if school_list[item].counter == 0:
                school_list[item].available = False
                print 'school out!'
k = 0
while True:

    count = 0
    for j in range(1, student_num + 1, 1):  # fuck it!
        if student_list['i' + str(j)].available is False:
            count += 1
    if count == student_num:
        break

    i = 1
    circle = []
    while i <= school_num:
        school_name = 's' + str(i)
        if school_list[school_name].available is False:
            continue
        # circle.append(school_name)
        while True:
            student_name = school_list[school_name].pointer
            circle.append(student_name)
            school_name = student_list[student_name].pointer
            circle.append(school_name)
            if school_name == 's' + str(i):
                flag = 1
                break
            if len(circle) > 10:
                flag = 0
                circle = 'Error'
                break
        if flag == 1:
            handle(circle)
            for j in range(1, school_num + 1, 1):  # careful
                school_list['s' + str(j)].refresh()
            for j in range(1, student_num + 1, 1):  # careful
                student_list['i' + str(j)].refresh()
        print circle
        circle = []
        i += 1
for k in range(1, student_num + 1, 1):
    print k, student_list['i' + str(k)].result
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,235评论 0 23
  • 一 在考虑街亭守将时 马谡为图虚名 请求守卫 诸葛亮虽有忧虑 最终还是答应了 这是一过 用人不疑疑人不用 二 诸葛...
    简单明了阅读 254评论 0 2
  • test
    genspring阅读 199评论 0 1
  • 天突然变冷,中午还下起了大雪。薄衫单衣在雪里走了一遭回来竟然有点发晕,鼻涕直流。羽绒棉袄都已经洗好收进了柜子,懒得...
    觉梦2016阅读 284评论 0 1
  • 故事里说,王子爱上了巫婆却抛弃了白雪公主,王后善妒的嘴脸从此彻底暴露无遗,她疯狂的虐待着白雪公主,直到七个小矮人都...
    心事于你阅读 445评论 0 2