From 7425b90a6f02a7d4efe36a7a76fcf0a1433d5829 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:02:16 +0530 Subject: [PATCH 01/13] create HLA --- planning.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/planning.py b/planning.py index b92cb6eaa..9be138682 100644 --- a/planning.py +++ b/planning.py @@ -574,3 +574,40 @@ def goal_test(kb): go = Action(expr("Go(actor, to)"), [precond_pos, precond_neg], [effect_add, effect_rem]) return PDLL(init, [hit, go], goal_test) + + +class HLA(Action): + """ + Define Actions for the real-world (that may be refined further), and satisfy resource + constraints. + """ + unique_group = 1 + + def __init__(self, action, precond=[None,None], effect=[None,None], duration=0, consume={}, use={}): + super().__init__(action, precond, effect) + self.duration = duration + self.consumes = consume + self.uses = use + self.completed = False + self.priority = -1 # must be assigned in relation to other HLAs + self.job_group = -1 # must be assigned in relation to other HLAs + + def __call__(self, kb, args, resources): + if self.check_resources(resources): + return self.act(kb, args) + + def order(hlas): + global unique_group + i = 1 + for hla in hlas: + if (hla.job_group == -1): # could replace if-test with assert + hla.priority = i + hla.job_group = unique_group + i += 1 + else: + raise Exception("Can't order HLA across job groups") + unique_group += 1 + + def check_resources(self, resources): + """Checks if the resources conditions are satisfied""" + pass From ca6c712905719fbeabd97d31373afcacd3557a63 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:03:12 +0530 Subject: [PATCH 02/13] create Real-World-Problem --- planning.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/planning.py b/planning.py index 9be138682..788978d7b 100644 --- a/planning.py +++ b/planning.py @@ -611,3 +611,17 @@ def order(hlas): def check_resources(self, resources): """Checks if the resources conditions are satisfied""" pass + +class Problem(PDLL): + """ + Define real-world problems by aggregating resources as numerical quantities instead of + named entities. + + This class is identical to PDLL, except that it overloads the act function to handle + resource and ordering conditions imposed by HLA as opposed to Action. + """ + def __init__(self, initial_state, actions, goal_test, jobs=None, resources={}): + super().__init__(initial_state, actions, goal_test) + self.jobs = jobs + self.resources = resources + From 3c1d3d196972630ae234506d87e2769ab2ca8bbc Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:05:03 +0530 Subject: [PATCH 03/13] implement HLA resource checks --- planning.py | 56 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/planning.py b/planning.py index 788978d7b..cc040f5d3 100644 --- a/planning.py +++ b/planning.py @@ -589,28 +589,44 @@ def __init__(self, action, precond=[None,None], effect=[None,None], duration=0, self.consumes = consume self.uses = use self.completed = False - self.priority = -1 # must be assigned in relation to other HLAs - self.job_group = -1 # must be assigned in relation to other HLAs + #self.priority = -1 # must be assigned in relation to other HLAs + #self.job_group = -1 # must be assigned in relation to other HLAs - def __call__(self, kb, args, resources): - if self.check_resources(resources): - return self.act(kb, args) - - def order(hlas): - global unique_group - i = 1 - for hla in hlas: - if (hla.job_group == -1): # could replace if-test with assert - hla.priority = i - hla.job_group = unique_group - i += 1 - else: - raise Exception("Can't order HLA across job groups") - unique_group += 1 + def has_consumable_resource(self, available_resources): + for resource in self.consumes: + if available_resources.get(resource) is None: + return False + if available_resources[resource] < self.consumes[resource]: + return False + return True + + def has_usable_resource(self, available_resources): + for resource in self.uses: + if available_resources.get(resource) is None: + return False + if available_resources[resource] < self.uses[resource]: + return False + return True - def check_resources(self, resources): - """Checks if the resources conditions are satisfied""" - pass + #def __call__(self, kb, args, resources): + # if self.check_resources(resources): + # return self.act(kb, args) + # + #def order(hlas): + # global unique_group + # i = 1 + # for hla in hlas: + # if (hla.job_group == -1): # could replace if-test with assert + # hla.priority = i + # hla.job_group = unique_group + # i += 1 + # else: + # raise Exception("Can't order HLA across job groups") + # unique_group += 1 + # + #def check_resources(self, resources): + # """Checks if the resources conditions are satisfied""" + # pass class Problem(PDLL): """ From fd4f6ba4f20dfdba64a5042515e71b669c7bc9a6 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:05:51 +0530 Subject: [PATCH 04/13] implement HLA order checks --- planning.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/planning.py b/planning.py index cc040f5d3..d43f28d94 100644 --- a/planning.py +++ b/planning.py @@ -608,6 +608,16 @@ def has_usable_resource(self, available_resources): return False return True + def inorder(self, job_order): + for jobs in job_order: + if self in jobs: + for job in jobs: + if job is self: + return True + if job.completed == False: + return False + return True + #def __call__(self, kb, args, resources): # if self.check_resources(resources): # return self.act(kb, args) From b17f84be14f6a61149bd4c09b4113c8e3aa52d08 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:07:00 +0530 Subject: [PATCH 05/13] complete HLA and Problem implementations --- planning.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/planning.py b/planning.py index d43f28d94..9447a2087 100644 --- a/planning.py +++ b/planning.py @@ -592,6 +592,16 @@ def __init__(self, action, precond=[None,None], effect=[None,None], duration=0, #self.priority = -1 # must be assigned in relation to other HLAs #self.job_group = -1 # must be assigned in relation to other HLAs + def do_action(self, job_order, available_resources, kb, args): + #print(self.name) + if (not self.has_usable_resource(available_resources) or + not self.has_consumable_resource(available_resources) ): + raise Exception('Not enough resources to execute {}'.format(self.name)) + if not self.inorder(job_order): + raise Exception("Can't execute {} - execute prerequisite actions first".format(self.name)) + super().act(kb, args) + self.completed = True + def has_consumable_resource(self, available_resources): for resource in self.consumes: if available_resources.get(resource) is None: @@ -617,7 +627,7 @@ def inorder(self, job_order): if job.completed == False: return False return True - + #def __call__(self, kb, args, resources): # if self.check_resources(resources): # return self.act(kb, args) @@ -650,4 +660,19 @@ def __init__(self, initial_state, actions, goal_test, jobs=None, resources={}): super().__init__(initial_state, actions, goal_test) self.jobs = jobs self.resources = resources + + def act(self, action): + """ + Performs the HLA given as argument. + + Note that this is different from the superclass action - where the parameter was an + Expression. For real world problems, an Expr object isn't enough to capture all the + detail required for executing the action - resources, preconditions, etc need to be + checked for too. + """ + args = action.args + list_action = first(a for a in self.actions if a.name == action.name) + if list_action is None: + raise Exception("Action '{}' not found".format(action.name)) + list_action.do_action(self.jobs, self.resources, self.kb, args) From f16b54afd9c7e4e6bdb4a8385c536bb7153511e8 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:08:36 +0530 Subject: [PATCH 06/13] define Job Shop Actions --- planning.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/planning.py b/planning.py index 9447a2087..a3d4b4a91 100644 --- a/planning.py +++ b/planning.py @@ -676,3 +676,76 @@ def act(self, action): raise Exception("Action '{}' not found".format(action.name)) list_action.do_action(self.jobs, self.resources, self.kb, args) +def job_shop_problem(): + init = [expr('Car(C1)'), + expr('Car(C2)'), + expr('Wheels(W1)'), + expr('Wheels(W2)'), + expr('Engine(E2)'), + expr('Engine(E2)'),] + + def goal_test(kb): + #print(kb.clauses) + required = [expr('Has(C1, W1)'), expr('Has(C1, E1)'), expr('Inspected(C1)'), + expr('Has(C2, W2)'), expr('Has(C2, E2)'), expr('Inspected(C2)')] + for q in required: + #print(q) + #print(kb.ask(q)) + if kb.ask(q) is False: + return False + return True + + #AddEngine1 + precond_pos = [] + precond_neg = [expr("Has(C1,E1)")] + effect_add = [expr("Has(C1,E1)")] + effect_rem = [] + add_engine1 = HLA(expr("AddEngine1"), + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=30, use={'EngineHoists':1}) + + #AddEngine2 + precond_pos = [] + precond_neg = [expr("Has(C2,E2)")] + effect_add = [expr("Has(C2,E2)")] + effect_rem = [] + add_engine2 = HLA(expr("AddEngine2"), + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=60, use={'EngineHoists':1}) + + #AddWheels1 + precond_pos = [] + precond_neg = [expr("Has(C1,W1)")] + effect_add = [expr("Has(C1,W1)")] + effect_rem = [] + add_wheels1 = HLA(expr("AddWheels1"), + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=30, consume={'LugNuts':20}, use={'WheelStations':1}) + + #AddWheels2 + precond_pos = [] + precond_neg = [expr("Has(C2,W2)")] + effect_add = [expr("Has(C2,W2)")] + effect_rem = [] + add_wheels2 = HLA(expr("AddWheels2"), + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=15, consume={'LugNuts':20}, use={'WheelStations':1}) + + #Inspect1 + precond_pos = [] + precond_neg = [expr("Inspected(C1)")] + effect_add = [expr("Inspected(C1)")] + effect_rem = [] + inspect1 = HLA(expr("Inspect1"), + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=10, use={'Inspectors':1}) + + #Inspect2 + precond_pos = [] + precond_neg = [expr("Inspected(C2)")] + effect_add = [expr("Inspected(C2)")] + effect_rem = [] + inspect2 = HLA(expr("Inspect2"), + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=10, use={'Inspectors':1}) + From 732c1b20e2c6aab4bcae6cb005d1abc642009a9f Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:10:00 +0530 Subject: [PATCH 07/13] complete HLA-Problem 11.1:job_shop --- planning.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/planning.py b/planning.py index a3d4b4a91..41096c815 100644 --- a/planning.py +++ b/planning.py @@ -695,6 +695,8 @@ def goal_test(kb): return False return True + resources = {'EngineHoists':1, 'WheelStations':2, 'Inspectors':2, 'LugNuts':500} + #AddEngine1 precond_pos = [] precond_neg = [expr("Has(C1,E1)")] @@ -748,4 +750,10 @@ def goal_test(kb): inspect2 = HLA(expr("Inspect2"), [precond_pos, precond_neg], [effect_add, effect_rem], duration=10, use={'Inspectors':1}) + + job_group1 = [add_engine1, add_wheels1, inspect1] + job_group2 = [add_engine2, add_wheels2, inspect2] + + return Problem(init, [add_engine1, add_engine2, add_wheels1, add_wheels2, inspect1, inspect2], + goal_test, [job_group1, job_group2], resources) From 4fb89e95566d80ed94dea25680ca16254e0c75bf Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:32:40 +0530 Subject: [PATCH 08/13] make code pep8 compliant using flake8 --- planning.py | 102 ++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 59 deletions(-) diff --git a/planning.py b/planning.py index 41096c815..6a9da840e 100644 --- a/planning.py +++ b/planning.py @@ -582,26 +582,29 @@ class HLA(Action): constraints. """ unique_group = 1 - - def __init__(self, action, precond=[None,None], effect=[None,None], duration=0, consume={}, use={}): + + def __init__(self, action, precond=[None, None], effect=[None, None], duration=0, + consume={}, use={}): super().__init__(action, precond, effect) self.duration = duration self.consumes = consume self.uses = use self.completed = False - #self.priority = -1 # must be assigned in relation to other HLAs - #self.job_group = -1 # must be assigned in relation to other HLAs - + # self.priority = -1 # must be assigned in relation to other HLAs + # self.job_group = -1 # must be assigned in relation to other HLAs + def do_action(self, job_order, available_resources, kb, args): - #print(self.name) - if (not self.has_usable_resource(available_resources) or - not self.has_consumable_resource(available_resources) ): - raise Exception('Not enough resources to execute {}'.format(self.name)) + # print(self.name) + if not self.has_usable_resource(available_resources): + raise Exception('Not enough usable resources to execute {}'.format(self.name)) + if not self.has_consumable_resource(available_resources): + raise Exception('Not enough consumable resources to execute {}'.format(self.name)) if not self.inorder(job_order): - raise Exception("Can't execute {} - execute prerequisite actions first".format(self.name)) - super().act(kb, args) - self.completed = True - + raise Exception("Can't execute {} - execute prerequisite actions first". + format(self.name)) + super().act(kb, args) # update knowledge base + self.completed = True # set the task status to complete + def has_consumable_resource(self, available_resources): for resource in self.consumes: if available_resources.get(resource) is None: @@ -617,42 +620,23 @@ def has_usable_resource(self, available_resources): if available_resources[resource] < self.uses[resource]: return False return True - + def inorder(self, job_order): for jobs in job_order: if self in jobs: for job in jobs: if job is self: return True - if job.completed == False: + if not job.completed: return False return True - #def __call__(self, kb, args, resources): - # if self.check_resources(resources): - # return self.act(kb, args) - # - #def order(hlas): - # global unique_group - # i = 1 - # for hla in hlas: - # if (hla.job_group == -1): # could replace if-test with assert - # hla.priority = i - # hla.job_group = unique_group - # i += 1 - # else: - # raise Exception("Can't order HLA across job groups") - # unique_group += 1 - # - #def check_resources(self, resources): - # """Checks if the resources conditions are satisfied""" - # pass class Problem(PDLL): """ Define real-world problems by aggregating resources as numerical quantities instead of named entities. - + This class is identical to PDLL, except that it overloads the act function to handle resource and ordering conditions imposed by HLA as opposed to Action. """ @@ -660,11 +644,11 @@ def __init__(self, initial_state, actions, goal_test, jobs=None, resources={}): super().__init__(initial_state, actions, goal_test) self.jobs = jobs self.resources = resources - + def act(self, action): """ Performs the HLA given as argument. - + Note that this is different from the superclass action - where the parameter was an Expression. For real world problems, an Expr object isn't enough to capture all the detail required for executing the action - resources, preconditions, etc need to be @@ -676,84 +660,84 @@ def act(self, action): raise Exception("Action '{}' not found".format(action.name)) list_action.do_action(self.jobs, self.resources, self.kb, args) + def job_shop_problem(): init = [expr('Car(C1)'), expr('Car(C2)'), expr('Wheels(W1)'), expr('Wheels(W2)'), expr('Engine(E2)'), - expr('Engine(E2)'),] + expr('Engine(E2)')] def goal_test(kb): - #print(kb.clauses) + # print(kb.clauses) required = [expr('Has(C1, W1)'), expr('Has(C1, E1)'), expr('Inspected(C1)'), expr('Has(C2, W2)'), expr('Has(C2, E2)'), expr('Inspected(C2)')] for q in required: - #print(q) - #print(kb.ask(q)) + # print(q) + # print(kb.ask(q)) if kb.ask(q) is False: return False return True - - resources = {'EngineHoists':1, 'WheelStations':2, 'Inspectors':2, 'LugNuts':500} - #AddEngine1 + resources = {'EngineHoists': 1, 'WheelStations': 2, 'Inspectors': 2, 'LugNuts': 500} + + # AddEngine1 precond_pos = [] precond_neg = [expr("Has(C1,E1)")] effect_add = [expr("Has(C1,E1)")] effect_rem = [] add_engine1 = HLA(expr("AddEngine1"), [precond_pos, precond_neg], [effect_add, effect_rem], - duration=30, use={'EngineHoists':1}) + duration=30, use={'EngineHoists': 1}) - #AddEngine2 + # AddEngine2 precond_pos = [] precond_neg = [expr("Has(C2,E2)")] effect_add = [expr("Has(C2,E2)")] effect_rem = [] add_engine2 = HLA(expr("AddEngine2"), [precond_pos, precond_neg], [effect_add, effect_rem], - duration=60, use={'EngineHoists':1}) + duration=60, use={'EngineHoists': 1}) - #AddWheels1 + # AddWheels1 precond_pos = [] precond_neg = [expr("Has(C1,W1)")] effect_add = [expr("Has(C1,W1)")] effect_rem = [] add_wheels1 = HLA(expr("AddWheels1"), [precond_pos, precond_neg], [effect_add, effect_rem], - duration=30, consume={'LugNuts':20}, use={'WheelStations':1}) + duration=30, consume={'LugNuts': 20}, use={'WheelStations': 1}) - #AddWheels2 + # AddWheels2 precond_pos = [] precond_neg = [expr("Has(C2,W2)")] effect_add = [expr("Has(C2,W2)")] effect_rem = [] add_wheels2 = HLA(expr("AddWheels2"), [precond_pos, precond_neg], [effect_add, effect_rem], - duration=15, consume={'LugNuts':20}, use={'WheelStations':1}) + duration=15, consume={'LugNuts': 20}, use={'WheelStations': 1}) - #Inspect1 + # Inspect1 precond_pos = [] precond_neg = [expr("Inspected(C1)")] effect_add = [expr("Inspected(C1)")] effect_rem = [] inspect1 = HLA(expr("Inspect1"), - [precond_pos, precond_neg], [effect_add, effect_rem], - duration=10, use={'Inspectors':1}) + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=10, use={'Inspectors': 1}) - #Inspect2 + # Inspect2 precond_pos = [] precond_neg = [expr("Inspected(C2)")] effect_add = [expr("Inspected(C2)")] effect_rem = [] inspect2 = HLA(expr("Inspect2"), - [precond_pos, precond_neg], [effect_add, effect_rem], - duration=10, use={'Inspectors':1}) - + [precond_pos, precond_neg], [effect_add, effect_rem], + duration=10, use={'Inspectors': 1}) + job_group1 = [add_engine1, add_wheels1, inspect1] job_group2 = [add_engine2, add_wheels2, inspect2] return Problem(init, [add_engine1, add_engine2, add_wheels1, add_wheels2, inspect1, inspect2], goal_test, [job_group1, job_group2], resources) - From 97473229b4bf7065564903a1e9dbbb31372e238c Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:33:07 +0530 Subject: [PATCH 09/13] fixed resource consumption bug --- planning.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/planning.py b/planning.py index 6a9da840e..3672f9dc1 100644 --- a/planning.py +++ b/planning.py @@ -603,6 +603,8 @@ def do_action(self, job_order, available_resources, kb, args): raise Exception("Can't execute {} - execute prerequisite actions first". format(self.name)) super().act(kb, args) # update knowledge base + for resource in self.consumes: # remove consumed resources + return available_resources[resource] -= self.consumes[resource] self.completed = True # set the task status to complete def has_consumable_resource(self, available_resources): From 793a1a3a81549c48901def1bdfa884379975b1dd Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:42:08 +0530 Subject: [PATCH 10/13] fixed resource consumption bug --- planning.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planning.py b/planning.py index 3672f9dc1..9cc5ab4ea 100644 --- a/planning.py +++ b/planning.py @@ -604,7 +604,7 @@ def do_action(self, job_order, available_resources, kb, args): format(self.name)) super().act(kb, args) # update knowledge base for resource in self.consumes: # remove consumed resources - return available_resources[resource] -= self.consumes[resource] + available_resources[resource] -= self.consumes[resource] self.completed = True # set the task status to complete def has_consumable_resource(self, available_resources): From ed38d8c48f98887c9f2f862c801ff683ee9aaa02 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:43:02 +0530 Subject: [PATCH 11/13] added docstrings --- planning.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/planning.py b/planning.py index 9cc5ab4ea..96317af88 100644 --- a/planning.py +++ b/planning.py @@ -585,6 +585,12 @@ class HLA(Action): def __init__(self, action, precond=[None, None], effect=[None, None], duration=0, consume={}, use={}): + """ + As opposed to actions, to define HLA, we have added constraints. + duration holds the amount of time required to execute the task + consumes holds a dictionary representing the resources the task consumes + uses holds a dictionary representing the resources the task uses + """ super().__init__(action, precond, effect) self.duration = duration self.consumes = consume @@ -594,6 +600,10 @@ def __init__(self, action, precond=[None, None], effect=[None, None], duration=0 # self.job_group = -1 # must be assigned in relation to other HLAs def do_action(self, job_order, available_resources, kb, args): + """ + An HLA based version of act - along with knowledge base updation, it handles + resource checks, and ensures the actions are executed in the correct order. + """ # print(self.name) if not self.has_usable_resource(available_resources): raise Exception('Not enough usable resources to execute {}'.format(self.name)) @@ -608,6 +618,9 @@ def do_action(self, job_order, available_resources, kb, args): self.completed = True # set the task status to complete def has_consumable_resource(self, available_resources): + """ + Ensure there are enough consumable resources for this action to execute. + """ for resource in self.consumes: if available_resources.get(resource) is None: return False @@ -616,6 +629,9 @@ def has_consumable_resource(self, available_resources): return True def has_usable_resource(self, available_resources): + """ + Ensure there are enough usable resources for this action to execute. + """ for resource in self.uses: if available_resources.get(resource) is None: return False @@ -624,6 +640,10 @@ def has_usable_resource(self, available_resources): return True def inorder(self, job_order): + """ + Ensure that all the jobs that had to be executed before the current one have been + successfully executed. + """ for jobs in job_order: if self in jobs: for job in jobs: @@ -661,9 +681,33 @@ def act(self, action): if list_action is None: raise Exception("Action '{}' not found".format(action.name)) list_action.do_action(self.jobs, self.resources, self.kb, args) + print(self.resources) def job_shop_problem(): + """ + [figure 11.1] JOB-SHOP-PROBLEM + + A job-shop scheduling problem for assembling two cars, + with resource and ordering constraints. + + Example: + >>> from planning import * + >>> p = job_shop_problem() + >>> p.goal_test() + False + >>> p.act(p.jobs[1][0]) + >>> p.act(p.jobs[1][1]) + >>> p.act(p.jobs[1][2]) + >>> p.act(p.jobs[0][0]) + >>> p.act(p.jobs[0][1]) + >>> p.goal_test() + False + >>> p.act(p.jobs[0][2]) + >>> p.goal_test() + True + >>> + """ init = [expr('Car(C1)'), expr('Car(C2)'), expr('Wheels(W1)'), From 27425fce83f1a5f628b081c471843e01dfb663f6 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:49:59 +0530 Subject: [PATCH 12/13] added unit test for job_shop_problem --- planning.py | 2 +- tests/test_planning.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/planning.py b/planning.py index 96317af88..bfc65e786 100644 --- a/planning.py +++ b/planning.py @@ -681,7 +681,7 @@ def act(self, action): if list_action is None: raise Exception("Action '{}' not found".format(action.name)) list_action.do_action(self.jobs, self.resources, self.kb, args) - print(self.resources) + # print(self.resources) def job_shop_problem(): diff --git a/tests/test_planning.py b/tests/test_planning.py index 461cdcdbb..e0ce30b0b 100644 --- a/tests/test_planning.py +++ b/tests/test_planning.py @@ -81,3 +81,20 @@ def test_graph_call(): graph() assert levels_size == len(graph.levels) - 1 + + +def test_job_shop_problem(): + p = job_shop_problem() + assert p.goal_test() is False + + solution = [p.jobs[1][0], + p.jobs[0][0], + p.jobs[0][1], + p.jobs[0][2], + p.jobs[1][1], + p.jobs[1][2]] + + for action in solution: + p.act(action) + + assert p.goal_test() From e1842b7261d22d8e289e661075860efc8e271f19 Mon Sep 17 00:00:00 2001 From: Kaivalya Rawal Date: Sun, 26 Mar 2017 14:57:43 +0530 Subject: [PATCH 13/13] updated README table --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7cb796b02..c43183c6c 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Here is a table of algorithms, the figure, name of the code in the book and in t | 10.7 | Cake-Problem | `have_cake_and_eat_cake_too` |[`planning.py`][planning]| | 10.9 | Graphplan | `GraphPlan` |[`planning.py`][planning]| | 10.13 | Partial-Order-Planner | | -| 11.1 | Job-Shop-Problem-With-Resources | | +| 11.1 | Job-Shop-Problem-With-Resources | `job_shop_problem` |[`planning.py`][planning]| | 11.5 | Hierarchical-Search | | | 11.8 | Angelic-Search | | | 11.10 | Doubles-tennis | `double_tennis_problem` |[`planning.py`][planning]|